@shivaedev/contract 0.0.0-stage → 0.16.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 (94) hide show
  1. package/CHANGELOG.md +210 -0
  2. package/LICENSE +21 -0
  3. package/README.md +511 -2
  4. package/dist/automaticLive.d.ts +28 -0
  5. package/dist/automaticLive.d.ts.map +1 -0
  6. package/dist/automaticLive.js +63 -0
  7. package/dist/automaticLive.js.map +1 -0
  8. package/dist/bind.d.ts +51 -0
  9. package/dist/bind.d.ts.map +1 -0
  10. package/dist/bind.js +14 -0
  11. package/dist/bind.js.map +1 -0
  12. package/dist/contract.d.ts +33 -0
  13. package/dist/contract.d.ts.map +1 -0
  14. package/dist/contract.js +44 -0
  15. package/dist/contract.js.map +1 -0
  16. package/dist/internal/bindingOwner.d.ts +8 -0
  17. package/dist/internal/bindingOwner.d.ts.map +1 -0
  18. package/dist/internal/bindingOwner.js +16 -0
  19. package/dist/internal/bindingOwner.js.map +1 -0
  20. package/dist/internal/clientOperations.d.ts +21 -0
  21. package/dist/internal/clientOperations.d.ts.map +1 -0
  22. package/dist/internal/clientOperations.js +36 -0
  23. package/dist/internal/clientOperations.js.map +1 -0
  24. package/dist/internal/liveInvalidation.d.ts +12 -0
  25. package/dist/internal/liveInvalidation.d.ts.map +1 -0
  26. package/dist/internal/liveInvalidation.js +14 -0
  27. package/dist/internal/liveInvalidation.js.map +1 -0
  28. package/dist/internal/makeHintPolicy.d.ts +4 -0
  29. package/dist/internal/makeHintPolicy.d.ts.map +1 -0
  30. package/dist/internal/makeHintPolicy.js +25 -0
  31. package/dist/internal/makeHintPolicy.js.map +1 -0
  32. package/dist/internal/queryReactivity.d.ts +5 -0
  33. package/dist/internal/queryReactivity.d.ts.map +1 -0
  34. package/dist/internal/queryReactivity.js +96 -0
  35. package/dist/internal/queryReactivity.js.map +1 -0
  36. package/dist/keys.d.ts +34 -0
  37. package/dist/keys.d.ts.map +1 -0
  38. package/dist/keys.js +25 -0
  39. package/dist/keys.js.map +1 -0
  40. package/dist/live.d.ts +39 -0
  41. package/dist/live.d.ts.map +1 -0
  42. package/dist/live.js +98 -0
  43. package/dist/live.js.map +1 -0
  44. package/dist/makeLiveServer.d.ts +20 -0
  45. package/dist/makeLiveServer.d.ts.map +1 -0
  46. package/dist/makeLiveServer.js +62 -0
  47. package/dist/makeLiveServer.js.map +1 -0
  48. package/dist/operation.d.ts +66 -0
  49. package/dist/operation.d.ts.map +1 -0
  50. package/dist/operation.js +29 -0
  51. package/dist/operation.js.map +1 -0
  52. package/dist/publicConfig.d.ts +20 -0
  53. package/dist/publicConfig.d.ts.map +1 -0
  54. package/dist/publicConfig.js +8 -0
  55. package/dist/publicConfig.js.map +1 -0
  56. package/dist/queryCoalesceWindow.d.ts +4 -0
  57. package/dist/queryCoalesceWindow.d.ts.map +1 -0
  58. package/dist/queryCoalesceWindow.js +11 -0
  59. package/dist/queryCoalesceWindow.js.map +1 -0
  60. package/dist/readPolicy.d.ts +10 -0
  61. package/dist/readPolicy.d.ts.map +1 -0
  62. package/dist/readPolicy.js +24 -0
  63. package/dist/readPolicy.js.map +1 -0
  64. package/dist/rejection.d.ts +41 -0
  65. package/dist/rejection.d.ts.map +1 -0
  66. package/dist/rejection.js +16 -0
  67. package/dist/rejection.js.map +1 -0
  68. package/dist/resume.d.ts +17 -0
  69. package/dist/resume.d.ts.map +1 -0
  70. package/dist/resume.js +28 -0
  71. package/dist/resume.js.map +1 -0
  72. package/dist/serverMetadata.d.ts +42 -0
  73. package/dist/serverMetadata.d.ts.map +1 -0
  74. package/dist/serverMetadata.js +27 -0
  75. package/dist/serverMetadata.js.map +1 -0
  76. package/package.json +76 -3
  77. package/src/automaticLive.ts +93 -0
  78. package/src/bind.ts +103 -0
  79. package/src/contract.ts +140 -0
  80. package/src/internal/bindingOwner.ts +24 -0
  81. package/src/internal/clientOperations.ts +74 -0
  82. package/src/internal/liveInvalidation.ts +21 -0
  83. package/src/internal/makeHintPolicy.ts +40 -0
  84. package/src/internal/queryReactivity.ts +109 -0
  85. package/src/keys.ts +62 -0
  86. package/src/live.ts +122 -0
  87. package/src/makeLiveServer.ts +76 -0
  88. package/src/operation.ts +145 -0
  89. package/src/publicConfig.ts +9 -0
  90. package/src/queryCoalesceWindow.ts +13 -0
  91. package/src/readPolicy.ts +33 -0
  92. package/src/rejection.ts +91 -0
  93. package/src/resume.ts +44 -0
  94. package/src/serverMetadata.ts +50 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,210 @@
