j-templates 7.0.72 → 7.0.74

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.
package/DOM/index.d.ts CHANGED
@@ -1,3 +1 @@
1
1
  export * from "./elements";
2
- export * from "./createPropertyAssignment";
3
- export * from "./createEventAssignment";
package/DOM/index.js CHANGED
@@ -16,5 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./elements"), exports);
18
18
  // export * from "./svgElements";
19
- __exportStar(require("./createPropertyAssignment"), exports);
20
- __exportStar(require("./createEventAssignment"), exports);
19
+ // export * from "./createPropertyAssignment";
20
+ // export * from "./createEventAssignment";
package/Node/vNode.js CHANGED
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.vNode = void 0;
4
4
  const Store_1 = require("../Store");
5
5
  const observableScope_1 = require("../Store/Tree/observableScope");
6
- const emitter_1 = require("../Utils/emitter");
7
6
  const functions_1 = require("../Utils/functions");
8
7
  const injector_1 = require("../Utils/injector");
9
8
  const thread_1 = require("../Utils/thread");
@@ -22,7 +21,6 @@ var vNode;
22
21
  node: definition.node ?? null,
23
22
  children: null,
24
23
  destroyed: false,
25
- onDestroyed: null,
26
24
  component: null,
27
25
  scopes: [],
28
26
  };
@@ -36,7 +34,6 @@ var vNode;
36
34
  node: nodeConfig_1.NodeConfig.createTextNode(text),
37
35
  children: null,
38
36
  destroyed: false,
39
- onDestroyed: null,
40
37
  component: null,
41
38
  scopes: [],
42
39
  };
@@ -59,7 +56,6 @@ var vNode;
59
56
  vnode.destroyed = true;
60
57
  vnode.component?.Destroy();
61
58
  Store_1.ObservableScope.DestroyAll(vnode.scopes);
