j-templates 9.0.1 → 10.0.0

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 (54) hide show
  1. package/SYNTAX_PRIMER.md +181 -101
  2. package/Store/Diff/channelClient.d.ts +106 -0
  3. package/Store/Diff/channelClient.js +228 -0
  4. package/Store/Diff/defaultDiffTreeWorker.js +3 -4
  5. package/Store/Diff/diffTree.d.ts +56 -0
  6. package/Store/Diff/diffTree.js +110 -4
  7. package/Store/Diff/diffTree.types.d.ts +191 -21
  8. package/Store/Diff/diffTree.types.js +2 -10
  9. package/Store/Diff/diffTreeEndpoint.d.ts +101 -0
  10. package/Store/Diff/diffTreeEndpoint.js +173 -0
  11. package/Store/Diff/diffTreeEndpoint.types.d.ts +71 -0
  12. package/Store/Diff/diffTreeEndpoint.types.js +1 -0
  13. package/Store/Diff/diffTreeHub.d.ts +139 -0
  14. package/Store/Diff/diffTreeHub.js +346 -0
  15. package/Store/Diff/hostPublisher.d.ts +39 -0
  16. package/Store/Diff/hostPublisher.js +151 -0
  17. package/Store/Diff/index.d.ts +3 -0
  18. package/Store/Diff/index.js +3 -0
  19. package/Store/Diff/observableDiffTree.d.ts +93 -0
  20. package/Store/Diff/observableDiffTree.js +199 -0
  21. package/Store/Diff/onConnect.d.ts +33 -0
  22. package/Store/Diff/onConnect.js +83 -0
  23. package/Store/Diff/utils/diffTree.types.d.ts +9 -0
  24. package/Store/Diff/utils/homes.d.ts +12 -0
  25. package/Store/Diff/utils/homes.js +40 -0
  26. package/Store/Diff/utils/routes.d.ts +18 -0
  27. package/Store/Diff/utils/routes.js +33 -2
  28. package/Store/Store/store.d.ts +36 -4
  29. package/Store/Store/store.js +47 -6
  30. package/Store/Store/storeAsync.d.ts +80 -25
  31. package/Store/Store/storeAsync.js +102 -33
  32. package/Store/Store/storeSync.d.ts +76 -11
  33. package/Store/Store/storeSync.js +105 -12
  34. package/Store/Tree/observableNode.js +68 -13
  35. package/Store/Tree/opaque.d.ts +30 -0
  36. package/Store/Tree/opaque.js +35 -0
  37. package/Store/Tree/snapshot.js +5 -4
  38. package/Store/index.d.ts +4 -1
  39. package/Store/index.js +1 -1
  40. package/Utils/decorators.d.ts +0 -98
  41. package/Utils/decorators.js +0 -156
  42. package/Utils/index.d.ts +2 -0
  43. package/Utils/index.js +1 -0
  44. package/Utils/subscriptionManager.d.ts +78 -0
  45. package/Utils/subscriptionManager.js +162 -0
  46. package/package.json +1 -1
  47. package/Store/Diff/diffTreeWorker.d.ts +0 -6
  48. package/Store/Diff/diffTreeWorker.js +0 -22
  49. package/Store/Diff/diffTreeWriter.d.ts +0 -92
  50. package/Store/Diff/diffTreeWriter.js +0 -137
  51. package/Store/Diff/workerQueue.d.ts +0 -7
  52. package/Store/Diff/workerQueue.js +0 -29
  53. package/Store/Store/pushStore.d.ts +0 -53
  54. package/Store/Store/pushStore.js +0 -77
@@ -1,137 +0,0 @@
1
- import { DiffTree } from "./diffTree";
2
- import { DIFF_TREE_ERROR, DIFF_TREE_EVENT } from "./diffTree.types";
3
- /**
4
- * A `DiffTree` that pushes its changes to a `PushStore` instead of answering a store's
5
- * requests. Use it inside a worker that produces data itself (for example, the result of a
6
- * computation it runs): write with the usual `DiffTree` methods, then call `Commit()` to run
7
- * projections and post everything since the last commit as one message.
8
- *
9
- * - Push only: don't pass a `DiffTreeWriter` to `ConnectWorkerToDiffTree`, which commits
10
- * every batch itself and would post it to the wrong place.
11
- * - After a change fails, every later change before `Commit()` throws that same error. The
12
- * changes made before the failure are already in the tree, so `Commit()` still sends them,
13
- * followed by a `DIFF_TREE_ERROR` message. Projections aren't run for that batch; the next
14
- * `Commit()` brings them up to date.
15
- * - A `PushStore` only receives the changes committed after it starts listening, so
16
- * create it before the writer's first `Commit()`.
17
- *
18
- * @example
19
- * // engine-worker.ts
20
- * const tree = new DiffTreeWriter(self, undefined, { "/": { projections } });
21
- * tree.WritePath("results", computeResults());
22
- * tree.Commit();
23
- *
24
- * // main thread
25
- * const store = new PushStore(worker);
26
- *
27
- * @see PushStore
28
- */
29
- export class DiffTreeWriter extends DiffTree {
30
- /**
31
- * Creates a DiffTreeWriter.
32
- * @param worker Where `Commit()` posts its messages: the worker's `self`, or a `MessagePort`.
33
- * On the same thread as the store, anything whose `postMessage` dispatches a `"message"`
34
- * event on the store's `EventTarget`. The store clones every value it applies, so it never
35
- * shares objects with the writer's tree.
36
- * @param keyFunc Optional function to extract a key from objects. Pass the same key logic to
37
- * the `PushStore` that receives the changes.
38
- * @param routes Optional route definitions. Projections run once per `Commit()`, after the
39
- * batch's changes.
40
- */
41
- constructor(worker, keyFunc, routes) {
42
- super(keyFunc, routes);
43
- this.worker = worker;
44
- this.uncommittedError = null;
45
- }
46
- /**
47
- * Not available on a DiffTreeWriter: `Commit()` runs projections once per batch, after its
48
- * changes. Running them earlier would push a projection result computed from part of a batch.
49
- * @throws Always.
50
- */
51
- RunProjections() {
52
- throw new Error("RunProjections is called during Commit()");
53
- }
54
- /**
55
- * Writes a value at a path.
56
- * @throws The change's error, or an earlier uncommitted change's error.
57
- */
58
- WritePath(path, value) {
59
- this.Guard(() => super.WritePath(path, value));
60
- }
61
- /**
62
- * Merges a patch into the current value at a path.
63
- * @throws The change's error, or an earlier uncommitted change's error.
64
- */
65
- PatchPath(path, patch) {
66
- this.Guard(() => super.PatchPath(path, patch));
67
- }
68
- /**
69
- * Appends items to the array at a path.
70
- * @throws The change's error, or an earlier uncommitted change's error.
71
- */
72
- PushPath(path, items) {
73
- this.Guard(() => super.PushPath(path, items));
74
- }
75
- /**
76
- * Splices the array at a path.
77
- * @throws The change's error, or an earlier uncommitted change's error.
78
- */
79
- SplicePath(path, start, deleteCount, items) {
80
- this.Guard(() => super.SplicePath(path, start, deleteCount, items));
81
- }
82
- /**
83
- * Deletes a route, its child routes and its route instances.
84
- * @throws The change's error, or an earlier uncommitted change's error.
85
- */
86
- DeleteRoute(routePath) {
87
- this.Guard(() => super.DeleteRoute(routePath));
88
- }
89
- /**
90
- * Runs projections and posts every change since the last commit as one `DIFF_TREE_EVENT`
91
- * message, which a `PushStore` applies as a unit. Posts nothing when nothing changed.
92
- *
93
- * If a change in the batch failed, projections are skipped, the applied changes are still
94
- * posted, and a `DIFF_TREE_ERROR` message follows with the error; `Commit()` itself doesn't
95
- * throw, since the failed change already did. If a projection throws, the batch's changes
96
- * and the error are posted the same way, then `Commit()` rethrows. Either way the next batch
97
- * starts clean.
98
- * @returns The diff that was posted.
99
- * @throws A projection's error.
100
- */
101
- Commit() {
102
- let diff = [];
103
- try {
104
- !this.uncommittedError && super.RunProjections();
105
- }
106
- catch (err) {
107
- this.uncommittedError = err;
108
- throw err;
109
- }
110
- finally {
111
- diff = super.Commit();
112
- diff.length > 0 && this.worker.postMessage({
113
- type: DIFF_TREE_EVENT,
114
- data: diff
115
- });
116
- if (this.uncommittedError) {
117
- this.worker.postMessage({
118
- type: DIFF_TREE_ERROR,
119
- data: this.uncommittedError
120
- });
121
- }
122
- this.uncommittedError = null;
123
- }
124
- return diff;
125
- }
126
- Guard(change) {
127
- if (this.uncommittedError)
128
- throw this.uncommittedError;
129
- try {
130
- change();
131
- }
132
- catch (err) {
133
- this.uncommittedError = err;
134
- throw err;
135
- }
136
- }
137
- }
@@ -1,7 +0,0 @@
1
- export declare class WorkerQueue<S, R> {
2
- private callbacks;
3
- private worker;
4
- constructor(worker: Worker);
5
- Push(message: S): Promise<R>;
6
- Destroy(): void;
7
- }
@@ -1,29 +0,0 @@
1
- import { List } from "../../Utils/list";
2
- export class WorkerQueue {
3
- constructor(worker) {
4
- this.worker = worker;
5
- this.callbacks = List.Create();
6
- this.worker.onerror = (err) => {
7
- const cb = List.Pop(this.callbacks);
8
- cb && cb(null, err);
9
- };
10
- this.worker.onmessage = (message) => {
11
- const cb = List.Pop(this.callbacks);
12
- cb && cb(message.data);
13
- };
14
- }
15
- Push(message) {
16
- return new Promise((resolve, reject) => {
17
- List.Add(this.callbacks, function (data, err) {
18
- if (err)
19
- reject(err);
20
- else
21
- resolve(data);
22
- });
23
- this.worker.postMessage(message);
24
- });
25
- }
26
- Destroy() {
27
- this.worker.terminate();
28
- }
29
- }
@@ -1,53 +0,0 @@
1
- import { ReadStore } from "./store";
2
- /**
3
- * A read-only store whose changes are pushed to it by a `DiffTreeWriter`. The writer decides
4
- * when data changes and pushes it with `Commit()`; this store applies each pushed batch as it
5
- * arrives, and readers update the same way they do for any other store.
6
- *
7
- * The source is any `EventTarget` that delivers the writer's messages as `"message"` events:
8
- * usually a `Worker` or a `MessagePort`, or a plain `EventTarget` when the writer runs on the
9
- * same thread. The store ignores any message that isn't a `DIFF_TREE_EVENT` or
10
- * `DIFF_TREE_ERROR`, so the source can carry other traffic too. It never takes over the
11
- * source's `onmessage` or terminates a worker; that stays with the source's owner. It doesn't
12
- * listen for the source's `"error"` events either: the writer's errors arrive as
13
- * `DIFF_TREE_ERROR` messages (see `Error`).
14
- *
15
- * Changes are diffs against the writer's tree, so create the store before the writer's
16
- * first `Commit()`. A store created later misses the earlier changes.
17
- *
18
- * @example
19
- * const worker = new Worker(new URL("./engine-worker.ts", import.meta.url), { type: "module" });
20
- * const store = new PushStore(worker);
21
- * store.Get<Results>("results"); // reactive; undefined until the first commit
22
- * store.Destroy(); // stops listening; doesn't terminate the worker
23
- *
24
- * @see DiffTreeWriter
25
- * @see StoreAsync
26
- */
27
- export declare class PushStore extends ReadStore {
28
- private eventTarget;
29
- private error;
30
- private errorScope;
31
- /**
32
- * The error the writer reported with its last commit, or null. Reactive. It's cleared when
33
- * a later commit's changes arrive, so it reflects the most recent push, not a stopped store:
34
- * the writer's later changes are still applied after an error.
35
- */
36
- get Error(): any;
37
- private messageHandler;
38
- /**
39
- * Creates a PushStore and starts listening to the source. A `MessagePort` is started for
40
- * you, since `addEventListener` doesn't start a port the way assigning `onmessage` does.
41
- * @param eventTarget The source of the `DiffTreeWriter`'s messages: a `Worker`, a
42
- * `MessagePort`, or any `EventTarget` that dispatches them as `"message"` events.
43
- * @param keyFunc Optional function to generate a key for a given data value, used to
44
- * resolve root objects. Pass the same key logic the `DiffTreeWriter` was constructed
45
- * with, if any.
46
- */
47
- constructor(eventTarget: EventTarget, keyFunc?: (value: any) => string | undefined);
48
- /**
49
- * Stops listening to the source and destroys the error scope. The source stays open (a
50
- * worker keeps running); closing or terminating it is up to its owner.
51
- */
52
- Destroy(): void;
53
- }
@@ -1,77 +0,0 @@
1
- import { DIFF_TREE_ERROR, DIFF_TREE_EVENT } from "../Diff/diffTree.types";
2
- import { ObservableScope } from "../Tree/observableScope";
3
- import { ReadStore } from "./store";
4
- /**
5
- * A read-only store whose changes are pushed to it by a `DiffTreeWriter`. The writer decides
6
- * when data changes and pushes it with `Commit()`; this store applies each pushed batch as it
7
- * arrives, and readers update the same way they do for any other store.
8
- *
9
- * The source is any `EventTarget` that delivers the writer's messages as `"message"` events:
10
- * usually a `Worker` or a `MessagePort`, or a plain `EventTarget` when the writer runs on the
11
- * same thread. The store ignores any message that isn't a `DIFF_TREE_EVENT` or
12
- * `DIFF_TREE_ERROR`, so the source can carry other traffic too. It never takes over the
13
- * source's `onmessage` or terminates a worker; that stays with the source's owner. It doesn't
14
- * listen for the source's `"error"` events either: the writer's errors arrive as
15
- * `DIFF_TREE_ERROR` messages (see `Error`).
16
- *
17
- * Changes are diffs against the writer's tree, so create the store before the writer's
18
- * first `Commit()`. A store created later misses the earlier changes.
19
- *
20
- * @example
21
- * const worker = new Worker(new URL("./engine-worker.ts", import.meta.url), { type: "module" });
22
- * const store = new PushStore(worker);
23
- * store.Get<Results>("results"); // reactive; undefined until the first commit
24
- * store.Destroy(); // stops listening; doesn't terminate the worker
25
- *
26
- * @see DiffTreeWriter
27
- * @see StoreAsync
28
- */
29
- export class PushStore extends ReadStore {
30
- /**
31
- * The error the writer reported with its last commit, or null. Reactive. It's cleared when
32
- * a later commit's changes arrive, so it reflects the most recent push, not a stopped store:
33
- * the writer's later changes are still applied after an error.
34
- */
35
- get Error() {
36
- return ObservableScope.Value(this.errorScope);
37
- }
38
- /**
39
- * Creates a PushStore and starts listening to the source. A `MessagePort` is started for
40
- * you, since `addEventListener` doesn't start a port the way assigning `onmessage` does.
41
- * @param eventTarget The source of the `DiffTreeWriter`'s messages: a `Worker`, a
42
- * `MessagePort`, or any `EventTarget` that dispatches them as `"message"` events.
43
- * @param keyFunc Optional function to generate a key for a given data value, used to
44
- * resolve root objects. Pass the same key logic the `DiffTreeWriter` was constructed
45
- * with, if any.
46
- */
47
- constructor(eventTarget, keyFunc) {
48
- super(keyFunc);
49
- this.eventTarget = eventTarget;
50
- this.error = null;
51
- this.errorScope = ObservableScope.Basic(() => this.error);
52
- this.messageHandler = (event) => {
53
- const messageData = event.data;
54
- if (messageData && messageData.type === DIFF_TREE_EVENT) {
55
- this.UpdateRootMap(messageData.data);
56
- if (this.error !== null) {
57
- this.error = null;
58
- ObservableScope.Update(this.errorScope);
59
- }
60
- }
61
- else if (messageData && messageData.type === DIFF_TREE_ERROR) {
62
- this.error = messageData.data;
63
- ObservableScope.Update(this.errorScope);
64
- }
65
- };
66
- eventTarget.addEventListener("message", this.messageHandler);
67
- eventTarget.start?.();
68
- }
69
- /**
70
- * Stops listening to the source and destroys the error scope. The source stays open (a
71
- * worker keeps running); closing or terminating it is up to its owner.
72
- */
73
- Destroy() {
74
- this.eventTarget.removeEventListener("message", this.messageHandler);
75
- ObservableScope.Destroy(this.errorScope);
76
- }
77
- }