Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@afshin/life

Package Overview
Dependencies
Maintainers
2
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@afshin/life - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

lib/example.d.ts

84

lib/index.d.ts

@@ -1,19 +0,62 @@

import { DataGrid, DataModel } from '@phosphor/datagrid';
import '../style/index.css';
import { DataGrid, DataModel } from '@lumino/datagrid';
/**
* A namespace for `Life`.
*/
export declare namespace Life {
interface IStyle {
/**
* The `Life` style type.
*/
type Style = {
alive?: string;
empty?: string;
size?: number;
}
};
/**
* The minimum size of a cell in a `Life` grid.
*/
const MINIMUM_SIZE = 4;
/**
* A Lumino `DataGrid` data model for Conway's Game of Life.
*/
class Model extends DataModel {
/**
* Instantiate a new life model.
*/
constructor(options?: Model.IOptions);
/**
* The model's refresh interval.
*/
get interval(): number;
set interval(interval: number);
/**
* Whether the model has been disposed.
*/
get isDisposed(): boolean;
/**
* The current state of the universe.
*/
state: Model.Bit[][];
get state(): Model.Bit[][];
set state(state: Model.Bit[][]);
/**
* The model's tick function.
*/
get tick(): Model.Tick;
set tick(tick: Model.Tick);
/**
* Get the row count for a region in the life data model.
*/
rowCount(region: DataModel.RowRegion): number;
/**
* Get the column count for a region in the life data model.
*/
columnCount(region: DataModel.ColumnRegion): number;
/**
* Get the data for a cell in the life data model.
*/
data(region: DataModel.CellRegion, row: number, column: number): any;
/**
* Dispose the model.
*/
dispose(): void;
/**
* Start ticking the life widget, rendering each generation.

@@ -26,7 +69,7 @@ */

stop(): void;
private _interval;
private _data;
private _swap;
private _started;
private _columnCount;
private _rowCount;
private _state;
private _tick;
private _ticker;
}

@@ -44,3 +87,3 @@ /**

*/
type Tick = (prev: Bit[][], next: Bit[][], fluctuation?: number) => void;
type Tick = (current: Bit[][], fluctuation?: number) => Bit[][];
/**

@@ -59,3 +102,3 @@ * The instantiation options for a life widget.

/**
* A function used to calculate generations, defaults to `LifeWidget.tick`.
* A function to calculate each generation, defaults to `Life.Model.tick`.
*/

@@ -79,6 +122,4 @@ tick?: Tick;

*
* @param input - The current state of the world.
* @param current - The current state of the world.
*
* @param output - An array that will be populated with the next generation.
*
* @param fluctuation - An optional value between 0 and 1 that indicates the

@@ -89,9 +130,18 @@ * likelihood that a bit will flip, contravening the rules.

* Instead of accepting a single state array, this function takes an `input`
* and an `output` array to faciliate swapping back and forth between
* and an `output` array to facilitate swapping back and forth between
* generation arrays without needing to reallocate memory. The `input` and
* `output` arrays must have the same dimensions.
*/
function tick(input: Bit[][], output: Bit[][], fluctuation?: number): void;
function tick(input: Bit[][], fluctuation?: number): Bit[][];
}
function create(model: Model, style?: IStyle): DataGrid;
/**
* Create a `DataGrid` to render a `Life.Model`.
*
* @param model - The `Life` model.
*
* @param style - The `Life` style.
*
* @returns A `DataGrid` that renders the `Life` model.
*/
function create(model: Model, style?: Style): DataGrid;
}
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {

@@ -12,13 +15,53 @@ extendStatics(d, b);

})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
var datagrid_1 = require("@phosphor/datagrid");
require("../style/index.css");
exports.Life = void 0;
var datagrid_1 = require("@lumino/datagrid");
var polling_1 = require("@lumino/polling");
/**

@@ -40,14 +83,70 @@ * The default likelihood that a random cell is alive.

var INTERVAL = 250;
/**
* A namespace for `Life`.
*/
var Life;
(function (Life) {
/**
* The minimum size of a cell in a `Life` grid.
*/
Life.MINIMUM_SIZE = 4;
/**
* A Lumino `DataGrid` data model for Conway's Game of Life.
*/
var Model = /** @class */ (function (_super) {
__extends(Model, _super);
/**
* Instantiate a new life model.
*/
function Model(options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this) || this;
_this._interval = options.interval || INTERVAL;
_this._tick = options.tick || Model.tick;
_this._tick = Model.tick;
_this._ticker = new polling_1.Poll({
auto: false,
factory: function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.state = this.tick(this.state);
this.emitChanged({
type: 'cells-changed',
rowSpan: this._rowCount,
columnSpan: this._columnCount,
region: 'body',
row: 0,
column: 0
});
return [2 /*return*/];
});
}); },
});
_this.interval = options.interval || INTERVAL;
_this.state = options.initial || Model.random();
_this.tick = options.tick || Model.tick;
return _this;
}
Object.defineProperty(Model.prototype, "interval", {
/**
* The model's refresh interval.
*/
get: function () {
return this._ticker.frequency.interval;
},
set: function (interval) {
if (this.interval !== interval) {
this._ticker.frequency = __assign(__assign({}, this._ticker.frequency), { interval: interval });
}
},
enumerable: false,
configurable: true
});
Object.defineProperty(Model.prototype, "isDisposed", {
/**
* Whether the model has been disposed.
*/
get: function () {
return this._ticker.isDisposed;
},
enumerable: false,
configurable: true
});
Object.defineProperty(Model.prototype, "state", {

@@ -58,49 +157,58 @@ /**

get: function () {
return this._data;
return this._state;
},
set: function (state) {
if (this._started) {
this.stop();
if (this.state !== state) {
this._columnCount = state[0].length;
this._rowCount = state.length;
this._state = state;
}
this._data = state;
this._swap = JSON.parse(JSON.stringify(state));
},
enumerable: true,
enumerable: false,
configurable: true
});
Object.defineProperty(Model.prototype, "tick", {
/**
* The model's tick function.
*/
get: function () {
return this._tick;
},
set: function (tick) {
if (this.tick !== tick) {
this._tick = tick;
}
},
enumerable: false,
configurable: true
});
/**
* Get the row count for a region in the life data model.
*/
Model.prototype.rowCount = function (region) {
return this._data.length;
return this._rowCount;
};
/**
* Get the column count for a region in the life data model.
*/
Model.prototype.columnCount = function (region) {
return this._data[0].length;
return this._columnCount;
};
/**
* Get the data for a cell in the life data model.
*/
Model.prototype.data = function (region, row, column) {
return this._data[row][column];
return this.state[row][column];
};
/**
* Dispose the model.
*/
Model.prototype.dispose = function () {
this._ticker.dispose();
};
/**
* Start ticking the life widget, rendering each generation.
*/
Model.prototype.start = function () {
var _this = this;
var swap = false;
if (this._started) {
this.stop();
}
this._started = window.setInterval(function () {
// Use a pointer to swap lists back so their names make semantic sense.
if (swap = !swap) {
var swapped = _this._data;
_this._data = _this._swap;
_this._swap = swapped;
}
_this._tick(_this._swap, _this._data);
_this.emitChanged({
type: 'cells-changed',
rowSpan: _this._data.length,
columnSpan: _this._data[0].length,
region: 'body',
rowIndex: 0,
columnIndex: 0
});
}, this._interval);
void this._ticker.start();
};

