opshot 0.4.0 → 0.5.1

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/dist/index.d.ts CHANGED
@@ -1,57 +1,21 @@
1
1
  import { ComponentType, FC } from 'react';
2
2
 
3
- declare const ignoreMarker: unique symbol;
4
3
  /**
5
- * A factory-argument marker wrapping `T`.
4
+ * Sets when a state's window flushes. Call `flush` once.
6
5
  *
7
- * @typeParam T - Value type.
8
- */
9
- interface Ignored<T> {
10
- readonly [ignoreMarker]: T;
11
- }
12
- /**
13
- * Marks a factory-argument value so the edge at that path is untracked in that state.
14
- *
15
- * @typeParam T - Value type.
16
- * @param value - Value to ignore.
17
- * @returns A marker consumed at create.
18
- */
19
- declare function ignore<T>(value: T): Ignored<T>;
20
-
21
- declare const unsafeMarker: unique symbol;
22
- /**
23
- * A factory-argument marker wrapping `T`.
24
- *
25
- * @typeParam T - Value type.
26
- */
27
- interface UnsafeTracked<T> {
28
- readonly [unsafeMarker]: T;
29
- }
30
- /**
31
- * Marks a factory-argument value so strict is disabled at and under that path.
32
- *
33
- * @typeParam T - Value type.
34
- * @param value - Value to track without strict.
35
- * @returns A marker consumed at create.
36
- */
37
- declare function unsafeTrack<T>(value: T): UnsafeTracked<T>;
38
-
39
- /**
40
- * Schedules when bare writes notify listeners. Call `flush` once.
41
- *
42
- * @param flush - Delivers pending ops.
6
+ * @param flush - Delivers pending operations.
43
7
  * @returns Nothing.
44
8
  */
45
9
  type EmissionScheduler = (flush: () => void) => void;
46
10
  /**
47
- * State creation options.
11
+ * Options for `createMutableState`.
48
12
  *
49
13
  * @example
50
- * createMutableState({ x: 0 }, { emitOn: (flush) => requestAnimationFrame(flush), strict: false })
14
+ * createMutableState({ count: 0 }, { emitOn, strict: false })
51
15
  */
52
- interface MutableNodeOptions {
16
+ interface MutableStateOptions {
53
17
  /**
54
- * When bare writes notify listeners. Defaults to a microtask.
18
+ * When the window flushes for all writes. Defaults to a microtask.
55
19
  */
56
20
  readonly emitOn?: EmissionScheduler;
57
21
  /**
@@ -59,366 +23,90 @@ interface MutableNodeOptions {
59
23
  */
60
24
  readonly strict?: boolean;
61
25
  }
62
-
63
- /**
64
- * Options for `createMutableState`.
65
- *
66
- * @example
67
- * createMutableState({ count: 0 }, { group, emitOn, strict: false })
68
- */
69
- interface MutableStateOptions extends MutableNodeOptions {
70
- /**
71
- * Group that receives this state's changes.
72
- */
73
- readonly group?: Group;
74
- }
75
- /**
76
- * The live state shape after factory-argument markers are collapsed.
77
- *
78
- * @typeParam T - Factory argument type.
79
- */
80
- type Unmarked<T> = T extends Ignored<infer Inner> ? Unmarked<Inner> : T extends UnsafeTracked<infer Inner> ? Unmarked<Inner> : T extends (...args: never) => unknown ? T : T extends ReadonlyArray<infer Element> ? Array<Unmarked<Element>> : T extends object ? {
81
- [Key in keyof T]: Unmarked<T[Key]>;
82
- } : T;
83
26
  /**
84
27
  * Creates a mutable state object.
85
28
  *
86
- * `ignore()` on a value in the factory argument makes the edge at that path untracked in that state.
87
- * `unsafeTrack()` on a value in the factory argument disables strict at and under that path.
29
+ * `ignore()` marks an object so every edge to it is untracked. `unsafeTrack()` marks an object so a node entering while marked, or entering beneath an exempt node, is exempt from strict.
88
30
  *
89
31
  * @typeParam T - State shape.
90
32
  * @param properties - Initial fields.
91
33
  * @param options - Creation options.
92
- * @returns The state, with factory-argument markers collapsed.
93
- */
94
- declare function createMutableState<T extends object>(properties: T, options?: MutableStateOptions): Unmarked<T>;
95
-
96
- /**
97
- * Path segments to a value in state.
98
- *
99
- * @example
100
- * ["document", "items", 0, "title"]
34
+ * @returns The state.
101
35
  */
102
- type OperationPath = ReadonlyArray<string | number>;
103
-
104
- interface DeclarationTrie {
105
- readonly ignored: boolean;
106
- readonly unsafe: boolean;
107
- readonly children: ReadonlyMap<string, DeclarationTrie>;
108
- }
109
-
110
- interface InEdge {
111
- readonly parent: object;
112
- readonly key: string | number;
113
- }
114
- interface NodeRecord {
115
- edges: Array<InEdge>;
116
- id: number | undefined;
117
- }
118
-
119
- interface CaptureTables {
120
- mints: Array<{
121
- readonly node: object;
122
- readonly id: number;
123
- }>;
124
- binds: Array<{
125
- readonly node: object;
126
- readonly id: number;
127
- }>;
128
- bindIdByNode: Map<object, number>;
129
- bindNodeById: Map<number, object>;
130
- mintIdByNode: Map<object, number>;
131
- mintNodeById: Map<number, object>;
132
- nextStagedId: number;
133
- }
134
-
135
- interface DirtyIndex {
136
- readonly edges: WeakMap<object, Set<string | symbol>>;
137
- readonly nodes: WeakSet<object>;
138
- }
139
- interface Handle {
140
- proxy: {
141
- readonly root: object;
142
- };
143
- lastSnapshot: object;
144
- hasPendingWrites: boolean;
145
- isFlushScheduled: boolean;
146
- isFlushHeld: boolean;
147
- flushGeneration: number;
148
- subscribers: StateListeners;
149
- groups?: ReadonlyArray<GroupListeners>;
150
- disarmWatch?: () => void;
151
- emitOn?: EmissionScheduler;
152
- strict: boolean;
153
- declarations: DeclarationTrie | undefined;
154
- nodes: WeakMap<object, NodeRecord>;
155
- byId: Map<number, object>;
156
- nextInternId: number;
157
- lastDirty?: DirtyIndex;
158
- stamp: object;
159
- version: number;
160
- replaying: boolean;
161
- transactionCapture?: CaptureTables;
162
- }
36
+ declare function createMutableState<T extends object>(properties: T, options?: MutableStateOptions): T;
163
37
 
164
38
  /**
165
- * Assigns a value at a path.
166
- *
167
- * @example
168
- * { verb: "assign", path: ["count"], value: 1 }
169
- */
170
- interface AssignMutation {
171
- /**
172
- * `"assign"`.
173
- */
174
- readonly verb: "assign";
175
- /**
176
- * Path to assign.
177
- */
178
- readonly path: OperationPath;
179
- /**
180
- * Value to assign.
181
- */
182
- readonly value: unknown;
183
- /**
184
- * Walk-ordered intern ids that override deterministic vending when this half re-admits departed material.
185
- */
186
- readonly ids?: ReadonlyArray<number>;
187
- }
188
- /**
189
- * Deletes the value at a path.
190
- *
191
- * @example
192
- * { verb: "delete", path: ["temp"] }
193
- */
194
- interface DeleteMutation {
195
- /**
196
- * `"delete"`.
197
- */
198
- readonly verb: "delete";
199
- /**
200
- * Path to delete.
201
- */
202
- readonly path: OperationPath;
203
- }
204
- /**
205
- * Links the interned node `ref` into `path`.
206
- *
207
- * @example
208
- * { verb: "link", path: ["alias"], ref: 0 }
209
- */
210
- interface LinkMutation {
211
- /**
212
- * `"link"`.
213
- */
214
- readonly verb: "link";
215
- /**
216
- * Path to place the linked node.
217
- */
218
- readonly path: OperationPath;
219
- /**
220
- * Intern id of the node to link.
221
- */
222
- readonly ref: number;
223
- }
224
- /**
225
- * An assign, a delete, or a link.
39
+ * Returns a stable identity key for a value.
226
40
  *
227
- * @example
228
- * { verb: "assign", path: ["profile"], value: { name: "Ada" } }
41
+ * @param value - Value to identify.
42
+ * @returns Identity key.
229
43
  */
230
- type Mutation = AssignMutation | DeleteMutation | LinkMutation;
44
+ declare function identify(value: object): object;
231
45
  /**
232
- * A change with do and undo halves.
46
+ * Returns whether two values share the same identity.
233
47
  *
234
- * @example
235
- * { do: { verb: "assign", path: ["count"], value: 1 }, undo: { verb: "assign", path: ["count"], value: 0 } }
48
+ * @param first - First value.
49
+ * @param second - Second value.
50
+ * @returns True if they match.
236
51
  */
237
- interface Operation {
238
- /**
239
- * Forward operation.
240
- */
241
- readonly do: Mutation;
242
- /**
243
- * Reverse operation.
244
- */
245
- readonly undo: Mutation;
246
- }
52
+ declare function isSameIdentity(first: object, second: object): boolean;
247
53
 
248
54
  /**
249
- * Listener for one state's changes.
250
- *
251
- * @param ops - Ops for the change.
252
- * @param meta - Writer meta, if any.
253
- * @returns Nothing.
254
- */
255
- type StateListener = (ops: ReadonlyArray<Operation>, meta: unknown) => void;
256
- /**
257
- * Listener for a group's changes.
55
+ * Returns whether a value is an opshot state.
258
56
  *
259
- * @param state - State that changed.
260
- * @param ops - Ops for the change.
261
- * @param meta - Writer meta, if any.
262
- * @returns Nothing.
57
+ * @param value - Value to test.
58
+ * @returns True if it is a state.
263
59
  */
264
- type GroupListener = (state: object, ops: ReadonlyArray<Operation>, meta: unknown) => void;
265
- type StateDeliver = (ops: ReadonlyArray<Operation>, meta: unknown, channelId: object | undefined) => void;
266
- type GroupDeliver = (state: object, ops: ReadonlyArray<Operation>, meta: unknown, channelId: object | undefined) => void;
267
- type StateListeners = Map<Function, Map<object | undefined, StateDeliver>>;
268
- type GroupListeners = Map<Function, Map<object | undefined, GroupDeliver>>;
60
+ declare function isState(value: unknown): value is object;
269
61
 
270
62
  /**
271
- * Creates states and receives their changes on one stream.
63
+ * A change to one key of a node.
272
64
  *
273
65
  * @example
274
- * const group = createGroup()
275
- * const doc = group.createMutableState({ title: "" })
276
- * subscribe(group, (state, ops, meta) => {})
66
+ * { node, key: "count", before: 0, after: 1, meta: undefined }
277
67
  */
278
- interface Group {
68
+ interface Operation {
279
69
  /**
280
- * Creates a state in this group.
281
- *
282
- * @typeParam T - State shape.
283
- * @param properties - Initial fields.
284
- * @param options - Creation options.
285
- * @returns The state.
70
+ * Node that changed.
286
71
  */
287
- createMutableState<T extends object>(properties: T, options?: MutableNodeOptions): Unmarked<T>;
288
- }
289
- /**
290
- * Creates a group.
291
- *
292
- * @param parent - Optional parent group whose listeners hear this group's states.
293
- * @returns A new group.
294
- */
295
- declare function createGroup(parent?: Group): Group;
296
-
297
- /**
298
- * Listener context from a channel subscription.
299
- *
300
- * @typeParam M - Meta type for this channel.
301
- */
302
- type EmissionContext<M> = {
303
- readonly isTransaction: true;
304
- readonly meta: M;
305
- } | {
306
- readonly isTransaction: false;
307
- readonly meta: unknown;
308
- };
309
- /**
310
- * Listens for changes from a group's states.
311
- *
312
- * @param group - Group to listen to.
313
- * @param listener - Called on each change.
314
- * @returns Unsubscribe function.
315
- */
316
- declare function subscribe(group: Group, listener: GroupListener): () => void;
317
- /**
318
- * Listens for changes to a state.
319
- *
320
- * @param state - State to listen to.
321
- * @param listener - Called on each change.
322
- * @returns Unsubscribe function.
323
- */
324
- declare function subscribe(state: object, listener: StateListener): () => void;
325
-
326
- type ApplyDirection = "do" | "undo";
327
-
328
- /**
329
- * Channel-bound `transact`, `subscribe`, and `applyOperations`.
330
- *
331
- * @typeParam M - Meta type for this channel.
332
- */
333
- interface Channel<M extends object> {
72
+ readonly node: object;
334
73
  /**
335
- * Runs a transaction with this channel's meta.
336
- *
337
- * @param state - State to change.
338
- * @param mutate - Function that writes the state.
339
- * @param meta - Meta for this write.
340
- * @returns Nothing.
74
+ * Key that changed.
341
75
  */
342
- transact(state: object, mutate: () => void, meta?: Partial<M>): void;
76
+ readonly key: string;
343
77
  /**
344
- * Listens for changes from a group's states.
345
- *
346
- * @param group - Group to listen to.
347
- * @param listener - Called on each change.
348
- * @returns Unsubscribe function.
78
+ * Value before, absent when the key was absent.
349
79
  */
350
- subscribe(group: Group, listener: (state: object, ops: ReadonlyArray<Operation>, context: EmissionContext<M>) => void): () => void;
80
+ readonly before?: unknown;
351
81
  /**
352
- * Listens for changes to a state.
353
- *
354
- * @param state - State to listen to.
355
- * @param listener - Called on each change.
356
- * @returns Unsubscribe function.
82
+ * Value after, absent when the key is absent.
357
83
  */
358
- subscribe(state: object, listener: (ops: ReadonlyArray<Operation>, context: EmissionContext<M>) => void): () => void;
84
+ readonly after?: unknown;
359
85
  /**
360
- * Applies operations with this channel's meta.
361
- *
362
- * @param state - State to change.
363
- * @param operations - Operations to apply.
364
- * @param direction - `"do"` or `"undo"`.
365
- * @param meta - Meta for this write.
366
- * @returns Nothing.
86
+ * Meta of the batch the write was made in.
367
87
  */
368
- applyOperations(state: object, operations: ReadonlyArray<Operation>, direction: ApplyDirection, meta?: Partial<M>): void;
88
+ readonly meta: unknown;
369
89
  }
370
- /**
371
- * Creates a channel with a typed meta convention.
372
- *
373
- * @typeParam M - Meta type for this channel.
374
- * @param defaults - Default meta for this channel's writes.
375
- * @returns The channel.
376
- */
377
- declare function createChannel<M extends object>(defaults?: M): Channel<M>;
378
90
 
379
91
  /**
380
- * Returns a stable identity key for a value.
92
+ * Marks an object so every edge to it is untracked in every state.
381
93
  *
382
- * @param value - Value to identify.
383
- * @returns Identity key.
384
- */
385
- declare function identify(value: object): object;
386
- /**
387
- * Returns whether two values share the same identity.
388
- *
389
- * @param first - First value.
390
- * @param second - Second value.
391
- * @returns True if they match.
392
- */
393
- declare function isSameIdentity(first: object, second: object): boolean;
394
-
395
- /**
396
- * Returns whether a value is an opshot state.
397
- *
398
- * @param value - Value to test.
399
- * @returns True if it is a state.
400
- */
401
- declare function isState(value: unknown): value is object;
402
-
403
- /**
404
- * Applies operations to a state.
405
- *
406
- * @param state - State to change.
407
- * @param operations - Operations to apply.
408
- * @param direction - `"do"` or `"undo"`.
409
- * @param meta - Passed to listeners.
410
- * @returns Nothing.
94
+ * @typeParam T - Value type.
95
+ * @param value - Value to mark or unmark.
96
+ * @param on - Whether the mark is set.
97
+ * @returns `value`.
411
98
  */
412
- declare function applyOperations(state: object, operations: ReadonlyArray<Operation>, direction: ApplyDirection, meta?: unknown): void;
99
+ declare function ignore<T>(value: T, on?: boolean): T;
413
100
 
414
101
  /**
415
- * Diffs two plain objects into ops.
102
+ * Marks an object so a node entering a state while marked, or entering beneath an exempt node, is exempt from strict.
416
103
  *
417
- * @param before - Earlier value.
418
- * @param after - Later value.
419
- * @returns Ops from before to after.
104
+ * @typeParam T - Value type.
105
+ * @param value - Value to mark or unmark.
106
+ * @param on - Whether the mark is set.
107
+ * @returns `value`.
420
108
  */
421
- declare function diffObjects(before: object, after: object, handle?: Handle, dirty?: DirtyIndex, capture?: CaptureTables): Array<Operation>;
109
+ declare function unsafeTrack<T>(value: T, on?: boolean): T;
422
110
 
423
111
  type DateConstructorArgs = [] | [value: number | string] | [
424
112
  year: number,
@@ -539,14 +227,35 @@ declare class TrackedSet<T> {
539
227
  }
540
228
 
541
229
  /**
542
- * Runs changes in one batch and notifies listeners with optional `meta`.
230
+ * Listener for one state's changes.
543
231
  *
544
- * @param state - State to change.
545
- * @param mutate - Function that writes the state.
546
- * @param meta - Passed to listeners.
547
- * @returns Nothing.
232
+ * @param operations - Operations for the change.
233
+ */
234
+ type StateListener = (operations: ReadonlyArray<Operation>) => void;
235
+
236
+ /**
237
+ * Listens for changes to a state.
238
+ *
239
+ * @param state - State to listen to.
240
+ * @param listener - Called on each change.
241
+ * @returns Unsubscribe function.
548
242
  */
549
- declare function transact(state: object, mutate: () => void, meta?: unknown): void;
243
+ declare function subscribe(state: object, listener: StateListener): () => void;
244
+
245
+ /**
246
+ * Runs writes carrying `meta`.
247
+ *
248
+ * @param callback - Function that writes any states.
249
+ * @param meta - Carried by each write's operation.
250
+ */
251
+ declare function batch(callback: () => void, meta?: unknown): void;
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;
550
259
 
551
260
  /**
552
261
  * Wraps a component so it re-renders only when fields it read change.
@@ -557,14 +266,6 @@ declare function transact(state: object, mutate: () => void, meta?: unknown): vo
557
266
  */
558
267
  declare function scope<P extends object>(Component: ComponentType<P>): FC<P>;
559
268
 
560
- /**
561
- * Creates a group for a component.
562
- *
563
- * @param parent - Optional parent group whose listeners hear this group's states.
564
- * @returns The group.
565
- */
566
- declare function useGroup(parent?: Group): Group;
567
-
568
269
  /**
569
270
  * Creates mutable state for a component.
570
271
  *
@@ -573,6 +274,6 @@ declare function useGroup(parent?: Group): Group;
573
274
  * @param options - Creation options.
574
275
  * @returns The state.
575
276
  */
576
- declare function useMutableState<T extends object>(properties: (() => T) | T, options?: MutableStateOptions): Unmarked<T>;
277
+ declare function useMutableState<T extends object>(properties: (() => T) | T, options?: MutableStateOptions): T;
577
278
 
578
- export { type Channel, type EmissionContext, type EmissionScheduler, type Group, type GroupListener, type Ignored, type MutableNodeOptions, type MutableStateOptions, type Operation, type OperationPath, type StateListener, TrackedDate, TrackedMap, TrackedSet, type UnsafeTracked, applyOperations, createChannel, createGroup, createMutableState, diffObjects, identify, ignore, isSameIdentity, isState, scope, subscribe, transact, unsafeTrack, useGroup, 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 };