@procedures/store 0.46.0 → 0.47.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/CHANGELOG.md +51 -13
- package/README.md +2 -2
- package/dist/.tsbuildinfo +1 -1
- package/dist/program-store/procedures.d.ts +1 -1
- package/dist/program-store/procedures.d.ts.map +1 -1
- package/dist/program-store/procedures.js +1 -1
- package/dist/program-store/procedures.js.map +1 -1
- package/dist/program-store/programs.js +1 -1
- package/dist/program-store/programs.js.map +1 -1
- package/dist/storage/feed.d.ts +3 -3
- package/dist/storage/feed.js +1 -1
- package/dist/storage/hybrid.d.ts +10 -10
- package/dist/storage/hybrid.d.ts.map +1 -1
- package/dist/storage/hybrid.js +8 -8
- package/dist/storage/hybrid.js.map +1 -1
- package/package.json +6 -6
- package/src/program-store/procedures.ts +1 -1
- package/src/program-store/programs.ts +1 -1
- package/src/storage/feed.ts +3 -3
- package/src/storage/hybrid.ts +12 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# @procedures/store
|
|
2
2
|
|
|
3
|
+
## 0.47.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [0650616]
|
|
8
|
+
- Updated dependencies [2684531]
|
|
9
|
+
- Updated dependencies [ae1e3fd]
|
|
10
|
+
- Updated dependencies [f1ece74]
|
|
11
|
+
- @procedures/client@0.47.2
|
|
12
|
+
- @procedures/collections@0.47.2
|
|
13
|
+
|
|
14
|
+
## 0.47.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [f845c6d]
|
|
19
|
+
- @procedures/client@0.47.1
|
|
20
|
+
- @procedures/collections@0.47.1
|
|
21
|
+
|
|
22
|
+
## 0.47.0
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- e913014: Each module imports zod with `import * as z from "zod"`, not `import { z } from "zod"`. With the old form, an esbuild bundle got each locale of zod: 264 kB of minified code (esbuild metafile of the journey worker of the site). The Vite build of the site gives the same worker files with both forms. The procedure scaffolder writes the new form in `types.ts`. The API and the behavior stay the same.
|
|
27
|
+
- Updated dependencies [397dd4b]
|
|
28
|
+
- Updated dependencies [c9125a8]
|
|
29
|
+
- Updated dependencies [335728b]
|
|
30
|
+
- Updated dependencies [d987202]
|
|
31
|
+
- Updated dependencies [45a737f]
|
|
32
|
+
- Updated dependencies [d77e9e8]
|
|
33
|
+
- Updated dependencies [e913014]
|
|
34
|
+
- Updated dependencies [2f0c7b0]
|
|
35
|
+
- Updated dependencies [ad70c38]
|
|
36
|
+
- Updated dependencies [47819c6]
|
|
37
|
+
- Updated dependencies [e1ce6f4]
|
|
38
|
+
- @procedures/collections@0.47.0
|
|
39
|
+
- @procedures/client@0.47.0
|
|
40
|
+
|
|
3
41
|
## 0.46.0
|
|
4
42
|
|
|
5
43
|
### Patch Changes
|
|
@@ -84,9 +122,9 @@
|
|
|
84
122
|
Migration steps:
|
|
85
123
|
|
|
86
124
|
- The site: no step. It does not catch a `TIMEOUT` of a `HybridStorage` write.
|
|
87
|
-
-
|
|
88
|
-
-
|
|
89
|
-
-
|
|
125
|
+
- An app: no step, unless code catches a `TIMEOUT` of a `write-through` write to show an undo. That code gets `PendingWriteError`, with the `TIMEOUT` as its `cause`.
|
|
126
|
+
- An app: the own `isUnavailable` that keeps `TIMEOUT` in the queue is not necessary at this time. Remove it, or keep it: the result is the same.
|
|
127
|
+
- An app: no step. To keep the old behavior, pass `isUnavailable: (error) => error?.retryable === true || error?.code === undefined`.
|
|
90
128
|
|
|
91
129
|
### Patch Changes
|
|
92
130
|
|
|
@@ -189,8 +227,8 @@
|
|
|
189
227
|
- A host whose `expose`, policy or limit pattern names such a path in text uses the encoded form, for example `collections.e2e%2Etabs.*`.
|
|
190
228
|
- An `mcpExclude` entry, an `expose` deny entry or a limit entry in the old raw form, for example `collections.e2e.tabs.drop`, does not match. The check compares the encoded key, so the procedure becomes visible, or the limit does not apply. Write each such entry in the encoded form, for example `collections.e2e%2Etabs.drop`.
|
|
191
229
|
- A subscriber of a dotted collection uses `collectionChangeTopic(name)`. The raw topic `collections.a.b` is the topic of the partition `b` of `a`.
|
|
192
|
-
-
|
|
193
|
-
-
|
|
230
|
+
- An app: read the collection of a topic with `collectionTopicPartition(topic)`, not with a pattern, for example `/^collections\.([^.]+)\./`.
|
|
231
|
+
- Other apps: no change, if their collection names have no `.` and no `%`.
|
|
194
232
|
|
|
195
233
|
### Patch Changes
|
|
196
234
|
|
|
@@ -207,7 +245,7 @@
|
|
|
207
245
|
|
|
208
246
|
Migration:
|
|
209
247
|
|
|
210
|
-
-
|
|
248
|
+
- Apps: no change at this time. The deprecated names work until the next MINOR.
|
|
211
249
|
- Before the next MINOR, replace `zodAdapter<T>(schema)` with `schema`. To keep the check of a schema against a type, write `const schema: z.ZodType<T> = ...`.
|
|
212
250
|
- Before the next MINOR, replace `typedAnySchema<T>()` and `outputSchema<T>()` with `typed<T>()`.
|
|
213
251
|
- A parse-only object (`{ parse }`) in `zodAdapter` becomes a Standard Schema with a `~standard` property.
|
|
@@ -344,7 +382,7 @@
|
|
|
344
382
|
|
|
345
383
|
### Patch Changes
|
|
346
384
|
|
|
347
|
-
- b7a5167: Added: the option `aroundRemoteApply` of `HybridStorage` puts each apply of the remote changes inside a hook
|
|
385
|
+
- b7a5167: Added: the option `aroundRemoteApply` of `HybridStorage` puts each apply of the remote changes inside a hook. An app uses it to start a span of a trace with the `traceparent` that the server sends with a change.
|
|
348
386
|
|
|
349
387
|
- `aroundRemoteApply(hint, apply, context)` starts `apply` one time and gives back its promise. `context.cause` is `"delta"`, `"hint"`, `"gap"` or `"pull"`. `context.hints` has the hints of the apply.
|
|
350
388
|
- A delta and a hint of the feed give their hint. A gap and a pull of the storage (the timer of `pullInterval`, `syncFromRemote()`, `sync()` and the first sync) give the hint `undefined`.
|
|
@@ -599,9 +637,9 @@
|
|
|
599
637
|
Migration:
|
|
600
638
|
|
|
601
639
|
- **Site.** No change. The site does not write collections.
|
|
602
|
-
- **
|
|
603
|
-
- **
|
|
604
|
-
- **
|
|
640
|
+
- **An app with `HybridStorage`.** No change for a storage or a `HybridStorage` without `versionOf`. A `HybridStorage` with `versionOf` over `ApiStorage` needs a server storage with the same `versionOf` (for example `new InMemoryStorage({ versionOf })`), or the option `sendBaseVersions: false`.
|
|
641
|
+
- **An app with last-write-wins.** It gives no expected version, so nothing changes. Its own storage must refuse a write with an expected version until it tests one. Add the guard to its `set`, `delete` and `setBatch`, and run the contract suite: its first case tests the refusal. To adopt the version later, stamp a version field on the server, give the storage a `versionOf` that tests it in the write, and give the same `versionOf` to the `HybridStorage` of the client. Then add `createWithVersions` to the contract run.
|
|
642
|
+
- **An app without versions.** No change: it gives no expected version. A storage of the app that implements `CollectionStorage` must refuse a write with an expected version, as above.
|
|
605
643
|
- **Other storages.** Each class that implements `CollectionStorage` reads the new options of `set`, `delete` and `setBatch`. It tests them in the write, or it rejects the write with `preconditionNotSupported()`. It never ignores them.
|
|
606
644
|
|
|
607
645
|
### Patch Changes
|
|
@@ -768,14 +806,14 @@
|
|
|
768
806
|
- The option `origin` of `HybridStorage` is the tag of the storage (a random `hybrid-…` tag by default). Each write of the storage to the local copy and to the remote has it. The write methods of `HybridStorage` and `ApiStorage` take `{ origin }`.
|
|
769
807
|
- `capture: "observe"`: the storage observes the local copy and queues each change with another origin. Thus an application can write to the local copy directly, for example with the synchronous writes of a SignalDB collection. In `write-through` and `remote-only` mode, the storage sends a captured change at once.
|
|
770
808
|
- The option `syncState` takes a `SyncStateStore`: `MemorySyncStateStore`, or `IndexedDbSyncStateStore` of `@procedures/store/indexeddb`. The store keeps the cursor and the base versions. A new storage with the same store and a durable local copy asks only for the changes since the cursor, and it finds the conflicts of the base versions. A failure of the store goes to the status (`operation: "store"`, `SyncStateError`), and the storage goes on.
|
|
771
|
-
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it
|
|
809
|
+
- The option `feed` takes a `RemoteChangeFeed`. A delta whose `since` is the cursor applies without a read of the remote. A gap, a lost event, a new subscription or another delta makes one pull. A delta that comes during a pull applies after the pull, so the pull does not erase it.
|
|
772
810
|
- In `write-through` mode, a pull or a delta does not write over an own write that waits for the remote, a set or a delete. The storage keeps the remote value of the id, and after the write it reads the id again: then the rules of a pull decide. A read of a missing id does not bring back an item whose own delete waits.
|
|
773
|
-
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write
|
|
811
|
+
- With `versionOf`, the storage keeps the versions of its own writes until their echoes come (option `echoWindow`, 30 seconds by default). The echo of an older own write does not write over a newer local write.
|
|
774
812
|
- `EventsChangeFeed` of `@procedures/store` is the feed of the change events. Its source is a `Client`, a `WebSocketTransport` or another transport. It treats the events as hints: a gap of the numbers, a lost event, a hint and each confirmation of the subscription call `onGap()`.
|
|
775
813
|
- The core collection procedures publish `CollectionChangeEvent` `{ since, version, changed, deleted, origin }` on `ctx.bus`, under the topic `collections.<name>` (`collectionChangeTopic()`), while a subscriber listens. The changes come from `getChangesSince()` of the storage, and the events of one storage make a chain of versions. The option `changeEvents` of `createCollectionProcedures()` turns them off, or gives the topic of each call: the partition of CLI-17 goes there.
|
|
776
814
|
- A value reaches a subscriber only through the checks of a read. By default, an event has the ids and the versions only, and `EventsChangeFeed` gives it to `onHint()`: `HybridStorage` reads the values with `changes`, and a hint with only deletes applies without a read. With `changeEvents: { values: true }`, an event also has `values`: each row `{ id, value }` passes the output filter of the host (`admitItem`) for each subscriber, and a refused id goes in `withheld`, so the storage pulls it.
|
|
777
815
|
- `EventPublisher` refuses a topic whose reads the capability of the call does not permit (`FORBIDDEN`, `effects-exceeded`). Its new option `reads` gives the reads of a topic. The default, `collectionTopicReads()`, gives `collection:<name>` for `collections.<name>` and `collections.<name>.<partition>`. `ctx.admit` gives a procedure the output filter of its host for the data that it sends later.
|
|
778
|
-
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time
|
|
816
|
+
- The syncs of one `HybridStorage` run one at a time: the deltas and the hints of the feed, the pulls, the pushes, the reads after an own write and the mode switches. A remote delta and a full sync never run at the same time.
|
|
779
817
|
- The write inputs of the collection procedures take an optional `origin` (1 to 256 characters). The procedure gives it to the storage and to the event. A server before this change ignores the field.
|
|
780
818
|
- `Client.subscribe()` and `Client.events()` subscribe to the topics of the bus of the server through the middleware and the context of the client. A subscription has no deadline: the timeouts of the client do not apply to it, and only `metadata: { timeout }` in its options gives one.
|
|
781
819
|
- New exports: `collectionChangeTopic`, `CollectionChangeEvent` and `CollectionChangeEventsOptions` from `@procedures/client`, `./browser` and `./procedures`. `EventsChangeFeed`, `MemorySyncStateStore`, `SyncStateError` and the types `RemoteChangeFeed`, `RemoteChangeListener`, `RemoteChanges`, `EventSubscriber`, `ChangeEventSource`, `EventsChangeFeedOptions`, `SyncState`, `SyncStateChange` and `SyncStateStore` from `@procedures/store`. `IndexedDbSyncStateStore` and `MemorySyncStateStore` from `@procedures/store/indexeddb`.
|
package/README.md
CHANGED
|
@@ -393,7 +393,7 @@ const users = new HybridStorage(new ApiStorage(client, { collection: "users" }),
|
|
|
393
393
|
|
|
394
394
|
### The hook around a remote apply
|
|
395
395
|
|
|
396
|
-
The option `aroundRemoteApply` puts each apply of the remote changes inside a hook
|
|
396
|
+
The option `aroundRemoteApply` puts each apply of the remote changes inside a hook. For example, the hook starts a span of a trace with the `traceparent` of the server.
|
|
397
397
|
|
|
398
398
|
- The hook gets `hint`, `apply` and `context`. It starts `apply` one time and gives back its promise.
|
|
399
399
|
- `context.cause` is `"delta"`, `"hint"`, `"gap"` or `"pull"`. `context.hints` has the hints of the apply.
|
|
@@ -588,7 +588,7 @@ The entry `@procedures/store/browser` has the parts of the store that run in a b
|
|
|
588
588
|
- `TabGroup`: one leader tab does the sync of many collections, with one lock and one channel.
|
|
589
589
|
- All of `@procedures/store/indexeddb`: `IndexedDbStorage`, the IndexedDB stores and their fallbacks in memory.
|
|
590
590
|
|
|
591
|
-
No module of the entry imports a module of Node. The modules import `@procedures/client/browser` and not the root of the client, because the root imports `http` and `ws`. The test `src/browser.test.ts` examines the imports of each module of the entry. The entry is in `client.browser` of `package.json`, so the CI check of the browser entries (`scripts/check-browser-entries.
|
|
591
|
+
No module of the entry imports a module of Node. The modules import `@procedures/client/browser` and not the root of the client, because the root imports `http` and `ws`. The test `src/browser.test.ts` examines the imports of each module of the entry. The entry is in `client.browser` of `package.json`, so the CI check of the browser entries (`scripts/check-browser-entries.ts`) bundles it for a browser too.
|
|
592
592
|
|
|
593
593
|
The entry does not have these parts:
|
|
594
594
|
|