@@ -111,6 +219,3 @@ /**

Model.prototype.stop = function () {
if (this._started) {
window.clearInterval(this._started);
this._started = 0;
}
void this._ticker.stop();
};

@@ -142,6 +247,6 @@ return Model;

var row = [];
data.push(row);
for (var j = 0; j < columns; j += 1) {
row[j] = Math.random() < likelihood ? 1 : 0;
}
data.push(row);
}

@@ -154,6 +259,4 @@ return data;

*
* @param input - The current state of the world.
* @param current - The current state of the world.
*
* @param output - An array that will be populated with the next generation.
*
* @param fluctuation - An optional value between 0 and 1 that indicates the

@@ -164,7 +267,7 @@ * likelihood that a bit will flip, contravening the rules.

* Instead of accepting a single state array, this function takes an `input`
* and an `output` array to faciliate swapping back and forth between
* and an `output` array to facilitate swapping back and forth between
* generation arrays without needing to reallocate memory. The `input` and
* `output` arrays must have the same dimensions.
*/
function tick(input, output, fluctuation) {
function tick(input, fluctuation) {
if (fluctuation === void 0) { fluctuation = 0; }

@@ -175,3 +278,5 @@ var rows = input.length;

var lastRow = rows - 1;
var output = new Array(rows);
for (var i = 0; i < rows; i += 1) {
output[i] = new Array(columns);
for (var j = 0; j < columns; j += 1) {

@@ -195,3 +300,3 @@ var alive = input[i][j];

// Any live cell with more than three live neighbors dies.
// Any dead cell with exactly three live neighbors becomes a live cell.
// Any dead cell with exactly three live neighbors comes to life.
if (alive && neighbors < 2) {

@@ -213,27 +318,60 @@ cell = 0;

}
output[i][j] = cell; // Record the tick value.
output[i][j] = cell;
}
}
return output;
}
Model.tick = tick;
})(Model = Life.Model || (Life.Model = {}));
/**
* Create a `DataGrid` to render a `Life.Model`.
*
* @param model - The `Life` model.
*
* @param style - The `Life` style.
*
* @returns A `DataGrid` that renders the `Life` model.
*/
function create(model, style) {
if (style === void 0) { style = {}; }
var size = Math.max(Life.MINIMUM_SIZE, style.size || 20);
var alive = style.alive || "rgb(0, 0, 0)";
var empty = style.empty || "rgb(50, 185, 25)";
var grid = new datagrid_1.DataGrid({
baseColumnSize: style.size || 9,
baseRowSize: style.size || 9,
defaultSizes: {
rowHeaderWidth: size,
rowHeight: size,
columnHeaderHeight: size,
columnWidth: size
},
headerVisibility: 'none',
style: __assign({}, datagrid_1.DataGrid.defaultStyle, { gridLineColor: "rgba(255, 255, 255, 0.5)", voidColor: 'transparent' })
});
var renderer = new datagrid_1.TextRenderer({
backgroundColor: function (_a) {
var value = _a.value;
return value === 1 ? style.alive || "rgb(0, 0, 0)"
: style.empty || "rgb(50, 185, 25)";
minimumSizes: {
rowHeight: Life.MINIMUM_SIZE,
columnWidth: Life.MINIMUM_SIZE,
rowHeaderWidth: Life.MINIMUM_SIZE,
columnHeaderHeight: Life.MINIMUM_SIZE
},
format: function () { return ''; }
style: __assign(__assign({}, datagrid_1.DataGrid.defaultStyle), { gridLineColor: "rgba(255, 255, 255, 0.5)", voidColor: 'transparent' })
});
grid.model = model;
grid.addClass('ad-Life');
grid.cellRenderers.set('body', {}, renderer);
grid.dataModel = model;
grid.addClass('atd-Life');
grid.disposed.connect(function () { model.dispose(); });
var Renderer = /** @class */ (function (_super) {
__extends(Renderer, _super);
function Renderer() {
return _super !== null && _super.apply(this, arguments) || this;
}
Renderer.prototype.paint = function (gc, config) {
_super.prototype.drawBackground.call(this, gc, __assign(__assign({}, config), { height: size, width: size }));
};
return Renderer;
}(datagrid_1.TextRenderer));
grid.cellRenderers.update({
'body': new Renderer({
backgroundColor: function (_a) {
var value = _a.value;
return value === 1 ? alive : empty;
}
})
});
return grid;

@@ -240,0 +378,0 @@ }

{
"name": "@afshin/life",
"version": "0.2.0",
"version": "0.3.0",
"description": "An implementation of Conway's Game of Life",
"main": "lib/index.js",
"files": [
"lib/**/*.{d.ts,eot,gif,html,jpg,js,js.map,json,png,svg,woff2,ttf}",
"style/**/*.{css,eot,gif,html,jpg,json,png,svg,woff2,ttf}"
"lib/*.{d.ts,js,js.map}"
],
"scripts": {
"build": "npm run clean && tsc",
"build:example": "npm run build && cd example && webpack",
"clean": "rimraf lib && rimraf example/dist && rimraf example/lib",
"build": "tsc && webpack",
"clean": "rimraf dist docs lib node_modules",
"docs": "typedoc src --out docs",
"prepublish": "npm run build",
"watch": "npm run clean && tsc --watch",
"watch:example": "npm run build && cd example && webpack --watch"
"watch": "webpack --watch"
},
"author": "Afshin Darian",
"author": "Afshin T. Darian",
"license": "MIT",
"devDependencies": {
"css-loader": "^0.28.10",
"rimraf": "^2.6.2",
"style-loader": "^0.20.3",
"ts-loader": "^4.0.1",
"typedoc": "^0.11.1",
"typescript": "^2.7.2",
"webpack": "^4.1.1",
"webpack-cli": "^2.0.11"
"css-loader": "^5.0.1",
"eslint": "^7.27.0",
"html-loader": "^2.1.2",
"rimraf": "~3.0.0",
"style-loader": "~2.0.0",
"ts-loader": "^9.1.2",
"typedoc": "~0.20.0-beta.27",
"typescript": "~4.1.3",
"webpack": "^5.3.1",
"webpack-cli": "^4.1.0"
},
"dependencies": {
"@phosphor/datagrid": "^0.1.5",
"@phosphor/widgets": "^1.5.0"
"@lumino/datagrid": "^0.20.0",
"@lumino/disposable": "^1.7.0",
"@lumino/polling": "^1.6.0",
"@lumino/widgets": "^1.19.0"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc