opshot 0.5.0 → 0.5.2
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/README.md +2 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +97 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -206,6 +206,8 @@ const Chart = () => {
|
|
|
206
206
|
};
|
|
207
207
|
```
|
|
208
208
|
|
|
209
|
+
Separate from that callback, the `flush(state)` export ends the window from outside.
|
|
210
|
+
|
|
209
211
|
## Batches
|
|
210
212
|
|
|
211
213
|
`batch` runs a callback and tags every write inside it with your `meta`, so a listener can tell its own writes from everyone else's.
|
package/dist/index.d.ts
CHANGED
|
@@ -250,6 +250,13 @@ declare function subscribe(state: object, listener: StateListener): () => void;
|
|
|
250
250
|
*/
|
|
251
251
|
declare function batch(callback: () => void, meta?: unknown): void;
|
|
252
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Ends the state's window now, delivering the operations gathered so far.
|
|
255
|
+
*
|
|
256
|
+
* @param state - State to flush.
|
|
257
|
+
*/
|
|
258
|
+
declare function flush(state: object): void;
|
|
259
|
+
|
|
253
260
|
/**
|
|
254
261
|
* Wraps a component so it re-renders only when fields it read change.
|
|
255
262
|
*
|
|
@@ -269,4 +276,4 @@ declare function scope<P extends object>(Component: ComponentType<P>): FC<P>;
|
|
|
269
276
|
*/
|
|
270
277
|
declare function useMutableState<T extends object>(properties: (() => T) | T, options?: MutableStateOptions): T;
|
|
271
278
|
|
|
272
|
-
export { type EmissionScheduler, type MutableStateOptions, type Operation, type StateListener, TrackedDate, TrackedMap, TrackedSet, batch, createMutableState, identify, ignore, isSameIdentity, isState, scope, subscribe, unsafeTrack, useMutableState };
|
|
279
|
+
export { type EmissionScheduler, type MutableStateOptions, type Operation, type StateListener, TrackedDate, TrackedMap, TrackedSet, batch, createMutableState, flush, identify, ignore, isSameIdentity, isState, scope, subscribe, unsafeTrack, useMutableState };
|
package/dist/index.js
CHANGED
|
@@ -257,9 +257,83 @@ function evict(handle, node) {
|
|
|
257
257
|
cascade(handle, rawNode, membership.keys);
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
+
// src/utils/predicates.ts
|
|
261
|
+
var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
262
|
+
|
|
263
|
+
// src/identity.ts
|
|
264
|
+
var readProxyTargets = /* @__PURE__ */ new WeakMap();
|
|
265
|
+
var identityRecords = /* @__PURE__ */ new WeakMap();
|
|
266
|
+
var nextInternId = 0;
|
|
267
|
+
var registerReadProxyTarget = (readProxy, target) => {
|
|
268
|
+
readProxyTargets.set(readProxy, target);
|
|
269
|
+
};
|
|
270
|
+
var getRegisteredReadProxyTarget = (readProxy) => readProxyTargets.get(readProxy);
|
|
271
|
+
function resolveIdentity(value) {
|
|
272
|
+
let current = value;
|
|
273
|
+
while (isObjectLike(current)) {
|
|
274
|
+
const readTarget = getRegisteredReadProxyTarget(current);
|
|
275
|
+
if (readTarget !== void 0 && readTarget !== current) {
|
|
276
|
+
current = readTarget;
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const raw = rawOf(current);
|
|
280
|
+
if (raw !== current) {
|
|
281
|
+
current = raw;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
return current;
|
|
287
|
+
}
|
|
288
|
+
var recordFor = (key) => {
|
|
289
|
+
let record = identityRecords.get(key);
|
|
290
|
+
if (record === void 0) {
|
|
291
|
+
record = {};
|
|
292
|
+
identityRecords.set(key, record);
|
|
293
|
+
}
|
|
294
|
+
return record;
|
|
295
|
+
};
|
|
296
|
+
function identify(value) {
|
|
297
|
+
const target = resolveIdentity(value);
|
|
298
|
+
if (!isObjectLike(target)) return value;
|
|
299
|
+
const record = recordFor(target);
|
|
300
|
+
if (record.token !== void 0) return record.token;
|
|
301
|
+
const token = Object.freeze({});
|
|
302
|
+
record.token = token;
|
|
303
|
+
return token;
|
|
304
|
+
}
|
|
305
|
+
var internIdentity = (key) => {
|
|
306
|
+
const resolved = resolveIdentity(key);
|
|
307
|
+
const record = recordFor(resolved);
|
|
308
|
+
if (record.id !== void 0) return record.id;
|
|
309
|
+
const id = nextInternId;
|
|
310
|
+
nextInternId += 1;
|
|
311
|
+
record.id = id;
|
|
312
|
+
return id;
|
|
313
|
+
};
|
|
314
|
+
function isSameIdentity(first, second) {
|
|
315
|
+
const resolvedFirst = resolveIdentity(first);
|
|
316
|
+
const resolvedSecond = resolveIdentity(second);
|
|
317
|
+
return resolvedFirst === resolvedSecond;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// src/peelReadProxy.ts
|
|
321
|
+
function peelReadProxy(value) {
|
|
322
|
+
if (!isObjectLike(value)) return value;
|
|
323
|
+
let current = value;
|
|
324
|
+
while (isObjectLike(current)) {
|
|
325
|
+
const registeredTarget = getRegisteredReadProxyTarget(current);
|
|
326
|
+
if (registeredTarget === void 0) break;
|
|
327
|
+
current = registeredTarget;
|
|
328
|
+
}
|
|
329
|
+
return current;
|
|
330
|
+
}
|
|
331
|
+
|
|
260
332
|
// src/handle.ts
|
|
261
333
|
function handleOf(state) {
|
|
262
|
-
const
|
|
334
|
+
const peeled = peelReadProxy(state);
|
|
335
|
+
if (!isObjectLike(peeled)) return void 0;
|
|
336
|
+
const raw = rawOf(peeled);
|
|
263
337
|
const record = recordOf(raw);
|
|
264
338
|
if (record === void 0) return void 0;
|
|
265
339
|
for (const handle of record.memberships.keys()) {
|
|
@@ -289,6 +363,7 @@ function batch(callback, meta) {
|
|
|
289
363
|
|
|
290
364
|
// src/emit/emitterDeliver.ts
|
|
291
365
|
var runDelivery = (pending, failures) => {
|
|
366
|
+
pending.handle.lastDirty = pending.dirty;
|
|
292
367
|
for (const deliver of pending.deliveries) {
|
|
293
368
|
try {
|
|
294
369
|
deliver(pending.operations);
|
|
@@ -305,9 +380,11 @@ var raiseFailures = (failures) => {
|
|
|
305
380
|
var queuedDeliveries = [];
|
|
306
381
|
var deliveryFailures = [];
|
|
307
382
|
var isDraining = false;
|
|
308
|
-
var prepareDelivery = (handle, operations) => ({
|
|
383
|
+
var prepareDelivery = (handle, operations, dirty) => ({
|
|
309
384
|
deliveries: [...handle.subscribers.values()],
|
|
310
|
-
operations
|
|
385
|
+
operations,
|
|
386
|
+
handle,
|
|
387
|
+
dirty
|
|
311
388
|
});
|
|
312
389
|
var enqueueDelivery = (pending) => {
|
|
313
390
|
queuedDeliveries.push(pending);
|
|
@@ -345,19 +422,21 @@ function recordOperation(handle, raw, pending) {
|
|
|
345
422
|
}
|
|
346
423
|
handle.pending.push(pending);
|
|
347
424
|
byKey.set(pending.key, handle.pending.length - 1);
|
|
348
|
-
if (handle.
|
|
349
|
-
handle.isFlushScheduled = true;
|
|
425
|
+
if (handle.scheduledFlush !== void 0) return;
|
|
350
426
|
const run = () => {
|
|
351
|
-
|
|
427
|
+
if (handle.scheduledFlush !== run) return;
|
|
428
|
+
flushWindow(handle);
|
|
352
429
|
};
|
|
430
|
+
handle.scheduledFlush = run;
|
|
353
431
|
void Promise.resolve().then(() => {
|
|
432
|
+
if (handle.scheduledFlush !== run) return;
|
|
354
433
|
const emitOn = handle.emitOn;
|
|
355
434
|
if (emitOn === void 0) run();
|
|
356
435
|
else emitOn(run);
|
|
357
436
|
});
|
|
358
437
|
}
|
|
359
|
-
function
|
|
360
|
-
handle.
|
|
438
|
+
function flushWindow(handle) {
|
|
439
|
+
handle.scheduledFlush = void 0;
|
|
361
440
|
const pending = handle.pending.splice(0);
|
|
362
441
|
handle.pendingIndex.clear();
|
|
363
442
|
const operations = new Array();
|
|
@@ -372,6 +451,7 @@ function flush(handle) {
|
|
|
372
451
|
};
|
|
373
452
|
operations.push(Object.freeze(operation));
|
|
374
453
|
}
|
|
454
|
+
if (operations.length === 0) return;
|
|
375
455
|
const edges = /* @__PURE__ */ new Map();
|
|
376
456
|
const nodes = /* @__PURE__ */ new Set();
|
|
377
457
|
for (const operation of operations) {
|
|
@@ -385,15 +465,10 @@ function flush(handle) {
|
|
|
385
465
|
nodes.add(raw);
|
|
386
466
|
}
|
|
387
467
|
const dirty = { edges, nodes };
|
|
388
|
-
handle
|
|
389
|
-
if (operations.length === 0) return;
|
|
390
|
-
enqueueDelivery(prepareDelivery(handle, operations));
|
|
468
|
+
enqueueDelivery(prepareDelivery(handle, operations, dirty));
|
|
391
469
|
drainDeliveries();
|
|
392
470
|
}
|
|
393
471
|
|
|
394
|
-
// src/utils/predicates.ts
|
|
395
|
-
var isObjectLike = (value) => value !== null && (typeof value === "object" || typeof value === "function");
|
|
396
|
-
|
|
397
472
|
// src/proxy.ts
|
|
398
473
|
var prototypeFunctionOf = (target, key) => {
|
|
399
474
|
for (let holder = Reflect.getPrototypeOf(target); holder !== null; holder = Reflect.getPrototypeOf(holder)) {
|
|
@@ -587,7 +662,7 @@ var handler = {
|
|
|
587
662
|
// src/createMutableState.ts
|
|
588
663
|
installProxyHandler(handler);
|
|
589
664
|
function createMutableState(properties, options) {
|
|
590
|
-
const incoming = properties;
|
|
665
|
+
const incoming = peelReadProxy(properties);
|
|
591
666
|
if (typeof incoming !== "object" || incoming === null) return properties;
|
|
592
667
|
if (isIgnored(incoming)) return properties;
|
|
593
668
|
if (Object.isFrozen(incoming)) return properties;
|
|
@@ -601,83 +676,13 @@ function createMutableState(properties, options) {
|
|
|
601
676
|
emitOn: options?.emitOn,
|
|
602
677
|
subscribers: /* @__PURE__ */ new Map(),
|
|
603
678
|
pending: [],
|
|
604
|
-
pendingIndex: /* @__PURE__ */ new Map()
|
|
605
|
-
isFlushScheduled: false
|
|
679
|
+
pendingIndex: /* @__PURE__ */ new Map()
|
|
606
680
|
};
|
|
607
681
|
const proxy = proxyOf(root);
|
|
608
682
|
attachRoot(handle, root, exempt);
|
|
609
683
|
return proxy;
|
|
610
684
|
}
|
|
611
685
|
|
|
612
|
-
// src/identity.ts
|
|
613
|
-
var readProxyTargets = /* @__PURE__ */ new WeakMap();
|
|
614
|
-
var identityRecords = /* @__PURE__ */ new WeakMap();
|
|
615
|
-
var nextInternId = 0;
|
|
616
|
-
var registerReadProxyTarget = (readProxy, target) => {
|
|
617
|
-
readProxyTargets.set(readProxy, target);
|
|
618
|
-
};
|
|
619
|
-
var getRegisteredReadProxyTarget = (readProxy) => readProxyTargets.get(readProxy);
|
|
620
|
-
function resolveIdentity(value) {
|
|
621
|
-
let current = value;
|
|
622
|
-
while (isObjectLike(current)) {
|
|
623
|
-
const readTarget = getRegisteredReadProxyTarget(current);
|
|
624
|
-
if (readTarget !== void 0 && readTarget !== current) {
|
|
625
|
-
current = readTarget;
|
|
626
|
-
continue;
|
|
627
|
-
}
|
|
628
|
-
const raw = rawOf(current);
|
|
629
|
-
if (raw !== current) {
|
|
630
|
-
current = raw;
|
|
631
|
-
continue;
|
|
632
|
-
}
|
|
633
|
-
break;
|
|
634
|
-
}
|
|
635
|
-
return current;
|
|
636
|
-
}
|
|
637
|
-
var recordFor = (key) => {
|
|
638
|
-
let record = identityRecords.get(key);
|
|
639
|
-
if (record === void 0) {
|
|
640
|
-
record = {};
|
|
641
|
-
identityRecords.set(key, record);
|
|
642
|
-
}
|
|
643
|
-
return record;
|
|
644
|
-
};
|
|
645
|
-
function identify(value) {
|
|
646
|
-
const target = resolveIdentity(value);
|
|
647
|
-
if (!isObjectLike(target)) return value;
|
|
648
|
-
const record = recordFor(target);
|
|
649
|
-
if (record.token !== void 0) return record.token;
|
|
650
|
-
const token = Object.freeze({});
|
|
651
|
-
record.token = token;
|
|
652
|
-
return token;
|
|
653
|
-
}
|
|
654
|
-
var internIdentity = (key) => {
|
|
655
|
-
const resolved = resolveIdentity(key);
|
|
656
|
-
const record = recordFor(resolved);
|
|
657
|
-
if (record.id !== void 0) return record.id;
|
|
658
|
-
const id = nextInternId;
|
|
659
|
-
nextInternId += 1;
|
|
660
|
-
record.id = id;
|
|
661
|
-
return id;
|
|
662
|
-
};
|
|
663
|
-
function isSameIdentity(first, second) {
|
|
664
|
-
const resolvedFirst = resolveIdentity(first);
|
|
665
|
-
const resolvedSecond = resolveIdentity(second);
|
|
666
|
-
return resolvedFirst === resolvedSecond;
|
|
667
|
-
}
|
|
668
|
-
|
|
669
|
-
// src/peelReadProxy.ts
|
|
670
|
-
function peelReadProxy(value) {
|
|
671
|
-
if (!isObjectLike(value)) return value;
|
|
672
|
-
let current = value;
|
|
673
|
-
while (isObjectLike(current)) {
|
|
674
|
-
const registeredTarget = getRegisteredReadProxyTarget(current);
|
|
675
|
-
if (registeredTarget === void 0) break;
|
|
676
|
-
current = registeredTarget;
|
|
677
|
-
}
|
|
678
|
-
return current;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
686
|
// src/isState.ts
|
|
682
687
|
function isState(value) {
|
|
683
688
|
const resolved = peelReadProxy(value);
|
|
@@ -1172,6 +1177,11 @@ function subscribe(state, listener) {
|
|
|
1172
1177
|
return addStateListener(state, listener, listener);
|
|
1173
1178
|
}
|
|
1174
1179
|
|
|
1180
|
+
// src/flush.ts
|
|
1181
|
+
function flush(state) {
|
|
1182
|
+
flushWindow(requireHandle(state, "opshot: flush requires a state"));
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1175
1185
|
// src/react/propWalk.ts
|
|
1176
1186
|
var stateKeysByContainer = /* @__PURE__ */ new WeakMap();
|
|
1177
1187
|
var noStateKeys = /* @__PURE__ */ new Set();
|
|
@@ -1678,4 +1688,4 @@ function useMutableState(properties, options) {
|
|
|
1678
1688
|
return readProxy;
|
|
1679
1689
|
}
|
|
1680
1690
|
|
|
1681
|
-
export { TrackedDate, TrackedMap, TrackedSet, batch, createMutableState, identify, ignore, isSameIdentity, isState, scope, subscribe, unsafeTrack, useMutableState };
|
|
1691
|
+
export { TrackedDate, TrackedMap, TrackedSet, batch, createMutableState, flush, identify, ignore, isSameIdentity, isState, scope, subscribe, unsafeTrack, useMutableState };
|
package/package.json
CHANGED