reactronic 0.22.313 → 0.22.316

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.
@@ -5,11 +5,11 @@ import { ObjectHandle, Subscription, Meta } from './Data';
5
5
  import { Changeset, Dump, EMPTY_SNAPSHOT, MAX_REVISION } from './Changeset';
6
6
  import { Transaction } from './Transaction';
7
7
  import { MonitorImpl } from './Monitor';
8
- import { Hooks, OptionsImpl } from './Hooks';
8
+ import { Mvcc, OptionsImpl } from './Mvcc';
9
9
  import { JournalImpl } from './Journal';
10
10
  const BOOT_ARGS = [];
11
11
  const BOOT_CAUSE = '<boot>';
12
- const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Hooks.handler, EMPTY_SNAPSHOT, '<empty>');
12
+ const EMPTY_HANDLE = new ObjectHandle(undefined, undefined, Mvcc.reactive, EMPTY_SNAPSHOT, '<empty>');
13
13
  export class OperationController extends Controller {
14
14
  constructor(h, m) {
15
15
  super();
@@ -36,12 +36,12 @@ export class OperationController extends Controller {
36
36
  && (!weak || op.cause === BOOT_CAUSE || !op.successor ||
37
37
  op.successor.transaction.isFinished)) {
38
38
  const outerOpts = (_a = Operation.current) === null || _a === void 0 ? void 0 : _a.options;
39
- const standalone = weak || opts.standalone || opts.kind === Kind.Reaction ||
39
+ const separation = weak || opts.separation || opts.kind === Kind.Reaction ||
40
40
  (opts.kind === Kind.Transaction && outerOpts && (outerOpts.noSideEffects || outerOpts.kind === Kind.Cache)) ||
41
41
  (opts.kind === Kind.Cache && (oc.snapshot.changeset.sealed ||
42
42
  oc.snapshot.former.snapshot !== EMPTY_SNAPSHOT));
43
43
  const token = opts.noSideEffects ? this : undefined;
44
- const oc2 = this.run(oc, standalone, opts, token, args);
44
+ const oc2 = this.run(oc, separation, opts, token, args);
45
45
  const ctx2 = oc2.operation.changeset;
46
46
  if (!weak || ctx === ctx2 || (ctx2.sealed && ctx.timestamp >= ctx2.timestamp))
47
47
  oc = oc2;
@@ -53,7 +53,7 @@ export class OperationController extends Controller {
53
53
  Changeset.markUsed(t, oc.snapshot, this.memberName, this.objectHandle, t.options.kind, weak);
54
54
  return t;
55
55
  }
56
- static of(method) {
56
+ static getControllerOf(method) {
57
57
  const ctl = Meta.get(method, Meta.Controller);
58
58
  if (!ctl)
59
59
  throw misuse(`given method is not decorated as reactronic one: ${method.name}`);
@@ -137,8 +137,8 @@ export class OperationController extends Controller {
137
137
  if (op.controller !== this) {
138
138
  if (os.changeset !== EMPTY_SNAPSHOT.changeset) {
139
139
  const hint = Log.isOn ? `${Dump.obj(this.objectHandle, m)}/boot` : 'MethodController/init';
140
- const standalone = os.changeset.sealed || os.former.snapshot !== EMPTY_SNAPSHOT;
141
- op = Transaction.run({ hint, standalone, token: this }, () => {
140
+ const separation = os.changeset.sealed || os.former.snapshot !== EMPTY_SNAPSHOT;
141
+ op = Transaction.run({ hint, separation, token: this }, () => {
142
142
  const h = this.objectHandle;
143
143
  let r2 = Changeset.current().getObjectSnapshot(h, m);
144
144
  let op2 = r2.data[m];
@@ -168,10 +168,10 @@ export class OperationController extends Controller {
168
168
  }
169
169
  return op;
170
170
  }
171
- run(existing, standalone, options, token, args) {
171
+ run(existing, separation, options, token, args) {
172
172
  const hint = Log.isOn ? `${Dump.obj(this.objectHandle, this.memberName)}${args && args.length > 0 && (typeof args[0] === 'number' || typeof args[0] === 'string') ? ` - ${args[0]}` : ''}` : `${Dump.obj(this.objectHandle, this.memberName)}`;
173
173
  let oc = existing;
174
- const opts = { hint, standalone, journal: options.journal, logging: options.logging, token };
174
+ const opts = { hint, separation, journal: options.journal, logging: options.logging, token };
175
175
  const result = Transaction.run(opts, (argsx) => {
176
176
  if (!oc.operation.transaction.isCanceled) {
177
177
  oc = this.edit();
@@ -226,7 +226,7 @@ class Operation extends Subscription {
226
226
  get originSnapshotId() { return this.changeset.id; }
227
227
  hint() { return `${Dump.snapshot2(this.controller.objectHandle, this.changeset, this.controller.memberName)}`; }
228
228
  get order() { return this.options.order; }
229
- get ['#this']() {
229
+ get ['#this#']() {
230
230
  return `Operation: ${this.why()}`;
231
231
  }
232
232
  why() {
@@ -254,7 +254,7 @@ class Operation extends Subscription {
254
254
  const ms = Date.now() - started;
255
255
  if (Log.isOn && Log.opt.step && this.result)
256
256
  Log.writeAs({ margin2: this.margin }, '║', '_/', `${this.hint()} - step out `, 0, this.started > 0 ? ' │' : '');
257
- if (ms > Hooks.mainThreadBlockingWarningThreshold)
257
+ if (ms > Mvcc.mainThreadBlockingWarningThreshold)
258
258
  Log.write('', '[!]', this.why(), ms, ' *** main thread is too busy ***');
259
259
  return result;
260
260
  };
@@ -410,7 +410,7 @@ class Operation extends Subscription {
410
410
  this.started = -this.started;
411
411
  if (Log.isOn && Log.opt.operation)
412
412
  Log.write('║', `${op}`, `${this.hint()} ${message}`, ms, highlight);
413
- if (ms > (main ? Hooks.mainThreadBlockingWarningThreshold : Hooks.asyncActionDurationWarningThreshold))
413
+ if (ms > (main ? Mvcc.mainThreadBlockingWarningThreshold : Mvcc.asyncActionDurationWarningThreshold))
414
414
  Log.write('', '[!]', this.why(), ms, main ? ' *** main thread is too busy ***' : ' *** async is too long ***');
415
415
  this.cause = undefined;
416
416
  if (this.options.monitor)
@@ -419,17 +419,17 @@ class Operation extends Subscription {
419
419
  monitorEnter(mon) {
420
420
  const options = {
421
421
  hint: 'Monitor.enter',
422
- standalone: 'isolated',
422
+ separation: 'isolated',
423
423
  logging: Log.isOn && Log.opt.monitor ? undefined : Log.global
424
424
  };
425
425
  OperationController.runWithin(undefined, Transaction.run, options, MonitorImpl.enter, mon, this.transaction);
426
426
  }
427
427
  monitorLeave(mon) {
428
- Transaction.off(() => {
428
+ Transaction.outside(() => {
429
429
  const leave = () => {
430
430
  const options = {
431
431
  hint: 'Monitor.leave',
432
- standalone: 'isolated',
432
+ separation: 'isolated',
433
433
  logging: Log.isOn && Log.opt.monitor ? undefined : Log.DefaultLevel
434
434
  };
435
435
  OperationController.runWithin(undefined, Transaction.run, options, MonitorImpl.leave, mon, this.transaction);
@@ -520,9 +520,9 @@ class Operation extends Subscription {
520
520
  }
521
521
  if (curr instanceof Operation) {
522
522
  if (curr.changeset === os.changeset && curr.subscriptions !== undefined) {
523
- if (Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
523
+ if (Mvcc.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
524
524
  curr.subscriptions.forEach((info, v) => {
525
- if (info.usageCount > Hooks.repetitiveUsageWarningThreshold)
525
+ if (info.usageCount > Mvcc.repetitiveUsageWarningThreshold)
526
526
  Log.write('', '[!]', `${curr.hint()} uses ${info.memberHint} ${info.usageCount} times (consider remembering it in a local variable)`, 0, ' *** WARNING ***');
527
527
  });
528
528
  }
@@ -566,7 +566,7 @@ class Operation extends Subscription {
566
566
  const ok = Operation.canSubscribe(subscription, os, m, h, timestamp);
567
567
  if (ok) {
568
568
  let times = 0;
569
- if (Hooks.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
569
+ if (Mvcc.repetitiveUsageWarningThreshold < Number.MAX_SAFE_INTEGER) {
570
570
  const existing = this.subscriptions.get(subscription);
571
571
  times = existing ? existing.usageCount + 1 : 1;
572
572
  }
@@ -628,8 +628,8 @@ class Operation extends Subscription {
628
628
  Changeset.propagateAllChangesThroughSubscriptions = Operation.propagateAllChangesThroughSubscriptions;
629
629
  Changeset.revokeAllSubscriptions = Operation.revokeAllSubscriptions;
630
630
  Changeset.enqueueReactionsToRun = Operation.enqueueReactionsToRun;
631
- Hooks.createOperation = Operation.createOperation;
632
- Hooks.rememberOperationOptions = Operation.rememberOperationOptions;
631
+ Mvcc.createOperation = Operation.createOperation;
632
+ Mvcc.rememberOperationOptions = Operation.rememberOperationOptions;
633
633
  Promise.prototype.then = reactronicHookedThen;
634
634
  try {
635
635
  Object.defineProperty(globalThis, 'rWhy', {
@@ -22,8 +22,8 @@ export declare abstract class Transaction implements Worker {
22
22
  whenFinished(): Promise<void>;
23
23
  static create(options: SnapshotOptions | null): Transaction;
24
24
  static run<T>(options: SnapshotOptions | null, func: F<T>, ...args: any[]): T;
25
- static standalone<T>(func: F<T>, ...args: any[]): T;
26
- static off<T>(func: F<T>, ...args: any[]): T;
25
+ static separate<T>(func: F<T>, ...args: any[]): T;
26
+ static outside<T>(func: F<T>, ...args: any[]): T;
27
27
  static isFrameOver(everyN?: number, timeLimit?: number): boolean;
28
28
  static requestNextFrame(sleepTime?: number): Promise<void>;
29
29
  static get isCanceled(): boolean;
@@ -17,8 +17,8 @@ export class Transaction {
17
17
  }
18
18
  static create(options) { return new TransactionImpl(options); }
19
19
  static run(options, func, ...args) { return TransactionImpl.run(options, func, ...args); }
20
- static standalone(func, ...args) { return TransactionImpl.standalone(func, ...args); }
21
- static off(func, ...args) { return TransactionImpl.off(func, ...args); }
20
+ static separate(func, ...args) { return TransactionImpl.separate(func, ...args); }
21
+ static outside(func, ...args) { return TransactionImpl.outside(func, ...args); }
22
22
  static isFrameOver(everyN = 1, timeLimit = 10) { return TransactionImpl.isFrameOver(everyN, timeLimit); }
23
23
  static requestNextFrame(sleepTime = 0) { return TransactionImpl.requestNextFrame(sleepTime); }
24
24
  static get isCanceled() { return TransactionImpl.current.isCanceled; }
@@ -118,7 +118,7 @@ class TransactionImpl extends Transaction {
118
118
  let result = t.runImpl(options === null || options === void 0 ? void 0 : options.logging, func, ...args);
119
119
  if (root) {
120
120
  if (result instanceof Promise) {
121
- result = TransactionImpl.off(() => {
121
+ result = TransactionImpl.outside(() => {
122
122
  return t.wrapToRetry(t.wrapToWaitUntilFinish(result), func, ...args);
123
123
  });
124
124
  }
@@ -126,10 +126,10 @@ class TransactionImpl extends Transaction {
126
126
  }
127
127
  return result;
128
128
  }
129
- static standalone(func, ...args) {
130
- return TransactionImpl.run({ standalone: true }, func, ...args);
129
+ static separate(func, ...args) {
130
+ return TransactionImpl.run({ separation: true }, func, ...args);
131
131
  }
132
- static off(func, ...args) {
132
+ static outside(func, ...args) {
133
133
  const outer = TransactionImpl.curr;
134
134
  try {
135
135
  TransactionImpl.curr = TransactionImpl.none;
@@ -153,7 +153,7 @@ class TransactionImpl extends Transaction {
153
153
  }
154
154
  static acquire(options) {
155
155
  const curr = TransactionImpl.curr;
156
- if ((options === null || options === void 0 ? void 0 : options.standalone) || curr.isFinished || curr.options.standalone === 'isolated')
156
+ if ((options === null || options === void 0 ? void 0 : options.separation) || curr.isFinished || curr.options.separation === 'isolated')
157
157
  return new TransactionImpl(options);
158
158
  else
159
159
  return TransactionImpl.curr;
@@ -176,7 +176,7 @@ class TransactionImpl extends Transaction {
176
176
  yield this.after.whenFinished();
177
177
  const options = {
178
178
  hint: `${this.hint} - restart after T${this.after.id}`,
179
- standalone: this.options.standalone === 'isolated' ? 'isolated' : true,
179
+ separation: this.options.separation === 'isolated' ? 'isolated' : true,
180
180
  logging: this.changeset.options.logging,
181
181
  token: this.changeset.options.token,
182
182
  };
@@ -226,7 +226,7 @@ class TransactionImpl extends Transaction {
226
226
  if (this.sealed && this.pending === 0) {
227
227
  const reactions = this.applyOrDiscard();
228
228
  TransactionImpl.curr = outer;
229
- TransactionImpl.off(Changeset.enqueueReactionsToRun, reactions);
229
+ TransactionImpl.outside(Changeset.enqueueReactionsToRun, reactions);
230
230
  }
231
231
  else
232
232
  TransactionImpl.curr = outer;
@@ -0,0 +1,63 @@
1
+ export declare type GetItemKey<T = unknown> = (item: T) => string | undefined;
2
+ export interface CollectionReader<T> {
3
+ readonly strict: boolean;
4
+ readonly count: number;
5
+ readonly addedCount: number;
6
+ readonly removedCount: number;
7
+ readonly isMergeInProgress: boolean;
8
+ lookup(key: string): Item<T> | undefined;
9
+ claim(key: string): Item<T> | undefined;
10
+ add(self: T): Item<T>;
11
+ remove(item: Item<T>): void;
12
+ move(item: Item<T>, after: Item<T>): void;
13
+ beginMerge(): void;
14
+ endMerge(error?: unknown): void;
15
+ resetAddedAndRemovedLists(): void;
16
+ items(): Generator<Item<T>>;
17
+ addedItems(reset?: boolean): Generator<Item<T>>;
18
+ removedItems(reset?: boolean): Generator<Item<T>>;
19
+ isAdded(item: Item<T>): boolean;
20
+ isMoved(item: Item<T>): boolean;
21
+ isRemoved(item: Item<T>): boolean;
22
+ isCurrent(item: Item<T>): boolean;
23
+ }
24
+ export interface Item<T> {
25
+ readonly self: T;
26
+ readonly prev?: Item<T>;
27
+ aux?: Item<T>;
28
+ }
29
+ export declare class Collection<T> implements CollectionReader<T> {
30
+ readonly strict: boolean;
31
+ readonly getKey: GetItemKey<T>;
32
+ private map;
33
+ private tag;
34
+ private current;
35
+ private added;
36
+ private removed;
37
+ private lastNotFoundKey;
38
+ private strictNextItem?;
39
+ constructor(strict: boolean, getKey: GetItemKey<T>);
40
+ get count(): number;
41
+ get addedCount(): number;
42
+ get removedCount(): number;
43
+ get isMergeInProgress(): boolean;
44
+ lookup(key: string | undefined): Item<T> | undefined;
45
+ claim(key: string, resolution?: {
46
+ isDuplicate: boolean;
47
+ }): Item<T> | undefined;
48
+ add(self: T): Item<T>;
49
+ remove(item: Item<T>): void;
50
+ move(item: Item<T>, after: Item<T>): void;
51
+ beginMerge(): void;
52
+ endMerge(error?: unknown): void;
53
+ resetAddedAndRemovedLists(): void;
54
+ items(): Generator<Item<T>>;
55
+ addedItems(reset?: boolean): Generator<Item<T>>;
56
+ removedItems(reset?: boolean): Generator<Item<T>>;
57
+ isAdded(item: Item<T>): boolean;
58
+ isMoved(item: Item<T>): boolean;
59
+ isRemoved(item: Item<T>): boolean;
60
+ isCurrent(item: Item<T>): boolean;
61
+ markAsMoved(item: Item<T>): void;
62
+ static createItem<T>(self: T): Item<T>;
63
+ }
@@ -0,0 +1,283 @@
1
+ export class Collection {
2
+ constructor(strict, getKey) {
3
+ this.strict = strict;
4
+ this.getKey = getKey;
5
+ this.map = new Map();
6
+ this.tag = ~0;
7
+ this.current = new ItemChain();
8
+ this.added = new ItemChain();
9
+ this.removed = new ItemChain();
10
+ this.lastNotFoundKey = undefined;
11
+ this.strictNextItem = undefined;
12
+ }
13
+ get count() {
14
+ return this.current.count;
15
+ }
16
+ get addedCount() {
17
+ return this.added.count;
18
+ }
19
+ get removedCount() {
20
+ return this.removed.count;
21
+ }
22
+ get isMergeInProgress() {
23
+ return this.tag > 0;
24
+ }
25
+ lookup(key) {
26
+ let result = undefined;
27
+ if (key !== undefined && key !== this.lastNotFoundKey) {
28
+ result = this.map.get(key);
29
+ if (result) {
30
+ if (this.getKey(result.self) !== key) {
31
+ this.lastNotFoundKey = key;
32
+ result = undefined;
33
+ }
34
+ }
35
+ else
36
+ this.lastNotFoundKey = key;
37
+ }
38
+ return result;
39
+ }
40
+ claim(key, resolution) {
41
+ const tag = this.tag;
42
+ if (tag < 0)
43
+ throw new Error('merge is not in progress');
44
+ let item = this.strictNextItem;
45
+ if (key !== (item ? this.getKey(item.self) : undefined))
46
+ item = this.lookup(key);
47
+ if (item) {
48
+ if (item.tag !== tag) {
49
+ item.tag = tag;
50
+ if (this.strict && item !== this.strictNextItem)
51
+ item.status = tag;
52
+ this.strictNextItem = item.next;
53
+ this.removed.exclude(item);
54
+ this.current.include(item);
55
+ if (resolution)
56
+ resolution.isDuplicate = false;
57
+ }
58
+ else if (resolution)
59
+ resolution.isDuplicate = true;
60
+ else
61
+ throw new Error(`duplicate item: ${key}`);
62
+ }
63
+ else if (resolution)
64
+ resolution.isDuplicate = false;
65
+ return item;
66
+ }
67
+ add(self) {
68
+ const key = this.getKey(self);
69
+ if (this.lookup(key) !== undefined)
70
+ throw new Error(`key is already in use: ${key}`);
71
+ let tag = this.tag;
72
+ if (tag < 0) {
73
+ tag = ~this.tag + 1;
74
+ this.tag = ~tag;
75
+ }
76
+ const item = new ItemImpl(self, tag);
77
+ this.map.set(key, item);
78
+ this.lastNotFoundKey = undefined;
79
+ this.strictNextItem = undefined;
80
+ this.current.include(item);
81
+ this.added.aux(item);
82
+ return item;
83
+ }
84
+ remove(item) {
85
+ const t = item;
86
+ if (!this.isRemoved(t)) {
87
+ this.current.exclude(t);
88
+ this.removed.include(t);
89
+ t.tag--;
90
+ }
91
+ }
92
+ move(item, after) {
93
+ throw new Error('not implemented');
94
+ }
95
+ beginMerge() {
96
+ if (this.isMergeInProgress)
97
+ throw new Error('merge is in progress already');
98
+ this.tag = ~this.tag + 1;
99
+ this.strictNextItem = this.current.first;
100
+ this.removed.grab(this.current, false);
101
+ this.added.reset();
102
+ }
103
+ endMerge(error) {
104
+ if (!this.isMergeInProgress)
105
+ throw new Error('merge is ended already');
106
+ this.tag = ~this.tag;
107
+ if (error === undefined) {
108
+ const currentCount = this.current.count;
109
+ if (currentCount > 0) {
110
+ const getKey = this.getKey;
111
+ if (currentCount > this.removed.count) {
112
+ const map = this.map;
113
+ for (const x of this.removed.items())
114
+ map.delete(getKey(x.self));
115
+ }
116
+ else {
117
+ const map = this.map = new Map();
118
+ for (const x of this.current.items())
119
+ map.set(getKey(x.self), x);
120
+ }
121
+ }
122
+ else
123
+ this.map = new Map();
124
+ }
125
+ else {
126
+ this.current.grab(this.removed, true);
127
+ const getKey = this.getKey;
128
+ for (const x of this.added.itemsViaAux()) {
129
+ this.map.delete(getKey(x.self));
130
+ this.current.exclude(x);
131
+ }
132
+ this.added.reset();
133
+ }
134
+ }
135
+ resetAddedAndRemovedLists() {
136
+ this.removed.reset();
137
+ this.added.reset();
138
+ }
139
+ *items() {
140
+ let x = this.current.first;
141
+ while (x !== undefined) {
142
+ const next = x.next;
143
+ yield x;
144
+ x = next;
145
+ }
146
+ }
147
+ *addedItems(reset) {
148
+ let x = this.added.first;
149
+ while (x !== undefined) {
150
+ const next = x.aux;
151
+ if (!this.isRemoved(x))
152
+ yield x;
153
+ x = next;
154
+ }
155
+ if (reset)
156
+ this.added.reset();
157
+ }
158
+ *removedItems(reset) {
159
+ let x = this.removed.first;
160
+ while (x !== undefined) {
161
+ const next = x.next;
162
+ yield x;
163
+ x = next;
164
+ }
165
+ if (reset)
166
+ this.removed.reset();
167
+ }
168
+ isAdded(item) {
169
+ const t = item;
170
+ let tag = this.tag;
171
+ if (tag < 0)
172
+ tag = ~tag;
173
+ return t.status === ~tag && t.tag > 0;
174
+ }
175
+ isMoved(item) {
176
+ const t = item;
177
+ let tag = this.tag;
178
+ if (tag < 0)
179
+ tag = ~tag;
180
+ return t.status === tag && t.tag > 0;
181
+ }
182
+ isRemoved(item) {
183
+ const t = item;
184
+ const tag = this.tag;
185
+ return tag > 0 ? t.tag < tag : t.tag < tag - 1;
186
+ }
187
+ isCurrent(item) {
188
+ const t = item;
189
+ return t.tag === this.tag;
190
+ }
191
+ markAsMoved(item) {
192
+ const t = item;
193
+ if (t.tag > 0)
194
+ t.status = t.tag;
195
+ }
196
+ static createItem(self) {
197
+ return new ItemImpl(self, 0);
198
+ }
199
+ }
200
+ class ItemImpl {
201
+ constructor(self, tag) {
202
+ this.self = self;
203
+ this.tag = tag;
204
+ this.status = ~tag;
205
+ this.next = undefined;
206
+ this.prev = undefined;
207
+ this.aux = undefined;
208
+ }
209
+ }
210
+ class ItemChain {
211
+ constructor() {
212
+ this.count = 0;
213
+ this.first = undefined;
214
+ this.last = undefined;
215
+ }
216
+ *items() {
217
+ let x = this.first;
218
+ while (x !== undefined) {
219
+ const next = x.next;
220
+ yield x;
221
+ x = next;
222
+ }
223
+ }
224
+ *itemsViaAux() {
225
+ let x = this.first;
226
+ while (x !== undefined) {
227
+ const next = x.aux;
228
+ yield x;
229
+ x = next;
230
+ }
231
+ }
232
+ reset() {
233
+ this.count = 0;
234
+ this.first = undefined;
235
+ this.last = undefined;
236
+ }
237
+ grab(from, join) {
238
+ const head = from.first;
239
+ if (join && head) {
240
+ const last = this.last;
241
+ head.prev = last;
242
+ if (last)
243
+ this.last = last.next = head;
244
+ else
245
+ this.first = this.last = head;
246
+ this.count += from.count;
247
+ }
248
+ else {
249
+ this.count = from.count;
250
+ this.first = head;
251
+ this.last = from.last;
252
+ }
253
+ from.reset();
254
+ }
255
+ include(item) {
256
+ const last = this.last;
257
+ item.prev = last;
258
+ item.next = undefined;
259
+ if (last)
260
+ this.last = last.next = item;
261
+ else
262
+ this.first = this.last = item;
263
+ this.count++;
264
+ }
265
+ exclude(item) {
266
+ if (item.prev !== undefined)
267
+ item.prev.next = item.next;
268
+ if (item.next !== undefined)
269
+ item.next.prev = item.prev;
270
+ if (item === this.first)
271
+ this.first = item.next;
272
+ this.count--;
273
+ }
274
+ aux(item) {
275
+ item.aux = undefined;
276
+ const last = this.last;
277
+ if (last)
278
+ this.last = last.aux = item;
279
+ else
280
+ this.first = this.last = item;
281
+ this.count++;
282
+ }
283
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reactronic",
3
- "version": "0.22.313",
3
+ "version": "0.22.316",
4
4
  "description": "Reactronic - Transactional Reactive State Management",
5
5
  "type": "module",
6
6
  "main": "build/dist/source/api.js",
@@ -30,15 +30,15 @@
30
30
  },
31
31
  "homepage": "https://github.com/nezaboodka/reactronic/blob/master/README.md#readme",
32
32
  "devDependencies": {
33
- "@types/node": "18.0.0",
34
- "@types/react": "18.0.14",
35
- "@typescript-eslint/eslint-plugin": "5.29.0",
36
- "@typescript-eslint/parser": "5.29.0",
37
- "ava": "4.3.0",
33
+ "@types/node": "18.0.5",
34
+ "@types/react": "18.0.15",
35
+ "@typescript-eslint/eslint-plugin": "5.30.6",
36
+ "@typescript-eslint/parser": "5.30.6",
37
+ "ava": "4.3.1",
38
38
  "c8": "7.11.3",
39
- "eslint": "8.18.0",
39
+ "eslint": "8.19.0",
40
40
  "react": "18.2.0",
41
- "ts-node": "10.8.1",
41
+ "ts-node": "10.9.1",
42
42
  "typescript": "4.7.3"
43
43
  },
44
44
  "scripts": {