@amalgm/live 0.2.27 → 0.2.29

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 (197) hide show
  1. package/PURPOSE.md +38 -25
  2. package/README.md +1 -2
  3. package/dist/contracts/index.d.ts +0 -1
  4. package/dist/contracts/index.d.ts.map +1 -1
  5. package/dist/contracts/index.js +0 -1
  6. package/dist/contracts/index.js.map +1 -1
  7. package/dist/detection/record-proposal.d.ts +3 -2
  8. package/dist/detection/record-proposal.d.ts.map +1 -1
  9. package/dist/detection/record-proposal.js +9 -7
  10. package/dist/detection/record-proposal.js.map +1 -1
  11. package/dist/entities/cloud.d.ts.map +1 -1
  12. package/dist/entities/cloud.js +4 -1
  13. package/dist/entities/cloud.js.map +1 -1
  14. package/dist/index.d.ts +3 -2
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +3 -2
  17. package/dist/index.js.map +1 -1
  18. package/dist/machines/index.d.ts +0 -2
  19. package/dist/machines/index.d.ts.map +1 -1
  20. package/dist/machines/index.js +0 -2
  21. package/dist/machines/index.js.map +1 -1
  22. package/dist/records/authority.d.ts +23 -0
  23. package/dist/records/authority.d.ts.map +1 -0
  24. package/dist/records/authority.js +28 -0
  25. package/dist/records/authority.js.map +1 -0
  26. package/dist/records/codec.d.ts +6 -0
  27. package/dist/records/codec.d.ts.map +1 -0
  28. package/dist/records/codec.js +42 -0
  29. package/dist/records/codec.js.map +1 -0
  30. package/dist/records/contracts.d.ts +46 -0
  31. package/dist/records/contracts.d.ts.map +1 -0
  32. package/dist/records/contracts.js +114 -0
  33. package/dist/records/contracts.js.map +1 -0
  34. package/dist/records/inbox.d.ts +18 -0
  35. package/dist/records/inbox.d.ts.map +1 -0
  36. package/dist/records/inbox.js +34 -0
  37. package/dist/records/inbox.js.map +1 -0
  38. package/dist/records/index.d.ts +7 -0
  39. package/dist/records/index.d.ts.map +1 -0
  40. package/dist/records/index.js +7 -0
  41. package/dist/records/index.js.map +1 -0
  42. package/dist/records/outbox.d.ts +20 -0
  43. package/dist/records/outbox.d.ts.map +1 -0
  44. package/dist/records/outbox.js +44 -0
  45. package/dist/records/outbox.js.map +1 -0
  46. package/dist/registration/user-ground.d.ts +4 -4
  47. package/dist/registration/user-ground.d.ts.map +1 -1
  48. package/dist/registration/user-ground.js +8 -3
  49. package/dist/registration/user-ground.js.map +1 -1
  50. package/dist-cjs/contracts/binding.js +26 -0
  51. package/dist-cjs/contracts/binding.js.map +1 -0
  52. package/dist-cjs/contracts/content.js +99 -0
  53. package/dist-cjs/contracts/content.js.map +1 -0
  54. package/dist-cjs/contracts/docs.js +56 -0
  55. package/dist-cjs/contracts/docs.js.map +1 -0
  56. package/dist-cjs/contracts/events.js +44 -0
  57. package/dist-cjs/contracts/events.js.map +1 -0
  58. package/dist-cjs/contracts/frames/gateway.js +39 -0
  59. package/dist-cjs/contracts/frames/gateway.js.map +1 -0
  60. package/dist-cjs/contracts/frames/stream.js +20 -0
  61. package/dist-cjs/contracts/frames/stream.js.map +1 -0
  62. package/dist-cjs/contracts/frames/tunnel.js +60 -0
  63. package/dist-cjs/contracts/frames/tunnel.js.map +1 -0
  64. package/dist-cjs/contracts/index.js +34 -0
  65. package/dist-cjs/contracts/index.js.map +1 -0
  66. package/dist-cjs/contracts/presence.js +38 -0
  67. package/dist-cjs/contracts/presence.js.map +1 -0
  68. package/dist-cjs/contracts/resources.js +114 -0
  69. package/dist-cjs/contracts/resources.js.map +1 -0
  70. package/dist-cjs/contracts/snapshot.js +31 -0
  71. package/dist-cjs/contracts/snapshot.js.map +1 -0
  72. package/dist-cjs/contracts/validate.js +34 -0
  73. package/dist-cjs/contracts/validate.js.map +1 -0
  74. package/dist-cjs/detection/adapter-contract.js +168 -0
  75. package/dist-cjs/detection/adapter-contract.js.map +1 -0
  76. package/dist-cjs/detection/batch.js +71 -0
  77. package/dist-cjs/detection/batch.js.map +1 -0
  78. package/dist-cjs/detection/classify.js +48 -0
  79. package/dist-cjs/detection/classify.js.map +1 -0
  80. package/dist-cjs/detection/content.js +122 -0
  81. package/dist-cjs/detection/content.js.map +1 -0
  82. package/dist-cjs/detection/continuity.js +88 -0
  83. package/dist-cjs/detection/continuity.js.map +1 -0
  84. package/dist-cjs/detection/diff.js +193 -0
  85. package/dist-cjs/detection/diff.js.map +1 -0
  86. package/dist-cjs/detection/echo.js +25 -0
  87. package/dist-cjs/detection/echo.js.map +1 -0
  88. package/dist-cjs/detection/enrollment.js +189 -0
  89. package/dist-cjs/detection/enrollment.js.map +1 -0
  90. package/dist-cjs/detection/index.js +57 -0
  91. package/dist-cjs/detection/index.js.map +1 -0
  92. package/dist-cjs/detection/record-proposal.js +170 -0
  93. package/dist-cjs/detection/record-proposal.js.map +1 -0
  94. package/dist-cjs/detection/refusal.js +44 -0
  95. package/dist-cjs/detection/refusal.js.map +1 -0
  96. package/dist-cjs/detection/repository.js +67 -0
  97. package/dist-cjs/detection/repository.js.map +1 -0
  98. package/dist-cjs/detection/territory.js +82 -0
  99. package/dist-cjs/detection/territory.js.map +1 -0
  100. package/dist-cjs/detection/watch-boundary.js +51 -0
  101. package/dist-cjs/detection/watch-boundary.js.map +1 -0
  102. package/dist-cjs/entities/bytes.js +92 -0
  103. package/dist-cjs/entities/bytes.js.map +1 -0
  104. package/dist-cjs/entities/cloud.js +174 -0
  105. package/dist-cjs/entities/cloud.js.map +1 -0
  106. package/dist-cjs/entities/index.js +39 -0
  107. package/dist-cjs/entities/index.js.map +1 -0
  108. package/dist-cjs/entities/moves.js +85 -0
  109. package/dist-cjs/entities/moves.js.map +1 -0
  110. package/dist-cjs/entities/repo-states.js +256 -0
  111. package/dist-cjs/entities/repo-states.js.map +1 -0
  112. package/dist-cjs/entities/rules.js +216 -0
  113. package/dist-cjs/entities/rules.js.map +1 -0
  114. package/dist-cjs/entities/types.js +44 -0
  115. package/dist-cjs/entities/types.js.map +1 -0
  116. package/dist-cjs/files/commands.js +120 -0
  117. package/dist-cjs/files/commands.js.map +1 -0
  118. package/dist-cjs/files/index.js +19 -0
  119. package/dist-cjs/files/index.js.map +1 -0
  120. package/dist-cjs/index.js +39 -0
  121. package/dist-cjs/index.js.map +1 -0
  122. package/dist-cjs/machines/arbitration.js +41 -0
  123. package/dist-cjs/machines/arbitration.js.map +1 -0
  124. package/dist-cjs/machines/backoff.js +38 -0
  125. package/dist-cjs/machines/backoff.js.map +1 -0
  126. package/dist-cjs/machines/bootstrap.js +110 -0
  127. package/dist-cjs/machines/bootstrap.js.map +1 -0
  128. package/dist-cjs/machines/chunks.js +72 -0
  129. package/dist-cjs/machines/chunks.js.map +1 -0
  130. package/dist-cjs/machines/index.js +28 -0
  131. package/dist-cjs/machines/index.js.map +1 -0
  132. package/dist-cjs/machines/presence.js +53 -0
  133. package/dist-cjs/machines/presence.js.map +1 -0
  134. package/dist-cjs/merge/index.js +25 -0
  135. package/dist-cjs/merge/index.js.map +1 -0
  136. package/dist-cjs/merge/merge3.js +191 -0
  137. package/dist-cjs/merge/merge3.js.map +1 -0
  138. package/dist-cjs/package.json +1 -0
  139. package/dist-cjs/records/authority.js +31 -0
  140. package/dist-cjs/records/authority.js.map +1 -0
  141. package/dist-cjs/records/codec.js +48 -0
  142. package/dist-cjs/records/codec.js.map +1 -0
  143. package/dist-cjs/records/contracts.js +121 -0
  144. package/dist-cjs/records/contracts.js.map +1 -0
  145. package/dist-cjs/records/inbox.js +37 -0
  146. package/dist-cjs/records/inbox.js.map +1 -0
  147. package/dist-cjs/records/index.js +23 -0
  148. package/dist-cjs/records/index.js.map +1 -0
  149. package/dist-cjs/records/outbox.js +48 -0
  150. package/dist-cjs/records/outbox.js.map +1 -0
  151. package/dist-cjs/registration/index.js +19 -0
  152. package/dist-cjs/registration/index.js.map +1 -0
  153. package/dist-cjs/registration/user-ground.js +183 -0
  154. package/dist-cjs/registration/user-ground.js.map +1 -0
  155. package/dist-cjs/transfer/artifacts.js +75 -0
  156. package/dist-cjs/transfer/artifacts.js.map +1 -0
  157. package/dist-cjs/transfer/batches.js +44 -0
  158. package/dist-cjs/transfer/batches.js.map +1 -0
  159. package/dist-cjs/transfer/download.js +88 -0
  160. package/dist-cjs/transfer/download.js.map +1 -0
  161. package/dist-cjs/transfer/index.js +21 -0
  162. package/dist-cjs/transfer/index.js.map +1 -0
  163. package/dist-cjs/transfer/parallel.js +35 -0
  164. package/dist-cjs/transfer/parallel.js.map +1 -0
  165. package/dist-cjs/transfer/upload.js +161 -0
  166. package/dist-cjs/transfer/upload.js.map +1 -0
  167. package/dist-cjs/watching/coverage.js +54 -0
  168. package/dist-cjs/watching/coverage.js.map +1 -0
  169. package/dist-cjs/watching/index.js +24 -0
  170. package/dist-cjs/watching/index.js.map +1 -0
  171. package/dist-cjs/watching/suspicion.js +105 -0
  172. package/dist-cjs/watching/suspicion.js.map +1 -0
  173. package/dist-cjs/workspace/api.js +66 -0
  174. package/dist-cjs/workspace/api.js.map +1 -0
  175. package/dist-cjs/workspace/identity.js +32 -0
  176. package/dist-cjs/workspace/identity.js.map +1 -0
  177. package/dist-cjs/workspace/index.js +14 -0
  178. package/dist-cjs/workspace/index.js.map +1 -0
  179. package/dist-cjs/workspace/memory-store.js +21 -0
  180. package/dist-cjs/workspace/memory-store.js.map +1 -0
  181. package/dist-cjs/workspace/registry.js +98 -0
  182. package/dist-cjs/workspace/registry.js.map +1 -0
  183. package/dist-cjs/workspace/types.js +3 -0
  184. package/dist-cjs/workspace/types.js.map +1 -0
  185. package/package.json +30 -8
  186. package/dist/contracts/mutation.d.ts +0 -51
  187. package/dist/contracts/mutation.d.ts.map +0 -1
  188. package/dist/contracts/mutation.js +0 -55
  189. package/dist/contracts/mutation.js.map +0 -1
  190. package/dist/machines/journal.d.ts +0 -63
  191. package/dist/machines/journal.d.ts.map +0 -1
  192. package/dist/machines/journal.js +0 -71
  193. package/dist/machines/journal.js.map +0 -1
  194. package/dist/machines/ordering.d.ts +0 -53
  195. package/dist/machines/ordering.d.ts.map +0 -1
  196. package/dist/machines/ordering.js +0 -87
  197. package/dist/machines/ordering.js.map +0 -1
