@thi.ng/cellular 0.2.73 → 0.2.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/1d.js +221 -355
  2. package/CHANGELOG.md +1 -1
  3. package/README.md +1 -1
  4. package/api.js +0 -1
  5. package/package.json +13 -10
package/1d.js CHANGED
@@ -12,369 +12,235 @@ import { transduce } from "@thi.ng/transducers/transduce";
12
12
  const $0 = BigInt(0);
13
13
  const $1 = BigInt(1);
14
14
  const $32 = BigInt(32);
15
- /**
16
- * Standard Wolfram automata 3-neighborhood (no history)
17
- */
18
- export const WOLFRAM3 = [
19
- [-1, 0],
20
- [0, 0],
21
- [1, 0],
15
+ const WOLFRAM3 = [
16
+ [-1, 0],
17
+ [0, 0],
18
+ [1, 0]
22
19
  ];
23
- /**
24
- * Standard 5-neighborhood (no history)
25
- */
26
- export const WOLFRAM5 = [[-2, 0], ...WOLFRAM3, [2, 0]];
27
- /**
28
- * Standard 7-neighborhood (no history)
29
- */
30
- export const WOLFRAM7 = [[-3, 0], ...WOLFRAM5, [3, 0]];
31
- /**
32
- * Implementation of a 1D cellular automata environment with support for
33
- * multiple automata, each with its own settings for replication rules,
34
- * arbitrary neighborhood kernels (optionally with short term memory) and number
35
- * of cell states, all selectable via a shared per-cell mask array. This generic
36
- * setup enables many novel and unusual CA setups as well as coevolution of
37
- * multiple CAs within a shared environment.
38
- *
39
- * @remarks
40
- * ### Neighborhoods
41
- *
42
- * Cell neighborhoods are defined via an arbitrary number of 2D offset vectors
43
- * `[x, y]`, where `x` coordinates are horizontal offsets and positive `y`
44
- * coordinates are used to refer to previous generations (e.g. 0 = current gen,
45
- * 1 = T-1, 2 = T-2 etc.) and thereby providing a form of short term memory for
46
- * that specific automata. Negative `y` coords will lead to cells being ignored.
47
- *
48
- * ### Rule encoding
49
- *
50
- * Automata rules are encoded as JS `BigInt` values and are considered
51
- * anisotropic by default. If isotropy is desired, it has to be explicitly
52
- * pre-encoded [out of scope of this library]. There's also built-in optional
53
- * support for position independent neighborhood encoding, only considering the
54
- * number/count of non-zero cells. An encoded rule ID and its overall magnitude
55
- * is directly related and dependent on the size and shape of its kernel config,
56
- * e.g.:
57
- *
58
- * ```ts
59
- * kernel = [[-2, 1], [-1, 0], [0, 0], [1, 0], [2, 1]]
60
- * ```
61
- *
62
- * This example kernel defines a 5-cell neighborhood with a max. short term
63
- * memory of one additional previous generation (i.e. the [-2,1] and [2,1]
64
- * offsets)
65
- *
66
- * The rules related to this kernel have a 32 bit address space (4 billion
67
- * possibilities), due to 2^5 = 32 and each kernel offset being assigned a
68
- * distinct bit value by default, i.e. first kernel offset = 2^0, second kernel
69
- * offset = 2^1, third = 2^2, fourth = 2^3, fifth = 2^4. Via the
70
- * {@link CASpec1D.positional} config option, this behavior can be overridden
71
- * per kernel, to achieve position-independent kernels (with much smaller rule
72
- * spaces).
73
- *
74
- * Given the following example cell matrix with the center cell highlighted with
75
- * caret (`^`):
76
- *
77
- * ```text
78
- * T-1: 2 0 1 2 1
79
- * T-0: 0 1 0 3 0
80
- * ^
81
- * ```
82
- *
83
- * The above example kernel will select the following values and assign bit
84
- * positions (for all non-zero cell states) to compute a summed ID:
85
- *
86
- * | k index | offset | cell value | encoded |
87
- * |--------:|-----------|-----------:|--------:|
88
- * | 0 | `[-2, 1]` | 2 | 1 |
89
- * | 1 | `[-1, 0]` | 1 | 2 |
90
- * | 2 | `[0, 0]` | 0 | 0 |
91
- * | 3 | `[1, 0]` | 3 | 8 |
92
- * | 4 | `[2, 1]` | 1 | 16 |
93
- *
94
- * Final encoded neighborhood sum: 1 + 2 + 8 + 16 = 27
95
- *
96
- * To determine if a the current cell should be active or not in the next
97
- * generation, we now use that encoded sum as bit position to test a single bit
98
- * of the automata's rule ID, i.e. here we're testing bit 27. If that
99
- * corresponding bit is set in the rule ID, the cell's state will be increased
100
- * by 1.
101
- *
102
- * ### Cell states
103
- *
104
- * Each automata config can define a max. number of possible cell states (aka
105
- * age). Once a cell reaches the configured `numStates`, it automatically resets
106
- * to zero. This is by default, but can be overridden via the
107
- * {@link CASpec1D.reset} option. Conversely, if the corresponding bit is _not_
108
- * set in the rule ID, the cell state will be zeroed too.
109
- *
110
- * ### Update probabilities
111
- *
112
- * Each cell has an optional update probability, which is initialized to 1.0 by
113
- * default (i.e. to always be updated). Use
114
- * {@link MultiCA1D.updateProbabilistic} or {@link MultiCA1D.updateImage} to
115
- * take these probabilities into account.
116
- *
117
- * ### Wraparound
118
- *
119
- * By default the environment is configured to be toroidal, i.e. both left/right
120
- * sides of the env are connected. The behavior can be controlled via a ctor arg
121
- * and/or at runtime via the {@link MultiCA1D.wrap} property.
122
- *
123
- * ### Masks
124
- *
125
- * The {@link MultiCA1D.mask} array can be used to select different CA
126
- * configurations for each cell in the environment. Because this mask array is
127
- * initialized to zero, only the first CA configuration will be used for all
128
- * cells in the environment by default. It's the user's responsibility to manage
129
- * the mask and select/enable other (if any) CA configs for individual cells
130
- * (usually cell ranges). The values stored in this array correspond to the
131
- * indices of the {@link MultiCA1D.config} array given at construction.
132
- *
133
- * ### Limits
134
- *
135
- * Due to using `Uint8Arrays` for storage, only up to 256 cell states are
136
- * supported. The same limit applies to the number of CA configs given.
137
- *
138
- * @example
139
- * ```ts
140
- * // classic Wolfram Rule 110 automata
141
- * const wolfram = new MultiCA1D(
142
- * [{
143
- * kernel: [[-1, 0], [0, 0], [1, 0]],
144
- * rule: 110,
145
- * states: 2,
146
- * reset: false
147
- * }],
148
- * 256
149
- * )
150
- * ```
151
- */
152
- export class MultiCA1D {
153
- width;
154
- wrap;
155
- configs;
156
- rows;
157
- numStates;
158
- mask;
159
- gens;
160
- prob;
161
- constructor(configs, width, wrap = true) {
162
- this.width = width;
163
- this.wrap = wrap;
164
- this.configs = configs.map(__compileSpec);
165
- this.rows =
166
- transduce(mapcat((c) => map((k) => k[1], c.kernel)), max(), configs) + 1;
167
- this.numStates = transduce(pluck("states"), max(), configs);
168
- assert(this.numStates >= 2 && this.numStates <= 256, "num states must be in [2..256] range");
169
- this.resize(width);
20
+ const WOLFRAM5 = [[-2, 0], ...WOLFRAM3, [2, 0]];
21
+ const WOLFRAM7 = [[-3, 0], ...WOLFRAM5, [3, 0]];
22
+ class MultiCA1D {
23
+ constructor(configs, width, wrap = true) {
24
+ this.width = width;
25
+ this.wrap = wrap;
26
+ this.configs = configs.map(__compileSpec);
27
+ this.rows = transduce(
28
+ mapcat((c) => map((k) => k[1], c.kernel)),
29
+ max(),
30
+ configs
31
+ ) + 1;
32
+ this.numStates = transduce(pluck("states"), max(), configs);
33
+ assert(
34
+ this.numStates >= 2 && this.numStates <= 256,
35
+ "num states must be in [2..256] range"
36
+ );
37
+ this.resize(width);
38
+ }
39
+ configs;
40
+ rows;
41
+ numStates;
42
+ mask;
43
+ gens;
44
+ prob;
45
+ get current() {
46
+ return this.gens[1];
47
+ }
48
+ get previous() {
49
+ return this.gens[2 % this.gens.length];
50
+ }
51
+ clear() {
52
+ this.gens.forEach((g) => g.fill(0));
53
+ this.mask.fill(0);
54
+ this.prob.fill(1);
55
+ }
56
+ clearTarget(target) {
57
+ this._getTarget(target)[0].fill(target === "prob" ? 1 : 0);
58
+ }
59
+ resize(width) {
60
+ this.width = width;
61
+ this.mask = new Uint8Array(width);
62
+ this.gens = [...repeatedly(() => new Uint8Array(width), this.rows + 1)];
63
+ this.prob = new Float32Array(width).fill(1);
64
+ }
65
+ /**
66
+ * Sets a parametric pattern in the current generation or mask array.
67
+ *
68
+ * @param target - target buffer ID to apply pattern
69
+ * @param width - number of consecutive cells per segment
70
+ * @param stride - number of cells between each pattern segment
71
+ * @param val - start cell value per segment
72
+ * @param inc - cell value increment
73
+ * @param offset - start cell offset
74
+ */
75
+ setPattern(target, width, stride, val = 1, inc = 0, offset = 0) {
76
+ const [dest, num] = this._getTarget(target);
77
+ for (let x = offset, w = this.width; x < w; x += stride) {
78
+ for (let k = 0, v = val; k < width; k++, v += inc) {
79
+ dest[x + k] = v % num;
80
+ }
170
81
  }
171
- get current() {
172
- return this.gens[1];
82
+ return this;
83
+ }
84
+ /**
85
+ * Sets cells in current generation array to a random state using given
86
+ * `probability` and optional PRNG
87
+ * ([`IRandom`](https://docs.thi.ng/umbrella/random/interfaces/IRandom.html)
88
+ * instance).
89
+ *
90
+ * @param target
91
+ * @param prob
92
+ * @param rnd
93
+ */
94
+ setNoise(target, prob = 0.5, rnd = SYSTEM) {
95
+ const [dest, num] = this._getTarget(target);
96
+ const fn = target === "prob" ? () => rnd.float() : () => rnd.int() % num;
97
+ for (let x = 0, width = this.width; x < width; x++) {
98
+ if (rnd.probability(prob))
99
+ dest[x] = fn();
173
100
  }
174
- get previous() {
175
- return this.gens[2 % this.gens.length];
101
+ return this;
102
+ }
103
+ /**
104
+ * Computes a single new generation using current cell states and mask only
105
+ * (no consideration for cell update probabilities, use
106
+ * {@link MultiCA1D.updateProbabilistic} for that instead). Als see
107
+ * {@link MultiCA1D.updateImage} for batch updates.
108
+ */
109
+ update() {
110
+ const { width, gens, configs, mask } = this;
111
+ const [next, curr] = gens;
112
+ for (let x = 0; x < width; x++) {
113
+ next[x] = this.computeCell(configs[mask[x]], x, curr[x]);
176
114
  }
177
- clear() {
178
- this.gens.forEach((g) => g.fill(0));
179
- this.mask.fill(0);
180
- this.prob.fill(1);
115
+ gens.unshift(gens.pop());
116
+ }
117
+ /**
118
+ * Same as {@link MultiCA1D.update}, but also considering cell update
119
+ * probabilities stored in the {@link MultiCA1D.prob} array.
120
+ *
121
+ * @param rnd
122
+ */
123
+ updateProbabilistic(rnd = SYSTEM) {
124
+ const { width, prob, gens, configs, mask } = this;
125
+ const [next, curr] = gens;
126
+ for (let x = 0; x < width; x++) {
127
+ next[x] = rnd.probability(prob[x]) ? this.computeCell(configs[mask[x]], x, curr[x]) : curr[x];
181
128
  }
182
- clearTarget(target) {
183
- this._getTarget(target)[0].fill(target === "prob" ? 1 : 0);
129
+ gens.unshift(gens.pop());
130
+ }
131
+ /**
132
+ * Computes (but doesn't apply) the new state for a single cell.
133
+ *
134
+ * @param config - CA configuration
135
+ * @param x - cell index
136
+ * @param val - current cell value
137
+ */
138
+ computeCell({ rule, kernel, weights, fn }, x, val) {
139
+ const { width, gens, wrap } = this;
140
+ let sum = $0;
141
+ for (let i = 0, n = kernel.length; i < n; i++) {
142
+ const k = kernel[i];
143
+ let xx = x + k[0];
144
+ if (wrap) {
145
+ if (xx < 0)
146
+ xx += width;
147
+ else if (xx >= width)
148
+ xx -= width;
149
+ } else if (xx < 0 || xx >= width)
150
+ continue;
151
+ const y = k[1];
152
+ if (y >= 0 && gens[1 + y][xx] !== 0)
153
+ sum += weights[i];
184
154
  }
185
- resize(width) {
186
- this.width = width;
187
- this.mask = new Uint8Array(width);
188
- this.gens = [...repeatedly(() => new Uint8Array(width), this.rows + 1)];
189
- this.prob = new Float32Array(width).fill(1);
190
- }
191
- /**
192
- * Sets a parametric pattern in the current generation or mask array.
193
- *
194
- * @param target - target buffer ID to apply pattern
195
- * @param width - number of consecutive cells per segment
196
- * @param stride - number of cells between each pattern segment
197
- * @param val - start cell value per segment
198
- * @param inc - cell value increment
199
- * @param offset - start cell offset
200
- */
201
- setPattern(target, width, stride, val = 1, inc = 0, offset = 0) {
202
- const [dest, num] = this._getTarget(target);
203
- for (let x = offset, w = this.width; x < w; x += stride) {
204
- for (let k = 0, v = val; k < width; k++, v += inc) {
205
- dest[x + k] = v % num;
206
- }
207
- }
208
- return this;
209
- }
210
- /**
211
- * Sets cells in current generation array to a random state using given
212
- * `probability` and optional PRNG
213
- * ([`IRandom`](https://docs.thi.ng/umbrella/random/interfaces/IRandom.html)
214
- * instance).
215
- *
216
- * @param target
217
- * @param prob
218
- * @param rnd
219
- */
220
- setNoise(target, prob = 0.5, rnd = SYSTEM) {
221
- const [dest, num] = this._getTarget(target);
222
- const fn = target === "prob" ? () => rnd.float() : () => rnd.int() % num;
223
- for (let x = 0, width = this.width; x < width; x++) {
224
- if (rnd.probability(prob))
225
- dest[x] = fn();
226
- }
227
- return this;
228
- }
229
- /**
230
- * Computes a single new generation using current cell states and mask only
231
- * (no consideration for cell update probabilities, use
232
- * {@link MultiCA1D.updateProbabilistic} for that instead). Als see
233
- * {@link MultiCA1D.updateImage} for batch updates.
234
- */
235
- update() {
236
- const { width, gens, configs, mask } = this;
237
- const [next, curr] = gens;
238
- for (let x = 0; x < width; x++) {
239
- next[x] = this.computeCell(configs[mask[x]], x, curr[x]);
240
- }
241
- gens.unshift(gens.pop());
242
- }
243
- /**
244
- * Same as {@link MultiCA1D.update}, but also considering cell update
245
- * probabilities stored in the {@link MultiCA1D.prob} array.
246
- *
247
- * @param rnd
248
- */
249
- updateProbabilistic(rnd = SYSTEM) {
250
- const { width, prob, gens, configs, mask } = this;
251
- const [next, curr] = gens;
252
- for (let x = 0; x < width; x++) {
253
- next[x] = rnd.probability(prob[x])
254
- ? this.computeCell(configs[mask[x]], x, curr[x])
255
- : curr[x];
256
- }
257
- gens.unshift(gens.pop());
258
- }
259
- /**
260
- * Computes (but doesn't apply) the new state for a single cell.
261
- *
262
- * @param config - CA configuration
263
- * @param x - cell index
264
- * @param val - current cell value
265
- */
266
- computeCell({ rule, kernel, weights, fn }, x, val) {
267
- const { width, gens, wrap } = this;
268
- let sum = $0;
269
- for (let i = 0, n = kernel.length; i < n; i++) {
270
- const k = kernel[i];
271
- let xx = x + k[0];
272
- if (wrap) {
273
- if (xx < 0)
274
- xx += width;
275
- else if (xx >= width)
276
- xx -= width;
277
- }
278
- else if (xx < 0 || xx >= width)
279
- continue;
280
- const y = k[1];
281
- if (y >= 0 && gens[1 + y][xx] !== 0)
282
- sum += weights[i];
283
- }
284
- return rule & ($1 << sum) ? fn(val) : 0;
285
- }
286
- /**
287
- * Batch version of {@link MultiCA1D.update} to compute an entire image of
288
- * given `height` (and assumed to be the same width as this CA instance has
289
- * been configured to). Fills given `pixels` array with consecutive
290
- * generations.
291
- *
292
- * @remarks
293
- * Via the provided options object, per-generation & per-cell perturbance
294
- * settings can be provided for cell states, mask and cell update
295
- * probabilities. The latter are only considered if the
296
- * {@link UpdateImageOpts1D.probabilistic} option is enabled. This can be
297
- * helpful to sporadically introduce noise into the sim, break constant
298
- * patterns and/or produce more varied/complex outputs.
299
- *
300
- * See {@link UpdateImageOpts1D} for further options.
301
- *
302
- * @param pixels
303
- * @param height
304
- * @param opts
305
- */
306
- updateImage(pixels, height, opts = {}) {
307
- assert(pixels.length >= this.width * height, "target pixel buffer too small");
308
- const { cells, mask, prob, probabilistic, rnd, onupdate } = {
309
- probabilistic: false,
310
- rnd: SYSTEM,
311
- ...opts,
312
- };
313
- const $ = (id, conf) => {
314
- conf &&
315
- conf.perturb &&
316
- rnd.probability(conf.perturb) &&
317
- this.setNoise(id, conf.density || 0.05, rnd);
318
- };
319
- for (let y = 0; y < height; y++) {
320
- $("cells", cells);
321
- $("mask", mask);
322
- $("prob", prob);
323
- probabilistic ? this.updateProbabilistic(rnd) : this.update();
324
- onupdate && onupdate(this, y);
325
- pixels.set(this.current, y * this.width);
326
- }
327
- }
328
- rotate(target, dir) {
329
- if (target === "all") {
330
- rotateTyped(this.current, dir);
331
- rotateTyped(this.mask, dir);
332
- rotateTyped(this.prob, dir);
333
- }
334
- else {
335
- rotateTyped(this._getTarget(target)[0], dir);
336
- }
155
+ return rule & $1 << sum ? fn(val) : 0;
156
+ }
157
+ /**
158
+ * Batch version of {@link MultiCA1D.update} to compute an entire image of
159
+ * given `height` (and assumed to be the same width as this CA instance has
160
+ * been configured to). Fills given `pixels` array with consecutive
161
+ * generations.
162
+ *
163
+ * @remarks
164
+ * Via the provided options object, per-generation & per-cell perturbance
165
+ * settings can be provided for cell states, mask and cell update
166
+ * probabilities. The latter are only considered if the
167
+ * {@link UpdateImageOpts1D.probabilistic} option is enabled. This can be
168
+ * helpful to sporadically introduce noise into the sim, break constant
169
+ * patterns and/or produce more varied/complex outputs.
170
+ *
171
+ * See {@link UpdateImageOpts1D} for further options.
172
+ *
173
+ * @param pixels
174
+ * @param height
175
+ * @param opts
176
+ */
177
+ updateImage(pixels, height, opts = {}) {
178
+ assert(
179
+ pixels.length >= this.width * height,
180
+ "target pixel buffer too small"
181
+ );
182
+ const { cells, mask, prob, probabilistic, rnd, onupdate } = {
183
+ probabilistic: false,
184
+ rnd: SYSTEM,
185
+ ...opts
186
+ };
187
+ const $ = (id, conf) => {
188
+ conf && conf.perturb && rnd.probability(conf.perturb) && this.setNoise(id, conf.density || 0.05, rnd);
189
+ };
190
+ for (let y = 0; y < height; y++) {
191
+ $("cells", cells);
192
+ $("mask", mask);
193
+ $("prob", prob);
194
+ probabilistic ? this.updateProbabilistic(rnd) : this.update();
195
+ onupdate && onupdate(this, y);
196
+ pixels.set(this.current, y * this.width);
337
197
  }
338
- _getTarget(target) {
339
- return target === "cells"
340
- ? [this.current, this.numStates]
341
- : target === "mask"
342
- ? [this.mask, this.configs.length]
343
- : [this.prob, 1];
198
+ }
199
+ rotate(target, dir) {
200
+ if (target === "all") {
201
+ rotateTyped(this.current, dir);
202
+ rotateTyped(this.mask, dir);
203
+ rotateTyped(this.prob, dir);
204
+ } else {
205
+ rotateTyped(this._getTarget(target)[0], dir);
344
206
  }
207
+ }
208
+ _getTarget(target) {
209
+ return target === "cells" ? [this.current, this.numStates] : target === "mask" ? [this.mask, this.configs.length] : [this.prob, 1];
210
+ }
345
211
  }
346
- const __compileSpec = ({ rule, kernel, positional, states, reset, }) => {
347
- const max = states - 1;
348
- return {
349
- kernel,
350
- states,
351
- rule: isBigInt(rule) ? rule : BigInt(rule),
352
- weights: positional !== false
353
- ? kernel.map((_, i) => BigInt(2) ** BigInt(i))
354
- : [...repeat($1, kernel.length)],
355
- fn: reset !== false
356
- ? (y) => (++y >= states ? 0 : y)
357
- : (y) => (++y >= max ? max : y),
358
- };
212
+ const __compileSpec = ({
213
+ rule,
214
+ kernel,
215
+ positional,
216
+ states,
217
+ reset
218
+ }) => {
219
+ const max2 = states - 1;
220
+ return {
221
+ kernel,
222
+ states,
223
+ rule: isBigInt(rule) ? rule : BigInt(rule),
224
+ weights: positional !== false ? kernel.map((_, i) => BigInt(2) ** BigInt(i)) : [...repeat($1, kernel.length)],
225
+ fn: reset !== false ? (y) => ++y >= states ? 0 : y : (y) => ++y >= max2 ? max2 : y
226
+ };
359
227
  };
360
- /**
361
- * Creates a random rule ID for given `kernelSize` and using optionally provided
362
- * `rnd`
363
- * [`IRandom`](https://docs.thi.ng/umbrella/random/interfaces/IRandom.html)
364
- * instance.
365
- *
366
- * @param kernelSize
367
- * @param rnd
368
- */
369
- export const randomRule1D = (kernelSize, rnd = SYSTEM) => {
370
- const n = BigInt(2 ** kernelSize);
371
- let id = $0;
372
- for (let i = $0; i < n; i += $32) {
373
- id <<= $32;
374
- let mask = n - i;
375
- if (mask > $32)
376
- mask = $32;
377
- id |= BigInt(rnd.int()) & (($1 << mask) - $1);
378
- }
379
- return id;
228
+ const randomRule1D = (kernelSize, rnd = SYSTEM) => {
229
+ const n = BigInt(2 ** kernelSize);
230
+ let id = $0;
231
+ for (let i = $0; i < n; i += $32) {
232
+ id <<= $32;
233
+ let mask = n - i;
234
+ if (mask > $32)
235
+ mask = $32;
236
+ id |= BigInt(rnd.int()) & ($1 << mask) - $1;
237
+ }
238
+ return id;
239
+ };
240
+ export {
241
+ MultiCA1D,
242
+ WOLFRAM3,
243
+ WOLFRAM5,
244
+ WOLFRAM7,
245
+ randomRule1D
380
246
  };
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-09T19:12:03Z
3
+ - **Last updated**: 2023-12-18T13:41:19Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/README.md CHANGED
@@ -161,7 +161,7 @@ For Node.js REPL:
161
161
  const cellular = await import("@thi.ng/cellular");
162
162
  ```
163
163
 
164
- Package sizes (brotli'd, pre-treeshake): ESM: 1.48 KB
164
+ Package sizes (brotli'd, pre-treeshake): ESM: 1.46 KB
165
165
 
166
166
  ## Dependencies
167
167
 
package/api.js CHANGED
@@ -1 +0,0 @@
1
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/cellular",
3
- "version": "0.2.73",
3
+ "version": "0.2.75",
4
4
  "description": "Highly customizable 1D cellular automata, shared env, multiple rules, arbitrary sized/shaped neighborhoods, short term memory, cell states etc.",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -24,7 +24,9 @@
24
24
  "author": "Karsten Schmidt (https://thi.ng)",
25
25
  "license": "Apache-2.0",
26
26
  "scripts": {
27
- "build": "yarn clean && tsc --declaration",
27
+ "build": "yarn build:esbuild && yarn build:decl",
28
+ "build:decl": "tsc --declaration --emitDeclarationOnly",
29
+ "build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
28
30
  "clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc",
29
31
  "doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
30
32
  "doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
@@ -33,15 +35,16 @@
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@thi.ng/api": "^8.9.11",
37
- "@thi.ng/arrays": "^2.7.7",
38
- "@thi.ng/checks": "^3.4.11",
39
- "@thi.ng/errors": "^2.4.5",
40
- "@thi.ng/random": "^3.6.17",
41
- "@thi.ng/transducers": "^8.8.14"
38
+ "@thi.ng/api": "^8.9.13",
39
+ "@thi.ng/arrays": "^2.7.9",
40
+ "@thi.ng/checks": "^3.4.13",
41
+ "@thi.ng/errors": "^2.4.7",
42
+ "@thi.ng/random": "^3.6.19",
43
+ "@thi.ng/transducers": "^8.8.16"
42
44
  },
43
45
  "devDependencies": {
44
46
  "@microsoft/api-extractor": "^7.38.3",
47
+ "esbuild": "^0.19.8",
45
48
  "rimraf": "^5.0.5",
46
49
  "tools": "^0.0.1",
47
50
  "typedoc": "^0.25.4",
@@ -67,7 +70,7 @@
67
70
  "setTimeout": false
68
71
  },
69
72
  "engines": {
70
- "node": ">=14"
73
+ "node": ">=18"
71
74
  },
72
75
  "files": [
73
76
  "./*.js",
@@ -91,5 +94,5 @@
91
94
  ],
92
95
  "year": 2022
93
96
  },
94
- "gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n"
97
+ "gitHead": "25a42a81fac8603a1e440a7aa8bc343276211ff4\n"
95
98
  }