62
- vnode.onDestroyed && emitter_1.Emitter.Emit(vnode.onDestroyed);
63
59
  for (let x = 0; vnode.children && x < vnode.children.length; x++) {
64
60
  DestroyAll(vnode.children[x][1]);
65
61
  Store_1.ObservableScope.Destroy(vnode.children[x][2]);
@@ -2,7 +2,6 @@ import { Component } from "./component";
2
2
  import { IObservableScope } from "../Store/Tree/observableScope";
3
3
  import { Injector } from "../Utils/injector";
4
4
  import { RecursivePartial } from "../Utils/utils.types";
5
- import { Emitter } from "../Utils/emitter";
6
5
  export type FunctionOr<T> = {
7
6
  (): T | Promise<T>;
8
7
  } | T;
@@ -21,7 +20,6 @@ export type vNode = {
21
20
  node: Node | null;
22
21
  children: [any, vNode[], IObservableScope<string | vNode | vNode[]> | null][] | null;
23
22
  destroyed: boolean;
24
- onDestroyed: Emitter | null;
25
23
  scopes: IObservableScope<unknown>[];
26
24
  component: Component;
27
25
  };
@@ -2,10 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObservableScope = void 0;
4
4
  exports.CalcScope = CalcScope;
5
- const array_1 = require("../../Utils/array");
5
+ const bitSet_1 = require("../../Utils/bitSet");
6
6
  const emitter_1 = require("../../Utils/emitter");
7
7
  const functions_1 = require("../../Utils/functions");
8
- const list_1 = require("../../Utils/list");
9
8
  /**
10
9
  * Creates a dynamic (reactive) observable scope.
11
10
  * @template T The type of value stored in the scope.
@@ -46,6 +45,11 @@ function CreateStaticScope(initialValue) {
46
45
  value: initialValue,
47
46
  };
48
47
  }
48
+ /**
49
+ * Queue of scopes pending batched update processing.
50
+ * Scopes are added when their dependencies change and greedy batching is enabled.
51
+ * The queue is processed in a microtask to batch multiple updates efficiently.
52
+ */
49
53
  let scopeQueue = [];
50
54
  /**
51
55
  * Processes all queued scopes, recomputing dirty scopes and emitting changes.
@@ -90,93 +94,78 @@ function OnSet() {
90
94
  emitter_1.Emitter.Emit(this.emitter, this);
91
95
  }
92
96
  /**
93
- * Registers an emitter using SAME_STRATEGY.
94
- * If the emitter is already registered at the current index, increments the index.
95
- * Otherwise, switches to PUSH_STRATEGY and appends the emitter.
96
- * @param state The current watch state.
97
- * @param emitter The emitter to register.
98
- */
99
- function RegisterSame(state, emitter) {
100
- if (state.emitterIndex < state.emitters.length &&
101
- state.emitters[state.emitterIndex] === emitter) {
102
- state.emitterIndex++;
103
- return;
104
- }
105
- state.emitters = state.emitters.slice(0, state.emitterIndex);
106
- state.strategy = SORTED_STRATEGY;
107
- RegisterSorted(state, emitter);
108
- }
109
- /**
110
- * Registers an emitter while maintaining sorted order by emitter ID.
111
- * If insertion would break sort order, falls back to PUSH_STRATEGY.
112
- * @param state The current watch state.
113
- * @param emitter The emitter to register.
97
+ * Strategy where emitters are accessed in the same order as the previous execution.
98
+ * This allows for efficient reconciliation by tracking which emitters were accessed
99
+ * at the same positions in the array.
114
100
  */
115
- function RegisterSorted(state, emitter) {
116
- if (state.emitters.length === 0 ||
117
- state.emitters[state.emitters.length - 1][0] < emitter[0])
118
- state.emitters.push(emitter);
119
- else {
120
- state.strategy = PUSH_STRATEGY;
121
- RegisterPush(state, emitter);
122
- }
123
- }
124
- /**
125
- * Registers an emitter using PUSH_STRATEGY.
126
- * Switches to DISTINCT_STRATEGY when the emitter count exceeds 50 to optimize memory.
127
- * @param state The current watch state.
128
- * @param emitter The emitter to register.
129
- */
130
- function RegisterPush(state, emitter) {
131
- state.emitters.push(emitter);
132
- if (state.emitters.length > 50) {
133
- const idSet = (state.emitterIds = new Set([state.emitters[0][0]]));
134
- let writePos = 0;
135
- for (let x = 1; x < state.emitters.length; x++) {
136
- if (!idSet.has(state.emitters[x][0])) {
137
- state.emitters[++writePos] = state.emitters[x];
138
- idSet.add(state.emitters[x][0]);
139
- }
140
- }
141
- writePos++;
142
- if (writePos < state.emitters.length)
143
- state.emitters.splice(writePos);
144
- state.strategy = DISTINCT_STRATEGY;
145
- }
146
- }
101
+ const SAME_STRATEGY = 1;
147
102
  /**
148
- * Registers an emitter using DISTINCT_STRATEGY.
149
- * Only adds emitters that haven't been registered yet, using an ID set for O(1) lookup.
150
- * @param state The current watch state.
151
- * @param emitter The emitter to register.
103
+ * Strategy where new emitters are pushed to the array when accessed.
104
+ * Used when the access pattern changes from the previous execution.
152
105
  */
153
- function RegisterDistinct(state, emitter) {
154
- if (!state.emitterIds.has(emitter[0])) {
155
- state.emitters.push(emitter);
156
- state.emitterIds.add(emitter[0]);
157
- }
106
+ const PUSH_STRATEGY = 2;
107
+ function GetBitSetFor(emitters) {
108
+ const bitSet = bitSet_1.BitSetPool.Get(BIT_SET_POOL);
109
+ for (let x = 0; x < emitters.length; x++)
110
+ bitSet_1.BitSet.set(bitSet, emitters[x][0]);
111
+ return bitSet;
158
112
  }
159
113
  /**
160
- * Routes an emitter to the appropriate registration strategy based on current watch state.
161
- * Does nothing if not within a watch context.
162
- * @param emitter The emitter to register.
114
+ * Registers an emitter as a dependency during a watch operation.
115
+ *
116
+ * This function tracks which emitters are accessed while executing a scope's getFunction.
117
+ * It uses two strategies for efficiency:
118
+ *
119
+ * - **SAME_STRATEGY**: When emitters are accessed in the same order as the previous execution,
120
+ * it tracks this via emitterIndex and skips array operations. Only switches to PUSH_STRATEGY
121
+ * when the order changes.
122
+ *
123
+ * - **PUSH_STRATEGY**: When access order differs or is new, emitters are pushed to the array.
124
+ * The BitSet prevents duplicates (same emitter accessed multiple times).
125
+ *
126
+ * The function does nothing if called outside a watch context (watchState is null).
127
+ *
128
+ * @param emitter The emitter to register as a dependency. Must have a unique ID at index 0.
163
129
  */
164
130
  function RegisterEmitter(emitter) {
165
131
  if (watchState === null)
166
132
  return;
167
133
  switch (watchState.strategy) {
168
- case SAME_STRATEGY:
169
- RegisterSame(watchState, emitter);
170
- break;
171
- case SORTED_STRATEGY:
172
- RegisterSorted(watchState, emitter);
173
- break;
174
- case PUSH_STRATEGY:
175
- RegisterPush(watchState, emitter);
134
+ case SAME_STRATEGY: {
135
+ if (watchState.emitterIndex < watchState.emitters.length &&
136
+ watchState.emitters[watchState.emitterIndex][0] === emitter[0]) {
137
+ watchState.emitterIndex++;
138
+ // BitSet.set(watchState.emitterIds, emitter[0]);
139
+ }
140
+ else {
141
+ watchState.strategy = PUSH_STRATEGY;
142
+ watchState.emitters = watchState.emitters.slice(0, watchState.emitterIndex);
143
+ RegisterEmitter(emitter);
144
+ }
176
145
  break;
177
- case DISTINCT_STRATEGY:
178
- RegisterDistinct(watchState, emitter);
146
+ }
147
+ case PUSH_STRATEGY: {
148
+ switch (watchState.emitters.length) {
149
+ case 0: {
150
+ watchState.emitters.push(emitter);
151
+ break;
152
+ }
153
+ case 1: {
154
+ if (watchState.emitters[0][0] !== emitter[0])
155
+ watchState.emitters.push(emitter);
156
+ break;
157
+ }
158
+ default: {
159
+ if (watchState.emitters[watchState.emitters.length - 1][0] !== emitter[0]) {
160
+ watchState.emitterIds ??= GetBitSetFor(watchState.emitters);
161
+ if (bitSet_1.BitSet.add(watchState.emitterIds, emitter[0]))
162
+ watchState.emitters.push(emitter);
163
+ }
164
+ break;
165
+ }
166
+ }
179
167
  break;
168
+ }
180
169
  }
181
170
  }
182
171
  /**
@@ -201,47 +190,16 @@ function GetScopeValue(scope) {
201
190
  return scope.value;
202
191
  }
203
192
  /**
204
- * Strategy constants for optimizing emitter registration during watch operations.
205
- * Each strategy represents a different approach to tracking and deduplicating dependencies.
193
+ * Global watch state representing the current dependency tracking context.
194
+ * This is set during scope execution and tracks which emitters/scopes are accessed.
195
+ * Nested watch contexts are supported via the parent reference pattern.
206
196
  */
207
- const SAME_STRATEGY = 1;
208
- const PUSH_STRATEGY = 2;
209
- const SORTED_STRATEGY = 3;
210
- const DISTINCT_STRATEGY = 4;
211
- const SHRINK_STRATEGY = 5;
212
197
  let watchState = null;
213
- const watchPool = list_1.List.Create();
214
- /**
215
- * Creates a new watch state object, reusing from pool if available.
216
- * Object pooling reduces GC pressure during frequent watch operations.
217
- * @returns A new or recycled watch state object.
218
- */
219
- function CreateWatchState() {
220
- return (list_1.List.Pop(watchPool) ?? {
221
- emitterIndex: 0,
222
- value: null,
223
- emitters: null,
224
- emitterIds: null,
225
- currentCalc: null,
226
- nextCalc: null,
227
- strategy: PUSH_STRATEGY,
228
- });
229
- }
230
198
  /**
231
- * Returns a watch state object to the pool for reuse.
232
- * Resets all fields to their default values before pooling.
233
- * @param state The watch state to return to the pool.
199
+ * Pool for recycling BitSet objects to reduce garbage collection overhead.
200
+ * BitSets are borrowed during watch operations and returned after use.
234
201
  */
235
- function ReturnWatchState(state) {
236
- state.emitterIndex = 0;
237
- state.value = null;
238
- state.emitters = null;
239
- state.emitterIds = null;
240
- state.currentCalc = null;
241
- state.nextCalc = null;
242
- state.strategy = SORTED_STRATEGY;
243
- list_1.List.Push(watchPool, state);
244
- }
202
+ const BIT_SET_POOL = bitSet_1.BitSetPool.Create();
245
203
  /**
246
204
  * Executes a callback while tracking all scope and emitter dependencies.
247
205
  * Creates a watch context that records what was accessed during execution.
@@ -251,19 +209,18 @@ function ReturnWatchState(state) {
251
209
  */
252
210
  function WatchFunction(callback, currentCalc, initialEmitters) {
253
211
  const parent = watchState;
254
- watchState = CreateWatchState();
255
- watchState.emitters = initialEmitters ?? [];
256
- watchState.currentCalc = currentCalc;
257
- if (initialEmitters !== null)
258
- watchState.strategy = SAME_STRATEGY;
212
+ watchState = {
213
+ emitterIndex: 0,
214
+ strategy: initialEmitters === null ? PUSH_STRATEGY : SAME_STRATEGY,
215
+ value: null,
216
+ emitters: initialEmitters ?? [],
217
+ emitterIds: null, // BitSetPool.Get(BIT_SET_POOL),
218
+ currentCalc,
219
+ nextCalc: null,
220
+ };
259
221
  watchState.value = callback();
260
222
  const resultState = watchState;
261
223
  watchState = parent;
262
- if (resultState.strategy === SAME_STRATEGY &&
263
- resultState.emitterIndex < resultState.emitters.length) {
264
- resultState.emitters = resultState.emitters.slice(0, resultState.emitterIndex);
265
- resultState.strategy = SHRINK_STRATEGY;
266
- }
267
224
  return resultState;
268
225
  }
269
226
  /**
@@ -274,7 +231,11 @@ function WatchFunction(callback, currentCalc, initialEmitters) {
274
231
  function ExecuteScope(scope) {
275
232
  scope.dirty = false;
276
233
  const state = WatchFunction(scope.getFunction, scope.calcScopes, scope.emitters);
277
- UpdateEmitters(scope, state.emitters, state.strategy);
234
+ if (state.strategy === SAME_STRATEGY &&
235
+ state.emitterIndex < state.emitters.length)
236
+ state.emitters = state.emitters.slice(0, state.emitterIndex);
237
+ UpdateEmitters(scope, state);
238
+ state.emitterIds && bitSet_1.BitSetPool.Return(BIT_SET_POOL, state.emitterIds);
278
239
  const calcScopes = state.currentCalc;
279
240
  scope.calcScopes = state.nextCalc;
280
241
  for (const key in calcScopes)
@@ -286,7 +247,6 @@ function ExecuteScope(scope) {
286
247
  });
287
248
  else
288
249
  scope.value = state.value;
289
- ReturnWatchState(state);
290
250
  }
291
251
  /**
292
252
  * Creates a scope from a function, choosing between static and dynamic based on dependencies.
@@ -302,17 +262,16 @@ function ExecuteFunction(callback, greedy, allowStatic) {
302
262
  if (!allowStatic || async || state.emitters !== null) {
303
263
  const scope = CreateDynamicScope(callback, greedy, async ? null : state.value);
304
264
  scope.calcScopes = state.nextCalc;
305
- UpdateEmitters(scope, state.emitters, state.strategy);
265
+ UpdateEmitters(scope, state);
266
+ state.emitterIds && bitSet_1.BitSetPool.Return(BIT_SET_POOL, state.emitterIds);
306
267
  if (async)
307
268
  state.value.then(function (result) {
308
269
  scope.value = result;
309
270
  emitter_1.Emitter.Emit(scope.emitter, scope);
310
271
  });
311
- ReturnWatchState(state);
312
272
  return scope;
313
273
  }
314
274
  const value = state.value;
315
- ReturnWatchState(state);
316
275
  return CreateStaticScope(value);
317
276
  }
318
277
  /**
@@ -335,7 +294,7 @@ function CalcScope(callback, idOverride) {
335
294
  return callback();
336
295
  const nextScopes = (watchState.nextCalc ??= {});
337
296
  const id = idOverride ?? "default";
338
- if (nextScopes[id]) {
297
+ if (Object.hasOwn(nextScopes, id)) {
339
298
  RegisterScope(nextScopes[id]);
340
299
  return GetScopeValue(nextScopes[id]);
341
300
  }
@@ -347,39 +306,31 @@ function CalcScope(callback, idOverride) {
347
306
  return GetScopeValue(nextScopes[id]);
348
307
  }
349
308
  /**
350
- * Updates a scope's dependency emitters using efficient diffing.
351
- * Subscribes to new emitters and unsubscribes from removed ones.
352
- * @param scope The scope to update dependencies for.
353
- * @param right The new list of emitters to track.
354
- * @param distinct Whether emitters are already unique (sorted and deduplicated).
309
+ * Updates a scope's emitter subscriptions based on the new watch state.
310
+ * Efficiently reconciles old and new emitter lists starting from emitterIndex.
311
+ *
312
+ * Emitters before emitterIndex are in the same position and don't need updates.
313
+ * Emitters at/after emitterIndex are removed if no longer accessed or added if newly accessed.
314
+ *
315
+ * @param scope The scope to update emitter subscriptions for.
316
+ * @param state The watch state containing the new emitter list.
355
317
  */
356
- function UpdateEmitters(scope, right, strategy) {
357
- switch (strategy) {
358
- case SHRINK_STRATEGY: {
359
- for (let x = right.length; x < scope.emitters.length; x++)
360
- emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
361
- break;
318
+ function UpdateEmitters(scope, state) {
319
+ const currentEmitters = scope.emitters;
320
+ const nextEmitters = state.emitters;
321
+ const nextEmitterIds = state.emitterIds;
322
+ const sameIndex = state.emitterIndex;
323
+ if (currentEmitters !== null) {
324
+ for (let x = sameIndex; x < currentEmitters.length; x++) {
325
+ if (nextEmitterIds === null || !bitSet_1.BitSet.remove(nextEmitterIds, currentEmitters[x][0]))
326
+ emitter_1.Emitter.Remove(currentEmitters[x], scope.setCallback);
362
327
  }
363
- case PUSH_STRATEGY:
364
- case DISTINCT_STRATEGY:
365
- strategy === PUSH_STRATEGY
366
- ? emitter_1.Emitter.Distinct(right)
367
- : emitter_1.Emitter.Sort(right);
368
- case SORTED_STRATEGY:
369
- if (scope.emitters === null || scope.emitters.length === 0) {
370
- for (let x = 0; x < right.length; x++)
371
- emitter_1.Emitter.On(right[x], scope.setCallback);
372
- }
373
- else {
374
- (0, array_1.ReconcileSortedEmitters)(scope.emitters, right, function (emitter) {
375
- emitter_1.Emitter.On(emitter, scope.setCallback);
376
- }, function (emitter) {
377
- emitter_1.Emitter.Remove(emitter, scope.setCallback);
378
- });
379
- }
380
- break;
381
328
  }
382
- scope.emitters = right;
329
+ for (let x = sameIndex; x < nextEmitters.length; x++) {
330
+ if (nextEmitterIds === null || bitSet_1.BitSet.has(nextEmitterIds, nextEmitters[x][0]))
331
+ emitter_1.Emitter.On(nextEmitters[x], scope.setCallback);
332
+ }
333
+ scope.emitters = nextEmitters;
383
334
  }
384
335
  /**
385
336
  * Destroys multiple scopes, cleaning up their resources.
@@ -411,6 +362,7 @@ function DestroyScope(scope) {
411
362
  scope.setCallback = null;
412
363
  scope.destroyed = true;
413
364
  scope.onDestroyed && emitter_1.Emitter.Emit(scope.onDestroyed, scope);
365
+ scope.onDestroyed && emitter_1.Emitter.Destroy(scope.onDestroyed);
414
366
  }
415
367
  var ObservableScope;
416
368
  (function (ObservableScope) {
@@ -0,0 +1,23 @@
1
+ export type BitSet = {
2
+ init: boolean;
3
+ buffer: Uint32Array | null;
4
+ activeFrames: Set<number>;
5
+ minFrame: number;
6
+ maxFrame: number;
7
+ };
8
+ export type BitSetPool = {
9
+ pool: BitSet[];
10
+ index: number;
11
+ };
12
+ export declare namespace BitSetPool {
13
+ function Create(): BitSetPool;
14
+ function Get(pool: BitSetPool): BitSet;
15
+ function Return(pool: BitSetPool, bitSet: BitSet): void;
16
+ }
17
+ export declare namespace BitSet {
18
+ function Create(): BitSet;
19
+ function set(set: BitSet, num: number): void;
20
+ function has(set: BitSet, num: number): boolean;
21
+ function add(set: BitSet, num: number): boolean;
22
+ function remove(set: BitSet, num: number): boolean;
23
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BitSet = exports.BitSetPool = void 0;
4
+ // 100000 = 31
5
+ const FRAME_BIT_SHIFT = 5;
6
+ const DEFAULT_FRAME_COUNT = 1024;
7
+ const DEFAULT_FRAME_HALF = DEFAULT_FRAME_COUNT / 2;
8
+ function GetFrame(number) {
9
+ // Effectively equivalent to Math.floor(number / 32)
10
+ return number >>> FRAME_BIT_SHIFT;
11
+ }
12
+ function GetBit(number) {
13
+ // JavaScript only uses rightmost 5 bits of num for this operation
14
+ // Effectively equivalent to number % 32
15
+ return 1 << number;
16
+ }
17
+ function Resize(set, frame) {
18
+ if (set.minFrame <= frame && frame < set.maxFrame)
19
+ return;
20
+ const currentSize = set.maxFrame - set.minFrame;
21
+ let newMin = Math.min(set.minFrame, frame);
22
+ let newMax = Math.max(set.maxFrame, frame + 1);
23
+ let newSize = newMax - newMin;
24
+ const minimumNewSize = currentSize * 2;
25
+ if (newSize < minimumNewSize) {
26
+ const growBy = minimumNewSize - newSize;
27
+ const growByHalf = growBy / 2;
28
+ newMin = newMin - Math.floor(growByHalf);
29
+ newMax = newMax + Math.ceil(growByHalf);
30
+ if (newMin < 0) {
31
+ newMax -= newMin;
32
+ newMin = 0;
33
+ }
34
+ newSize = newMax - newMin;
35
+ }
36
+ const newBuffer = new Uint32Array(newSize);
37
+ newBuffer.set(set.buffer, set.minFrame - newMin);
38
+ set.buffer = newBuffer;
39
+ set.minFrame = newMin;
40
+ set.maxFrame = newMax;
41
+ }
42
+ function Initialize(set, initFrameNumber) {
43
+ if (set.init)
44
+ return;
45
+ set.init = true;
46
+ set.activeFrames.clear();
47
+ const frame = GetFrame(initFrameNumber);
48
+ const sizeHalf = (set.buffer?.length ?? DEFAULT_FRAME_COUNT) / 2;
49
+ set.buffer ??= new Uint32Array(DEFAULT_FRAME_COUNT);
50
+ set.minFrame = frame - Math.floor(sizeHalf);
51
+ set.maxFrame = frame + Math.ceil(sizeHalf);
52
+ if (set.minFrame < 0) {
53
+ set.maxFrame -= set.minFrame;
54
+ set.minFrame = 0;
55
+ }
56
+ }
57
+ var BitSetPool;
58
+ (function (BitSetPool) {
59
+ function Create() {
60
+ return {
61
+ pool: [],
62
+ index: 0
63
+ };
64
+ }
65
+ BitSetPool.Create = Create;
66
+ function Get(pool) {
67
+ return pool.index === 0 ? BitSet.Create() : pool.pool[--pool.index];
68
+ }
69
+ BitSetPool.Get = Get;
70
+ function Return(pool, bitSet) {
71
+ bitSet.init = false;
72
+ pool.pool[pool.index++] = bitSet;
73
+ }
74
+ BitSetPool.Return = Return;
75
+ })(BitSetPool || (exports.BitSetPool = BitSetPool = {}));
76
+ var BitSet;
77
+ (function (BitSet) {
78
+ function Create() {
79
+ return {
80
+ init: false,
81
+ buffer: null,
82
+ activeFrames: new Set(),
83
+ minFrame: -1,
84
+ maxFrame: -1,
85
+ };
86
+ }
87
+ BitSet.Create = Create;
88
+ function set(set, num) {
89
+ Initialize(set, num);
90
+ const frame = GetFrame(num);
91
+ Resize(set, frame);
92
+ if (!set.activeFrames.has(frame)) {
93
+ set.buffer[frame] = 0;
94
+ set.activeFrames.add(frame);
95
+ }
96
+ const frameOffset = frame - set.minFrame;
97
+ set.buffer[frameOffset] |= GetBit(num);
98
+ }
99
+ BitSet.set = set;
100
+ function has(set, num) {
101
+ if (set.buffer === null)
102
+ return false;
103
+ const frame = GetFrame(num);
104
+ if (!set.activeFrames.has(frame))
105
+ return false;
106
+ if (frame < set.minFrame || set.maxFrame <= frame)
107
+ return false;
108
+ const frameOffset = frame - set.minFrame;
109
+ const frameValue = set.buffer[frameOffset] & GetBit(num);
110
+ return frameValue !== 0;
111
+ }
112
+ BitSet.has = has;
113
+ function add(set, num) {
114
+ Initialize(set, num);
115
+ const frame = GetFrame(num);
116
+ Resize(set, frame);
117
+ if (!set.activeFrames.has(frame)) {
118
+ set.buffer[frame] = 0;
119
+ set.activeFrames.add(frame);
120
+ }
121
+ const frameOffset = frame - set.minFrame;
122
+ const frameStart = set.buffer[frameOffset];
123
+ set.buffer[frameOffset] |= GetBit(num);
124
+ return frameStart !== set.buffer[frameOffset];
125
+ }
126
+ BitSet.add = add;
127
+ function remove(set, num) {
128
+ if (set.buffer === null)
129
+ return false;
130
+ const frame = GetFrame(num);
131
+ if (!set.activeFrames.has(frame) || frame < set.minFrame || set.maxFrame <= frame)
132
+ return false;
133
+ const frameOffset = frame - set.minFrame;
134
+ const frameStart = set.buffer[frameOffset];
135
+ set.buffer[frameOffset] ^= GetBit(num);
136
+ return frameStart !== set.buffer[frameOffset];
137
+ }
138
+ BitSet.remove = remove;
139
+ })(BitSet || (exports.BitSet = BitSet = {}));
@@ -8,7 +8,4 @@ export declare namespace Emitter {
8
8
  function Destroy(emitter: Emitter): void;
9
9
  function Remove(emitter: Emitter, callback: EmitterCallback): void;
10
10
  function Clear(emitter: Emitter): void;
11
- function Distinct(emitters: Emitter[]): void;
12
- function Sort(emitters: Emitter[]): void;
13
- function Compare(a: Emitter, b: Emitter): number;
14
11
  }
package/Utils/emitter.js CHANGED
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Emitter = void 0;
4
- const array_1 = require("./array");
4
+ const idPool = [];
5
+ let idPoolIndex = 0;
6
+ let globalId = 0;
5
7
  var Emitter;
6
8
  (function (Emitter) {
7
- let globalId = 0;
8
9
  function Create() {
9
- const emitter = [++globalId];
10
+ const emitterId = idPoolIndex === 0 ? ++globalId : idPool[--idPoolIndex];
11
+ const emitter = [emitterId];
10
12
  return emitter;
11
13
  }
12
14
  Emitter.Create = Create;
@@ -33,6 +35,7 @@ var Emitter;
33
35
  }
34
36
  Emitter.Emit = Emit;
35
37
  function Destroy(emitter) {
38
+ idPool[idPoolIndex++] = emitter[0];
36
39
  emitter[0] = -1;
37
40
  }
38
41
  Emitter.Destroy = Destroy;
@@ -48,30 +51,4 @@ var Emitter;
48
51
  emitter.splice(1);
49
52
  }
50
53
  Emitter.Clear = Clear;
51
- function Distinct(emitters) {
52
- if (emitters.length < 2)
53
- return;
54
- Sort(emitters);
55
- let writePos = 0;
56
- for (let x = 1; x < emitters.length; x++) {
57
- if (emitters[x][0] !== emitters[writePos][0]) {
58
- emitters[++writePos] = emitters[x];
59
- }
60
- }
61
- writePos++;
62
- if (writePos < emitters.length)
63
- emitters.splice(writePos);
64
- }
65
- Emitter.Distinct = Distinct;
66
- function Sort(emitters) {
67
- if (emitters.length < 11)
68
- (0, array_1.InsertionSortTuples)(emitters);
69
- else
70
- emitters.sort(Compare);
71
- }
72
- Emitter.Sort = Sort;
73
- function Compare(a, b) {
74
- return a[0] - b[0];
75
- }
76
- Emitter.Compare = Compare;
77
54
  })(Emitter || (exports.Emitter = Emitter = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "j-templates",
3
- "version": "7.0.72",
3
+ "version": "7.0.74",
4
4
  "description": "j-templates",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/TypesInCode/jTemplates",