@@ -1,51 +0,0 @@
1
- /**
2
- * Durable mutations — one edit, one identity, forever.
3
- *
4
- * The hard product invariant (realtime-sdk.md §4, §5): one surface edit
5
- * creates one logical mutation with one `mutationId`, stable across every
6
- * retry, journaled before local materialization, and deduplicated by
7
- * `(resourceId, mutationId)` at every door. Transport may pack, compress,
8
- * or chunk envelopes — it may never merge identities.
9
- *
10
- * After acceptance the authority adds server-derived fields. A
11
- * client-supplied actor, role, official version, or commit time is never
12
- * trusted (realtime-sdk.md §5).
13
- */
14
- import { type Checked } from './validate.js';
15
- export interface LiveMutation<Operation = unknown> {
16
- readonly resourceId: string;
17
- /** Fences writes across authority handoffs: a stale epoch is refused. */
18
- readonly authorityEpoch: number;
19
- /** Stable across retries. A retry never manufactures a second edit. */
20
- readonly mutationId: string;
21
- readonly deviceId: string;
22
- /** The official per-resource version this edit was built against. */
23
- readonly baseVersion: number;
24
- /** Data contract of the operation, e.g. "text-yjs@1". */
25
- readonly contract: string;
26
- readonly operation: Operation;
27
- }
28
- /** Server-derived facts stamped by the authority on acceptance. */
29
- export interface AcceptedMutation<Operation = unknown> extends LiveMutation<Operation> {
30
- readonly actorId: string;
31
- /** Official per-resource version assigned by the authority. */
32
- readonly version: number;
33
- readonly committedAt: number;
34
- }
35
- /**
36
- * Durable mutation state, separate from connection state
37
- * (realtime-sdk.md §7). Terminal states preserve local work: `rejected`
38
- * and `conflicted` never discard the losing side (axiom: never a silent
39
- * winner).
40
- */
41
- export declare const MUTATION_STATES: readonly ["saving-local", "saved-local", "syncing", "synced", "rejected", "conflicted"];
42
- export type MutationState = (typeof MUTATION_STATES)[number];
43
- /**
44
- * The cloud dedupes both entry doors on this key; repeating an accepted
45
- * mutation returns the original ack. NUL-separated: ids may contain any
46
- * printable character, so a printable separator could collide two
47
- * different identities.
48
- */
49
- export declare const mutationKey: (m: Pick<LiveMutation, "resourceId" | "mutationId">) => string;
50
- export declare function checkLiveMutation(input: unknown): Checked<LiveMutation>;
51
- //# sourceMappingURL=mutation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mutation.d.ts","sourceRoot":"","sources":["../../src/contracts/mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAsD,MAAM,eAAe,CAAC;AAEjG,MAAM,WAAW,YAAY,CAAC,SAAS,GAAG,OAAO;IAC/C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAED,mEAAmE;AACnE,MAAM,WAAW,gBAAgB,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC,SAAS,CAAC;IACpF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,yFAOlB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,GAAG,IAAI,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY,CAAC,KAAG,MACzC,CAAC;AAKzC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAevE"}
@@ -1,55 +0,0 @@
1
- /**
2
- * Durable mutations — one edit, one identity, forever.
3
- *
4
- * The hard product invariant (realtime-sdk.md §4, §5): one surface edit
5
- * creates one logical mutation with one `mutationId`, stable across every
6
- * retry, journaled before local materialization, and deduplicated by
7
- * `(resourceId, mutationId)` at every door. Transport may pack, compress,
8
- * or chunk envelopes — it may never merge identities.
9
- *
10
- * After acceptance the authority adds server-derived fields. A
11
- * client-supplied actor, role, official version, or commit time is never
12
- * trusted (realtime-sdk.md §5).
13
- */
14
- import { pass, failShape, isRecord, isNonEmptyString, isSeq } from './validate.js';
15
- /**
16
- * Durable mutation state, separate from connection state
17
- * (realtime-sdk.md §7). Terminal states preserve local work: `rejected`
18
- * and `conflicted` never discard the losing side (axiom: never a silent
19
- * winner).
20
- */
21
- export const MUTATION_STATES = [
22
- 'saving-local', // selected journal is persisting the edit
23
- 'saved-local', // journal contains it; runtime-routed edits are also materialized
24
- 'syncing', // leased/pending in the outbox view
25
- 'synced', // cloud accepted and assigned the official version
26
- 'rejected', // cloud refused (permission/schema); local work preserved
27
- 'conflicted', // contract requires an explicit merge decision; both sides survive
28
- ];
29
- /**
30
- * The cloud dedupes both entry doors on this key; repeating an accepted
31
- * mutation returns the original ack. NUL-separated: ids may contain any
32
- * printable character, so a printable separator could collide two
33
- * different identities.
34
- */
35
- export const mutationKey = (m) => `${m.resourceId}\u0000${m.mutationId}`;
36
- const EXAMPLE = '{ resourceId: "r1", authorityEpoch: 1, mutationId: "m-7", deviceId: "d1", baseVersion: 12, contract: "text-yjs@1", operation: {...} }';
37
- export function checkLiveMutation(input) {
38
- if (!isRecord(input))
39
- return failShape(EXAMPLE, `got ${input === null ? 'null' : typeof input}`);
40
- for (const field of ['resourceId', 'mutationId', 'deviceId', 'contract']) {
41
- if (!isNonEmptyString(input[field])) {
42
- return failShape(EXAMPLE, `${field} was ${JSON.stringify(input[field])}, not a non-empty string`);
43
- }
44
- }
45
- if (!isSeq(input.authorityEpoch)) {
46
- return failShape(EXAMPLE, `authorityEpoch was ${JSON.stringify(input.authorityEpoch)}, not a non-negative integer`);
47
- }
48
- if (!isSeq(input.baseVersion)) {
49
- return failShape(EXAMPLE, `baseVersion was ${JSON.stringify(input.baseVersion)}, not a non-negative integer`);
50
- }
51
- if (!('operation' in input))
52
- return failShape(EXAMPLE, 'operation was missing');
53
- return pass(input);
54
- }
55
- //# sourceMappingURL=mutation.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mutation.js","sourceRoot":"","sources":["../../src/contracts/mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAgB,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAwBjG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,cAAc,EAAE,0CAA0C;IAC1D,aAAa,EAAE,kEAAkE;IACjF,SAAS,EAAE,oCAAoC;IAC/C,QAAQ,EAAE,mDAAmD;IAC7D,UAAU,EAAE,0DAA0D;IACtE,YAAY,EAAE,mEAAmE;CACzE,CAAC;AAGX;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAkD,EAAU,EAAE,CACxF,GAAG,CAAC,CAAC,UAAU,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC;AAEzC,MAAM,OAAO,GACX,uIAAuI,CAAC;AAE1I,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC,OAAO,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;IACjG,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,CAAU,EAAE,CAAC;QAClF,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACpC,OAAO,SAAS,CAAC,OAAO,EAAE,GAAG,KAAK,QAAQ,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,0BAA0B,CAAC,CAAC;QACpG,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,SAAS,CAAC,OAAO,EAAE,sBAAsB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,cAAc,CAAC,8BAA8B,CAAC,CAAC;IACtH,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC,OAAO,EAAE,mBAAmB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC;IAChH,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,KAAgC,CAAC,CAAC;AAChD,CAAC"}
@@ -1,63 +0,0 @@
1
- /**
2
- * The mutation journal machine — journal first, materialize second.
3
- *
4
- * The hard rule (cloud-mutation-discipline.md): one SDK commit creates one
5
- * durable mutation identity; the journal row is written BEFORE the local
6
- * materialization, and that same row is the cloud outbox record. There is
7
- * no second outgoing table and no contract-specific retry loop.
8
- *
9
- * This machine owns the state transitions and their legality. The host
10
- * supplies the durable store through the `MutationJournalStore` port and
11
- * performs the actual materialization and network submission; the cloud
12
- * pump drives `claim → synced/rejected/conflicted`.
13
- */
14
- import { type LiveMutation, type MutationState } from '../contracts/mutation.js';
15
- export interface JournalRow<Operation = unknown> {
16
- readonly mutation: LiveMutation<Operation>;
17
- readonly state: MutationState;
18
- /** Set once the cloud assigns the official per-resource version. */
19
- readonly officialVersion?: number;
20
- /** Present on `rejected`/`conflicted`; local work is preserved either way. */
21
- readonly reason?: string;
22
- }
23
- /** The durable store port. Every method is synchronous from the machine's view; a host may back it with SQLite, IndexedDB, or memory. */
24
- export interface MutationJournalStore<Operation = unknown> {
25
- read(key: string): JournalRow<Operation> | null;
26
- write(key: string, row: JournalRow<Operation>): void;
27
- /** The outbox is a filtered view of this journal — never a second table. */
28
- pendingShared(): readonly JournalRow<Operation>[];
29
- }
30
- export type JournalDecision<Operation = unknown> =
31
- /** New identity: the row is journaled; the host must now materialize, then call `advance(key, 'saved-local')`. */
32
- {
33
- readonly outcome: 'journaled';
34
- readonly row: JournalRow<Operation>;
35
- }
36
- /** Same `(resourceId, mutationId)` seen before: return the existing row — a retry never creates a second edit. */
37
- | {
38
- readonly outcome: 'duplicate';
39
- readonly row: JournalRow<Operation>;
40
- };
41
- export declare class MutationJournal<Operation = unknown> {
42
- private readonly store;
43
- constructor(store: MutationJournalStore<Operation>);
44
- /** SDK commit: journal the mutation before anything else happens. Idempotent by mutation identity. */
45
- commit(mutation: LiveMutation<Operation>): JournalDecision<Operation>;
46
- /**
47
- * Advance a mutation's state along the discipline's order. An illegal
48
- * transition throws — it is a programming error in the host, not a wire
49
- * condition, and hiding it would corrupt the journal's meaning.
50
- */
51
- advance(key: string, to: MutationState, detail?: {
52
- officialVersion?: number;
53
- reason?: string;
54
- }): JournalRow<Operation>;
55
- /**
56
- * Crash recovery: an unfinished materialization is resumed from the
57
- * journal already on disk — rows still `saving-local` need their
58
- * materialization re-applied (idempotently), rows `saved-local` and
59
- * later resume from the pump.
60
- */
61
- unfinishedMaterializations(): readonly JournalRow<Operation>[];
62
- }
63
- //# sourceMappingURL=journal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/machines/journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAe,MAAM,0BAA0B,CAAC;AAE9F,MAAM,WAAW,UAAU,CAAC,SAAS,GAAG,OAAO;IAC7C,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,yIAAyI;AACzI,MAAM,WAAW,oBAAoB,CAAC,SAAS,GAAG,OAAO;IACvD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACrD,4EAA4E;IAC5E,aAAa,IAAI,SAAS,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;CACnD;AAWD,MAAM,MAAM,eAAe,CAAC,SAAS,GAAG,OAAO;AAC7C,kHAAkH;AAChH;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;CAAE;AACxE,kHAAkH;GAChH;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC;AAE3E,qBAAa,eAAe,CAAC,SAAS,GAAG,OAAO;IAClC,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,oBAAoB,CAAC,SAAS,CAAC;IAEnE,sGAAsG;IACtG,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC;IASrE;;;;OAIG;IACH,OAAO,CACL,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,aAAa,EACjB,MAAM,GAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAO,GACzD,UAAU,CAAC,SAAS,CAAC;IAqBxB;;;;;OAKG;IACH,0BAA0B,IAAI,SAAS,UAAU,CAAC,SAAS,CAAC,EAAE;CAG/D"}
@@ -1,71 +0,0 @@
1
- /**
2
- * The mutation journal machine — journal first, materialize second.
3
- *
4
- * The hard rule (cloud-mutation-discipline.md): one SDK commit creates one
5
- * durable mutation identity; the journal row is written BEFORE the local
6
- * materialization, and that same row is the cloud outbox record. There is
7
- * no second outgoing table and no contract-specific retry loop.
8
- *
9
- * This machine owns the state transitions and their legality. The host
10
- * supplies the durable store through the `MutationJournalStore` port and
11
- * performs the actual materialization and network submission; the cloud
12
- * pump drives `claim → synced/rejected/conflicted`.
13
- */
14
- import { mutationKey } from '../contracts/mutation.js';
15
- const LEGAL = {
16
- 'saving-local': ['saved-local'],
17
- 'saved-local': ['syncing'],
18
- syncing: ['synced', 'rejected', 'conflicted', 'saved-local'], // saved-local: a lease expired; the pump re-claims
19
- synced: [],
20
- rejected: [],
21
- conflicted: [],
22
- };
23
- export class MutationJournal {
24
- store;
25
- constructor(store) {
26
- this.store = store;
27
- }
28
- /** SDK commit: journal the mutation before anything else happens. Idempotent by mutation identity. */
29
- commit(mutation) {
30
- const key = mutationKey(mutation);
31
- const existing = this.store.read(key);
32
- if (existing)
33
- return { outcome: 'duplicate', row: existing };
34
- const row = { mutation, state: 'saving-local' };
35
- this.store.write(key, row);
36
- return { outcome: 'journaled', row };
37
- }
38
- /**
39
- * Advance a mutation's state along the discipline's order. An illegal
40
- * transition throws — it is a programming error in the host, not a wire
41
- * condition, and hiding it would corrupt the journal's meaning.
42
- */
43
- advance(key, to, detail = {}) {
44
- const row = this.store.read(key);
45
- if (!row) {
46
- throw new Error(`no journal row for "${key}" — commit() the mutation before advancing it`);
47
- }
48
- if (!LEGAL[row.state].includes(to)) {
49
- throw new Error(`illegal journal transition "${row.state}" → "${to}" for "${key}" — ` +
50
- `the order is saving-local → saved-local → syncing → synced|rejected|conflicted`);
51
- }
52
- const next = {
53
- mutation: row.mutation,
54
- state: to,
55
- ...(detail.officialVersion !== undefined ? { officialVersion: detail.officialVersion } : {}),
56
- ...(detail.reason !== undefined ? { reason: detail.reason } : {}),
57
- };
58
- this.store.write(key, next);
59
- return next;
60
- }
61
- /**
62
- * Crash recovery: an unfinished materialization is resumed from the
63
- * journal already on disk — rows still `saving-local` need their
64
- * materialization re-applied (idempotently), rows `saved-local` and
65
- * later resume from the pump.
66
- */
67
- unfinishedMaterializations() {
68
- return this.store.pendingShared().filter((row) => row.state === 'saving-local');
69
- }
70
- }
71
- //# sourceMappingURL=journal.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/machines/journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAyC,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAmB9F,MAAM,KAAK,GAA8D;IACvE,cAAc,EAAE,CAAC,aAAa,CAAC;IAC/B,aAAa,EAAE,CAAC,SAAS,CAAC;IAC1B,OAAO,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,CAAC,EAAE,mDAAmD;IACjH,MAAM,EAAE,EAAE;IACV,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,EAAE;CACf,CAAC;AAQF,MAAM,OAAO,eAAe;IACG;IAA7B,YAA6B,KAAsC;QAAtC,UAAK,GAAL,KAAK,CAAiC;IAAG,CAAC;IAEvE,sGAAsG;IACtG,MAAM,CAAC,QAAiC;QACtC,MAAM,GAAG,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,QAAQ;YAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;QAC7D,MAAM,GAAG,GAA0B,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QACvE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC3B,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;IACvC,CAAC;IAED;;;;OAIG;IACH,OAAO,CACL,GAAW,EACX,EAAiB,EACjB,SAAwD,EAAE;QAE1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,uBAAuB,GAAG,+CAA+C,CAAC,CAAC;QAC7F,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,+BAA+B,GAAG,CAAC,KAAK,QAAQ,EAAE,UAAU,GAAG,MAAM;gBACnE,gFAAgF,CACnF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAA0B;YAClC,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,EAAE;YACT,GAAG,CAAC,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5F,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClE,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,0BAA0B;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC;IAClF,CAAC;CACF"}
@@ -1,53 +0,0 @@
1
- /**
2
- * The sequence ledger — ordered, gap-free application of state events.
3
- *
4
- * Client obligations (local-live-protocol.md §6): never re-apply an event
5
- * at or below the applied seq; on a gap, run exactly one backfill at a
6
- * time (`GET /state/events?after=`); on backfill failure or a `reset`
7
- * frame, converge on a full re-sync. Every decision is returned as data —
8
- * the host performs the fetches.
9
- */
10
- import type { StateEvent } from '../contracts/events.js';
11
- export type LedgerDecision =
12
- /** In order: apply to local state, advance the ledger. */
13
- {
14
- readonly action: 'apply';
15
- readonly event: StateEvent;
16
- }
17
- /** At or below the applied seq: drop silently (duplicate delivery is normal). */
18
- | {
19
- readonly action: 'skip-duplicate';
20
- readonly event: StateEvent;
21
- }
22
- /** A gap opened. Run one backfill after `after`; the event is buffered and will replay once the gap closes. */
23
- | {
24
- readonly action: 'backfill';
25
- readonly after: number;
26
- readonly buffered: StateEvent;
27
- }
28
- /** A backfill is already in flight: buffer only (single-flight obligation). */
29
- | {
30
- readonly action: 'buffer';
31
- readonly buffered: StateEvent;
32
- };
33
- export declare class SequenceLedger {
34
- #private;
35
- constructor(appliedSeq: number);
36
- get appliedSeq(): number;
37
- get backfilling(): boolean;
38
- /** Feed one live event; act on the returned decision. */
39
- accept(event: StateEvent): LedgerDecision;
40
- /**
41
- * Deliver the backfill body. Returns the events to apply, in order,
42
- * merged with everything buffered while the backfill was in flight.
43
- * Backfilled and buffered ranges may overlap; the ledger dedupes by seq.
44
- */
45
- completeBackfill(events: readonly StateEvent[]): StateEvent[];
46
- /** Whether `completeBackfill` left the ledger still gapped — the caller must re-sync. */
47
- needsResync(nextBufferedSeq?: number): boolean;
48
- /** Backfill failed, or a `reset` frame arrived: drop everything and let the caller re-snapshot. */
49
- abandonToResync(): void;
50
- /** A full snapshot installed at `seq` supersedes anything older. */
51
- resumeFrom(seq: number): void;
52
- }
53
- //# sourceMappingURL=ordering.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ordering.d.ts","sourceRoot":"","sources":["../../src/machines/ordering.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,MAAM,cAAc;AACxB,0DAA0D;AACxD;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE;AAC1D,iFAAiF;GAC/E;IAAE,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE;AACnE,+GAA+G;GAC7G;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAA;CAAE;AACxF,+EAA+E;GAC7E;IAAE,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAA;CAAE,CAAC;AAEjE,qBAAa,cAAc;;gBAKb,UAAU,EAAE,MAAM;IAI9B,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED,yDAAyD;IACzD,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc;IAezC;;;;OAIG;IACH,gBAAgB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE;IAmB7D,yFAAyF;IACzF,WAAW,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO;IAI9C,mGAAmG;IACnG,eAAe,IAAI,IAAI;IAKvB,oEAAoE;IACpE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAY9B"}
@@ -1,87 +0,0 @@
1
- /**
2
- * The sequence ledger — ordered, gap-free application of state events.
3
- *
4
- * Client obligations (local-live-protocol.md §6): never re-apply an event
5
- * at or below the applied seq; on a gap, run exactly one backfill at a
6
- * time (`GET /state/events?after=`); on backfill failure or a `reset`
7
- * frame, converge on a full re-sync. Every decision is returned as data —
8
- * the host performs the fetches.
9
- */
10
- export class SequenceLedger {
11
- #appliedSeq;
12
- #backfilling = false;
13
- #buffer = [];
14
- constructor(appliedSeq) {
15
- this.#appliedSeq = appliedSeq;
16
- }
17
- get appliedSeq() {
18
- return this.#appliedSeq;
19
- }
20
- get backfilling() {
21
- return this.#backfilling;
22
- }
23
- /** Feed one live event; act on the returned decision. */
24
- accept(event) {
25
- if (event.seq <= this.#appliedSeq)
26
- return { action: 'skip-duplicate', event };
27
- if (this.#backfilling) {
28
- this.#insertBuffered(event);
29
- return { action: 'buffer', buffered: event };
30
- }
31
- if (event.seq === this.#appliedSeq + 1) {
32
- this.#appliedSeq = event.seq;
33
- return { action: 'apply', event };
34
- }
35
- this.#backfilling = true;
36
- this.#insertBuffered(event);
37
- return { action: 'backfill', after: this.#appliedSeq, buffered: event };
38
- }
39
- /**
40
- * Deliver the backfill body. Returns the events to apply, in order,
41
- * merged with everything buffered while the backfill was in flight.
42
- * Backfilled and buffered ranges may overlap; the ledger dedupes by seq.
43
- */
44
- completeBackfill(events) {
45
- this.#backfilling = false;
46
- const merged = [...events, ...this.#buffer].sort((a, b) => a.seq - b.seq);
47
- this.#buffer = [];
48
- const toApply = [];
49
- for (const event of merged) {
50
- if (event.seq <= this.#appliedSeq)
51
- continue;
52
- if (event.seq !== this.#appliedSeq + 1) {
53
- // The backfill itself was gappy — the buffer cannot repair it.
54
- // Converge on the recovery rule: full re-sync.
55
- this.#buffer = [];
56
- return toApply;
57
- }
58
- this.#appliedSeq = event.seq;
59
- toApply.push(event);
60
- }
61
- return toApply;
62
- }
63
- /** Whether `completeBackfill` left the ledger still gapped — the caller must re-sync. */
64
- needsResync(nextBufferedSeq) {
65
- return nextBufferedSeq !== undefined && nextBufferedSeq > this.#appliedSeq + 1;
66
- }
67
- /** Backfill failed, or a `reset` frame arrived: drop everything and let the caller re-snapshot. */
68
- abandonToResync() {
69
- this.#backfilling = false;
70
- this.#buffer = [];
71
- }
72
- /** A full snapshot installed at `seq` supersedes anything older. */
73
- resumeFrom(seq) {
74
- this.#appliedSeq = seq;
75
- this.#backfilling = false;
76
- this.#buffer = this.#buffer.filter((event) => event.seq > seq);
77
- }
78
- #insertBuffered(event) {
79
- // Keep the buffer sorted and deduped; delivery may repeat frames.
80
- const at = this.#buffer.findIndex((held) => held.seq >= event.seq);
81
- if (at === -1)
82
- this.#buffer.push(event);
83
- else if (this.#buffer[at].seq !== event.seq)
84
- this.#buffer.splice(at, 0, event);
85
- }
86
- }
87
- //# sourceMappingURL=ordering.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ordering.js","sourceRoot":"","sources":["../../src/machines/ordering.ts"],"names":[],"mappings":"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"}