1
+ # Changelog
2
+
3
+ ## 0.16.0 - 2026-10-26
4
+
5
+ ### Added
6
+
7
+ - Provide the shared expected failure schemas and `rejectedField` in `@shivaedev/effect-contract/errors/`, so browser-safe contract consumers can use them without depending on Platform. Tags, schema fields and RPC encoding remain the same.
8
+
9
+ ### Breaking
10
+
11
+ - Move all imports from `@shivaedev/platform/errors/taxonomy.ts` to `@shivaedev/effect-contract/errors/taxonomy.ts`, and from `@shivaedev/platform/errors/rejectedField.ts` to `@shivaedev/effect-contract/errors/rejectedField.ts`. The old modules are removed. Add a direct `@shivaedev/effect-contract` dependency if the consuming package does not already declare one. Admin, GitHub, Work Board and Work Fleet public failure types now refer to these shared classes.
12
+ - Generated apps use the new imports. The create-app updater applies the starter changes through its usual three-way patch; it does not rewrite imports in app-owned files. Replace both old import paths above in those files when upgrading existing apps.
13
+
14
+ ## 0.15.0 - 2026-10-25
15
+
16
+ ### Added
17
+
18
+ - `bind` accepts an optional `resume: ResumeSource` to reopen and reconcile automatic live subscriptions from application lifecycle events alongside the browser defaults. Registry disposal unsubscribes the source.
19
+ - React automatic session subscriptions use the same source supplied to `bind` in `SessionBoundary.connect`, so native shells can reconcile live query screens from their own lifecycle events.
20
+
21
+ ## 0.14.0 - 2026-10-25
22
+
23
+ ### Added
24
+
25
+ - `effect-sql` logs one lost warning per PostgreSQL listener outage and an info line after recovery, with `downtimeMs` since that warning and `streamCount` for the live streams resynchronized. Failed reconnect attempts log at debug. Initial successful startup logs neither outage line, and outage diagnostics omit database error causes and connection details.
26
+ - `effect-contract`'s `makeLiveServer.resync` reports the number of open live streams it marked for reconciliation, excluding streams whose scopes have closed.
27
+
28
+ ### Breaking
29
+
30
+ - Direct `postgresChanges` callers must supply `resync: Effect.Effect<number>` instead of `Effect.Effect<void>`. Pass `makeLiveServer.resync` unchanged, or return the number of open streams marked by your own stream owner.
31
+
32
+ ## 0.13.0 - 2026-10-25
33
+
34
+ ### Added
35
+
36
+ - Declare `keyScope: "session"` on a contract and bind it with `bind(Api, Client, { registry })`. Its query keys, successful-command invalidations, live hints and reconciliation use that session registry's scope. `List` and `Item` retain their shapes and item/list/wildcard semantics; `readKeys`, `invalidationKeys`, `makeLiveServer.stream` and `live` accept contextual scope resolution. Server adapters receive the `KeyScope` annotation and must resolve session scopes from request-local authenticated identity.
37
+ - Session-scoped automatic subscriptions track mounted query references per registry and release them when queries unmount or the registry is disposed.
38
+
39
+ ### Breaking
40
+
41
+ - The reserved `<contract>.$changes` payload is now `{ queries: [{ query: "get", payload: { id: 1 } }] }`, typed and decoded with the contract's declared query payload schemas. Custom clients must replace `{ keys }` with declared query references; payloadless queries use `{ query: "list", payload: undefined }`. Subscription handlers must resolve these references with `queryKeys(Api.declaration.queries, queries)` or the RPC's `ChangesReads` annotation before calling `makeLiveServer.stream`. `changesRpc` now requires both the contract name and its query declarations. No raw-key subscription endpoint remains.
42
+ - Board's handoff and response RPC contracts use distinct `work-board-handoffs` and `work-board-responses` namespaces so merging contracts preserves each declared subscription schema. Custom RPC clients must replace the `work-board.` prefix for handoff and response operations with the corresponding namespace; operation names and payloads stay the same.
43
+
44
+ ## 0.12.0 - 2026-10-25
45
+
46
+ ### Added
47
+
48
+ - effect-contract item reads refresh on their collection-wide `<collection>:*` key, with live hints naming each affected subscribed item.
49
+
50
+ ### Breaking
51
+
52
+ - effect-sql writes returning more than 1,000 rows across all chunks of a single call announce `<table>` and `<table>:*` instead of item keys. Code registering raw `<table>:<id>` Reactivity keys outside effect-contract must also register `<table>:*`.
53
+
54
+ ## 0.11.1 - 2026-10-25
55
+
56
+ ### Changed
57
+
58
+ - Release with updated workspace dependencies.
59
+
60
+ ## 0.11.0 - 2026-10-24
61
+
62
+ ### Added
63
+
64
+ - Contracts expose `application`, a native RPC group for building application handlers without naming the reserved `$changes` stream. Middleware stays attached, and Platform hosts complete the full contract with the stream handler.
65
+ - Generated applications build their handlers through the contract's `application` group.
66
+
67
+ ### Changed
68
+
69
+ - Require Effect and its companion packages at exactly 4.0.5. Generated applications use the same versions.
70
+
71
+ ## 0.10.0 - 2026-10-19
72
+
73
+ ### Added
74
+
75
+ - Choose a live changed-hint coalescing window per bound query with React's `useQuery(atom, { coalesceWindow })`, keeping the session window as the default. Queries over one connection refetch on their own schedules; changing the option does not reconnect or refetch queries.
76
+ - Configure a bound query's window through its registry with `queryCoalesceWindow(query)` from `@shivaedev/effect-contract/queryCoalesceWindow.ts`.
77
+
78
+ ## 0.9.0 - 2026-10-19
79
+
80
+ ### Added
81
+
82
+ - Contracts include their reserved `<namespace>.$changes` stream in native RPC client types, with the same middleware as declared operations. Subscribe through a client typed from the contract without a cast or a separate Changes group.
83
+
84
+ ### Breaking
85
+
86
+ - Native contract handler builders now require the reserved `$changes` handler. When a Platform host supplies it, build application handlers with `contract.omit("<namespace>.$changes").of(...)` and `.toLayer(...)`, while retaining the full contract for the host and client. Standalone servers and test clients must supply a changes stream handler. Remove hand-built Changes groups and use the contract directly.
87
+
88
+ ## 0.8.0 - 2026-10-19
89
+
90
+ ### Added
91
+
92
+ - `authorizeReads` accepts typed policy failures and preserves them in the query's error channel. Declare those errors in the native RPC middleware's error schema alongside its denial so clients can distinguish an outage from denied access.
93
+ - `ReadPolicyMemoWindow`, a `Context.Reference<Duration.Input>`, configures per-subscription, per-key memoisation of successful policy results. The default is one second; provide a shorter duration or `0` to disable it. Queries always check afresh, and failures are never memoised.
94
+ - Coalesce live changed hints over a default 20 ms window, with one follow-up read when hints arrive during an in-flight refetch. Configure `live()` with `coalesceWindow`, or set its returned `coalesceWindow` atom; zero retains immediate invalidation. Reconciliation stays immediate.
95
+ - Configure automatic live connections per React `SessionBoundary` with `liveCoalesceWindow`.
96
+
97
+ ### Fixed
98
+
99
+ - Failed live hint checks omit the affected keys and keep the stream open. Scoped rechecks after one second deliver an allowed key after recovery without another change or reconnect; a `false` does not schedule a recheck.
100
+
101
+ ### Breaking
102
+
103
+ - Direct readers of `ReadPolicy` now receive `Effect<boolean, unknown>` instead of an infallible Effect. Handle its error channel when invoking the reference directly. Existing infallible policies passed to `authorizeReads` still work; fallible policies should declare their errors in their RPC middleware schema.
104
+
105
+ ## 0.7.0 - 2026-10-19
106
+
107
+ ### Added
108
+
109
+ - `authorizeReads(effect, request, policy, denied)` and `ReadPolicy` in `readPolicy.ts` share a key authorization policy between query reads and live hints. `QueryReads` in `serverMetadata.ts` exposes the declared query read keys to server middleware.
110
+ - `changesRpc(name)` retains the literal contract name for typed native clients.
111
+
112
+ ### Fixed
113
+
114
+ - effect-contract's `live` coordinator no longer reconciles its read scope when `paused` is read for the first time; a component that showed the pause state while connecting used to make every loaded query read again.
115
+ - Opening a Board page sends each read once. The page starts its reads after the live connection's first update, which used to read navigation and watcher state a second time, and a failed connection does not hold the page.
116
+ - A file event that changes neither the bytes nor the modification time no longer refreshes open Board pages. A file saved with the same bytes and a new modification time still refreshes them.
117
+ - Live streams filter changed keys with the viewer's read policy and suppress empty hints, while preserving independently allowed list hints.
118
+
119
+ ## 0.6.0 - 2026-10-18
120
+
121
+ ### Added
122
+
123
+ - Contracts attach command invalidation metadata and a host-served change subscription. `serverMetadata.ts` exports `CommandInvalidation` and `changesRpc(name)` for server adapters.
124
+ - Bindings expose the `LiveConnection` symbol from `automaticLive.ts`; React session boundaries mount its `connection` atom and track the binding's query keys. `LiveBound` describes its connection and status atoms; `automaticLive(service, name)` and `ChangesClient` expose the underlying tracked coordination. `live` also accepts a function for `resyncKeys`.
125
+
126
+ ### Fixed
127
+
128
+ - Live server hints contain only changed keys intersecting the subscription, so one item's change does not refetch unrelated item queries.
129
+
130
+ ### Breaking
131
+
132
+ - Contracts reserve the `<contract>.$changes` RPC name for automatic subscriptions. Use Platform's database host and NDJSON transport for automatic live queries, and remove application subscription handlers and `live()` mounting when using a React session boundary.
133
+
134
+ ## 0.5.1 - 2026-10-17
135
+
136
+ ### Fixed
137
+
138
+ - Publish against `@shivaedev/types` 0.2.1 so framework consumers share the current version.
139
+
140
+ ## 0.5.0 - 2026-10-13
141
+
142
+ ### Breaking
143
+
144
+ - Requires stable Effect 4.0.4 in place of 4.0.0-rc.112. Effect 4.0.4 moves the former `effect/unstable/*` modules to `effect/*` and renames constructors such as `Config.string` to `Config.String`.
145
+
146
+ ## 0.4.1 - 2026-10-12
147
+
148
+ ### Added
149
+
150
+ - `makeLiveServer` in `makeLiveServer.ts` converts local Reactivity invalidations into native `LiveHint` streams for explicit read keys. Independent helpers keep their resync scopes separate. Each subscription starts with `Resync`; `resync` reconciles every active stream, including after a PostgreSQL listener loses its connection.
151
+ - Declare typed streaming operations with Schema payloads and elements, rejections and read keys in native RPC contracts. Bound `run` returns a native Stream, with HTTP tests proving element delivery, declared failures and server subscription release on completion or client interruption.
152
+
153
+ ### Changed
154
+
155
+ - Prefix generic type parameter names in contract, operation and collection declarations with `T` while preserving their types and runtime behavior.
156
+ - Document the package's purpose, native RPC and freshness model, complete usage, design priorities and roadmap; publish `docs/` with the README.
157
+ - Build package JavaScript, declarations and source maps with TypeScript 7.
158
+
159
+ ## 0.4.0 - 2026-10-05
160
+
161
+ ### Added
162
+
163
+ - Optional `live.ts` invalidation over native Streams, Reactivity and AtomRpc runtimes: precise changed keys, explicit full-scope reconciliation after initial/reconnected delivery, bounded paused observations, resume, typed stream failures and scoped teardown. Native query atoms own retained data and stale-request interruption.
164
+ - `Key` and `LiveHint` Schemas for existing list/item keys and Changed/Resync hints. A real streaming HTTP/browser fixture demonstrates their composition with native newline-delimited RPC serialization.
165
+ - Browser-safe `resume.ts` owns the existing native/browser resume signal without React peers; effect-react delegates its existing entry to it.
166
+
167
+ ### Changed
168
+
169
+ - `bind` accepts a native client group with additional RPC operations while preserving the declared contract's types and rejecting clients missing its operations.
170
+
171
+ ## 0.3.0 - 2026-10-04
172
+
173
+ ### Changed
174
+
175
+ - Breaking: no root entry and no module that re-exports another. `exports` maps one `"./*.ts"` pattern to every module (`src` under the `source` condition, `dist` otherwise), so you import the module that defines a name, and a bundler sees only the modules you use. Where each name now lives:
176
+ - `@shivaedev/effect-contract`: `@shivaedev/effect-contract/bind.ts` (`Bound`, `BoundCommand`, `BoundQuery`, `bind`, `Failure`, `QueryOptions`, `RunFailure`), `@shivaedev/effect-contract/contract.ts` (`Contract`, `contract`, `Declared`, `OperationRpc`, `Tag`), `@shivaedev/effect-contract/keys.ts` (`Collection`, `collection`, `Identity`, `ItemKey`, `invalidationKeys`, `Key`, `ListKey`, `readKeys`), `@shivaedev/effect-contract/operation.ts` (`Command`, `CommandShape`, `command`, `OperationShape`, `PayloadSchema`, `Query`, `QueryShape`, `query`), `@shivaedev/effect-contract/rejection.ts` (`FieldRejection`, `fieldRejection`, `MatchingTags`, `Reject`, `RejectedBy`, `RejectionClass`, `RejectionSpecs`, `Rejections`, `RejectionUnion`, `RejectionValue`, `TaggedRejection`)
177
+
178
+ ## 0.2.1 - 2026-10-04
179
+
180
+ ### Changed
181
+
182
+ - Imports that leave their folder go through `#` aliases declared in the `imports` field of `package.json`: `#*.ts` resolves to `src` under the `source` condition and to `dist` otherwise, and `#test/*` names a test file. The published modules and declarations name the package's own files through these aliases.
183
+
184
+ ## 0.2.0 - 2026-10-04
185
+
186
+ ### Changed
187
+
188
+ - Consolidate duplicate test cases around observable package behavior.
189
+ - The function members of `Contract`, `Query` and `Command` are declared as properties, so TypeScript checks their parameters strictly. `QueryShape.reads` and `CommandShape.invalidates` stay bivariant, so a contract still takes operations with typed payloads; the package now depends on `@shivaedev/types` for `Bivariant`.
190
+
191
+ - Validate packed consumers and executable bins through the shared workspace gate.
192
+
193
+ - Build with the `@shivaedev/quality` tsconfig presets, which target ESNext and allow only erasable TypeScript syntax.
194
+
195
+ - Type-check with TypeScript 7 only. TypeScript 6 still builds the package.
196
+
197
+ - Lint and format with the `@shivaedev/quality` Biome preset through `quality lint` at the repository root, which replaces the package's `check` script.
198
+
199
+ - Run tests through the `@shivaedev/quality` Vitest projects, which take a test's environment from its file name. Type tests are named `*.typecheck.test.ts`.
200
+
201
+ - Keep `package.json` in sort-package-json key order, checked by `quality lint`.
202
+
203
+ ## 0.1.0 - 2026-09-26
204
+
205
+ ### Added
206
+
207
+ - Declare queries and commands with typed rejections and reactivity keys; group
208
+ them into a native `RpcGroup` with namespaced tags.
209
+ - Bind a contract to a native `AtomRpc` service: query atoms register declared
210
+ read keys; command runs invalidate declared keys after success.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ShivaeDev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.