@owlmeans/server-planning 0.1.18-rc.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 (174) hide show
  1. package/README.md +150 -0
  2. package/agent-meta/manifest.json +16 -0
  3. package/agent-meta/skills/server-planning/SKILL.md +203 -0
  4. package/build/actions/cards.d.ts +16 -0
  5. package/build/actions/cards.d.ts.map +1 -0
  6. package/build/actions/cards.js +32 -0
  7. package/build/actions/cards.js.map +1 -0
  8. package/build/actions/commit.d.ts +14 -0
  9. package/build/actions/commit.d.ts.map +1 -0
  10. package/build/actions/commit.js +48 -0
  11. package/build/actions/commit.js.map +1 -0
  12. package/build/actions/execute.d.ts +13 -0
  13. package/build/actions/execute.d.ts.map +1 -0
  14. package/build/actions/execute.js +35 -0
  15. package/build/actions/execute.js.map +1 -0
  16. package/build/actions/index.d.ts +9 -0
  17. package/build/actions/index.d.ts.map +1 -0
  18. package/build/actions/index.js +9 -0
  19. package/build/actions/index.js.map +1 -0
  20. package/build/actions/links.d.ts +5 -0
  21. package/build/actions/links.d.ts.map +1 -0
  22. package/build/actions/links.js +8 -0
  23. package/build/actions/links.js.map +1 -0
  24. package/build/actions/schemas.d.ts +6 -0
  25. package/build/actions/schemas.d.ts.map +1 -0
  26. package/build/actions/schemas.js +9 -0
  27. package/build/actions/schemas.js.map +1 -0
  28. package/build/actions/specs.d.ts +10 -0
  29. package/build/actions/specs.d.ts.map +1 -0
  30. package/build/actions/specs.js +14 -0
  31. package/build/actions/specs.js.map +1 -0
  32. package/build/actions/transitions.d.ts +6 -0
  33. package/build/actions/transitions.d.ts.map +1 -0
  34. package/build/actions/transitions.js +8 -0
  35. package/build/actions/transitions.js.map +1 -0
  36. package/build/actions/watch.d.ts +12 -0
  37. package/build/actions/watch.d.ts.map +1 -0
  38. package/build/actions/watch.js +45 -0
  39. package/build/actions/watch.js.map +1 -0
  40. package/build/consts.d.ts +18 -0
  41. package/build/consts.d.ts.map +1 -0
  42. package/build/consts.js +19 -0
  43. package/build/consts.js.map +1 -0
  44. package/build/executor/changes.d.ts +31 -0
  45. package/build/executor/changes.d.ts.map +1 -0
  46. package/build/executor/changes.js +55 -0
  47. package/build/executor/changes.js.map +1 -0
  48. package/build/executor/code.d.ts +15 -0
  49. package/build/executor/code.d.ts.map +1 -0
  50. package/build/executor/code.js +59 -0
  51. package/build/executor/code.js.map +1 -0
  52. package/build/executor/receipt.d.ts +12 -0
  53. package/build/executor/receipt.d.ts.map +1 -0
  54. package/build/executor/receipt.js +56 -0
  55. package/build/executor/receipt.js.map +1 -0
  56. package/build/executor/resolve.d.ts +35 -0
  57. package/build/executor/resolve.d.ts.map +1 -0
  58. package/build/executor/resolve.js +136 -0
  59. package/build/executor/resolve.js.map +1 -0
  60. package/build/executor/validate.d.ts +13 -0
  61. package/build/executor/validate.d.ts.map +1 -0
  62. package/build/executor/validate.js +222 -0
  63. package/build/executor/validate.js.map +1 -0
  64. package/build/executor.d.ts +15 -0
  65. package/build/executor.d.ts.map +1 -0
  66. package/build/executor.js +113 -0
  67. package/build/executor.js.map +1 -0
  68. package/build/facade.d.ts +12 -0
  69. package/build/facade.d.ts.map +1 -0
  70. package/build/facade.js +131 -0
  71. package/build/facade.js.map +1 -0
  72. package/build/helper.d.ts +18 -0
  73. package/build/helper.d.ts.map +1 -0
  74. package/build/helper.js +32 -0
  75. package/build/helper.js.map +1 -0
  76. package/build/index.d.ts +13 -0
  77. package/build/index.d.ts.map +1 -0
  78. package/build/index.js +11 -0
  79. package/build/index.js.map +1 -0
  80. package/build/projection.d.ts +28 -0
  81. package/build/projection.d.ts.map +1 -0
  82. package/build/projection.js +40 -0
  83. package/build/projection.js.map +1 -0
  84. package/build/registry.d.ts +30 -0
  85. package/build/registry.d.ts.map +1 -0
  86. package/build/registry.js +103 -0
  87. package/build/registry.js.map +1 -0
  88. package/build/service.d.ts +40 -0
  89. package/build/service.d.ts.map +1 -0
  90. package/build/service.js +109 -0
  91. package/build/service.js.map +1 -0
  92. package/build/store/commits.d.ts +15 -0
  93. package/build/store/commits.d.ts.map +1 -0
  94. package/build/store/commits.js +147 -0
  95. package/build/store/commits.js.map +1 -0
  96. package/build/store/composite.d.ts +12 -0
  97. package/build/store/composite.d.ts.map +1 -0
  98. package/build/store/composite.js +150 -0
  99. package/build/store/composite.js.map +1 -0
  100. package/build/store/fold.d.ts +39 -0
  101. package/build/store/fold.d.ts.map +1 -0
  102. package/build/store/fold.js +220 -0
  103. package/build/store/fold.js.map +1 -0
  104. package/build/store/index.d.ts +6 -0
  105. package/build/store/index.d.ts.map +1 -0
  106. package/build/store/index.js +5 -0
  107. package/build/store/index.js.map +1 -0
  108. package/build/store/memory.d.ts +19 -0
  109. package/build/store/memory.d.ts.map +1 -0
  110. package/build/store/memory.js +0 -0
  111. package/build/store/memory.js.map +1 -0
  112. package/build/store/types.d.ts +82 -0
  113. package/build/store/types.d.ts.map +1 -0
  114. package/build/store/types.js +2 -0
  115. package/build/store/types.js.map +1 -0
  116. package/build/types.d.ts +46 -0
  117. package/build/types.d.ts.map +1 -0
  118. package/build/types.js +2 -0
  119. package/build/types.js.map +1 -0
  120. package/build/utils/guard.d.ts +19 -0
  121. package/build/utils/guard.d.ts.map +1 -0
  122. package/build/utils/guard.js +35 -0
  123. package/build/utils/guard.js.map +1 -0
  124. package/build/utils/index.d.ts +3 -0
  125. package/build/utils/index.d.ts.map +1 -0
  126. package/build/utils/index.js +3 -0
  127. package/build/utils/index.js.map +1 -0
  128. package/build/utils/scope.d.ts +20 -0
  129. package/build/utils/scope.d.ts.map +1 -0
  130. package/build/utils/scope.js +36 -0
  131. package/build/utils/scope.js.map +1 -0
  132. package/package.json +66 -0
  133. package/src/actions/cards.ts +52 -0
  134. package/src/actions/commit.ts +55 -0
  135. package/src/actions/execute.ts +47 -0
  136. package/src/actions/index.ts +8 -0
  137. package/src/actions/links.ts +14 -0
  138. package/src/actions/schemas.ts +15 -0
  139. package/src/actions/specs.ts +23 -0
  140. package/src/actions/transitions.ts +14 -0
  141. package/src/actions/watch.ts +52 -0
  142. package/src/consts.ts +22 -0
  143. package/src/executor/changes.ts +78 -0
  144. package/src/executor/code.ts +83 -0
  145. package/src/executor/receipt.ts +66 -0
  146. package/src/executor/resolve.ts +174 -0
  147. package/src/executor/validate.ts +253 -0
  148. package/src/executor.ts +149 -0
  149. package/src/facade.ts +162 -0
  150. package/src/helper.ts +44 -0
  151. package/src/index.ts +13 -0
  152. package/src/projection.ts +65 -0
  153. package/src/registry.ts +143 -0
  154. package/src/service.ts +157 -0
  155. package/src/store/commits.ts +174 -0
  156. package/src/store/composite.ts +171 -0
  157. package/src/store/fold.ts +257 -0
  158. package/src/store/index.ts +6 -0
  159. package/src/store/memory.ts +0 -0
  160. package/src/store/types.ts +94 -0
  161. package/src/types.ts +48 -0
  162. package/src/utils/guard.ts +40 -0
  163. package/src/utils/index.ts +2 -0
  164. package/src/utils/scope.ts +51 -0
  165. package/tests/commits.spec.ts +78 -0
  166. package/tests/context.ts +198 -0
  167. package/tests/entrypoints.spec.ts +72 -0
  168. package/tests/executor.spec.ts +69 -0
  169. package/tests/memory-store.spec.ts +84 -0
  170. package/tests/plugins.spec.ts +86 -0
  171. package/tests/specifications.spec.ts +61 -0
  172. package/tests/tsconfig.json +17 -0
  173. package/tests/validation.spec.ts +62 -0
  174. package/tsconfig.json +16 -0
@@ -0,0 +1,15 @@
1
+ import type { CommitHub, CommitHubOptions } from './types.js';
2
+ /**
3
+ * An in-process commit fan-out with a status lookup.
4
+ *
5
+ * It is the `CommitSource` a store answers with: the memory store publishes into it from its fold,
6
+ * and a durable store feeds it from its own bus (a Redis subscription) while answering `status`
7
+ * from its transition rows. It never decides anything about a commit — it only delivers events and
8
+ * waits for them.
9
+ *
10
+ * `wait` subscribes FIRST and polls second, so a commit that lands between the two is never
11
+ * missed; after one immediate poll it climbs `ladder`, which is what answers when the fold
12
+ * published somewhere this hub does not hear.
13
+ */
14
+ export declare const makeCommitHub: (options: CommitHubOptions) => CommitHub;
15
+ //# sourceMappingURL=commits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../../src/store/commits.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAiB7D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,YAAa,gBAAgB,KAAG,SA6IzD,CAAA"}
@@ -0,0 +1,147 @@
1
+ import { CommitFailed, CommitState, CommitTimeout, DEFAULT_COMMIT_TIMEOUT, WorkcardNotFound } from '@owlmeans/planning';
2
+ import { COMMIT_POLL_LADDER, DEFAULT_COMMIT_MEMORY } from '../consts.js';
3
+ const matches = (event, filter) => filter == null || ((filter.entityId == null || filter.entityId === event.entityId)
4
+ && (filter.project == null || filter.project === event.project)
5
+ && (filter.card == null || filter.card === event.card)
6
+ && (filter.kind == null || filter.kind === event.kind));
7
+ const settled = (state) => state !== CommitState.Pending;
8
+ const failureOf = (transition, error) => new CommitFailed(`${transition}:${error ?? 'unknown'}`);
9
+ /**
10
+ * An in-process commit fan-out with a status lookup.
11
+ *
12
+ * It is the `CommitSource` a store answers with: the memory store publishes into it from its fold,
13
+ * and a durable store feeds it from its own bus (a Redis subscription) while answering `status`
14
+ * from its transition rows. It never decides anything about a commit — it only delivers events and
15
+ * waits for them.
16
+ *
17
+ * `wait` subscribes FIRST and polls second, so a commit that lands between the two is never
18
+ * missed; after one immediate poll it climbs `ladder`, which is what answers when the fold
19
+ * published somewhere this hub does not hear.
20
+ */
21
+ export const makeCommitHub = (options) => {
22
+ const listeners = new Set();
23
+ const memory = new Map();
24
+ const remember = options.remember ?? DEFAULT_COMMIT_MEMORY;
25
+ const ladder = options.ladder != null && options.ladder.length > 0 ? options.ladder : COMMIT_POLL_LADDER;
26
+ const remembered = (event) => {
27
+ if (!settled(event.state) || remember <= 0) {
28
+ return;
29
+ }
30
+ memory.delete(event.transition);
31
+ memory.set(event.transition, event);
32
+ while (memory.size > remember) {
33
+ const oldest = memory.keys().next().value;
34
+ if (oldest == null) {
35
+ break;
36
+ }
37
+ memory.delete(oldest);
38
+ }
39
+ };
40
+ const hub = {
41
+ publish: async (event) => {
42
+ remembered(event);
43
+ const targets = [...listeners].filter(entry => matches(event, entry.filter));
44
+ const results = await Promise.allSettled(targets.map(async (entry) => await entry.listener(event)));
45
+ results.forEach(result => {
46
+ if (result.status === 'rejected') {
47
+ console.error('planning: commit listener failed:', result.reason);
48
+ }
49
+ });
50
+ },
51
+ recall: transition => memory.get(transition),
52
+ listeners: () => listeners.size,
53
+ subscribe: (listener, filter) => {
54
+ const entry = { listener, filter };
55
+ listeners.add(entry);
56
+ const unsubscribe = () => { listeners.delete(entry); };
57
+ return unsubscribe;
58
+ },
59
+ status: async (transition) => {
60
+ const found = await options.status(transition);
61
+ if (found != null) {
62
+ return found;
63
+ }
64
+ const event = memory.get(transition);
65
+ if (event != null) {
66
+ const status = { transition, state: event.state, at: event.at };
67
+ if (event.error != null) {
68
+ status.error = event.error;
69
+ }
70
+ if (event.record !== undefined) {
71
+ status.card = event.record;
72
+ }
73
+ return status;
74
+ }
75
+ throw new WorkcardNotFound(`transition:${transition}`);
76
+ },
77
+ wait: async (transition, opts) => {
78
+ const timeout = opts?.timeout ?? DEFAULT_COMMIT_TIMEOUT;
79
+ return await new Promise((resolve, reject) => {
80
+ let done = false;
81
+ let step = 0;
82
+ let poller;
83
+ let unsubscribe = () => undefined;
84
+ const finish = (settle) => {
85
+ if (done) {
86
+ return;
87
+ }
88
+ done = true;
89
+ clearTimeout(deadline);
90
+ clearTimeout(poller);
91
+ unsubscribe();
92
+ settle();
93
+ };
94
+ const committedCard = async (record) => {
95
+ if (record !== undefined) {
96
+ return record;
97
+ }
98
+ try {
99
+ return (await hub.status(transition)).card ?? null;
100
+ }
101
+ catch {
102
+ return null;
103
+ }
104
+ };
105
+ const answer = async (state, error, record) => {
106
+ if (state === CommitState.Committed) {
107
+ const card = await committedCard(record);
108
+ finish(() => resolve(card));
109
+ return true;
110
+ }
111
+ if (state === CommitState.Failed) {
112
+ finish(() => reject(failureOf(transition, error)));
113
+ return true;
114
+ }
115
+ return false;
116
+ };
117
+ const deadline = setTimeout(() => finish(() => reject(new CommitTimeout(transition))), timeout);
118
+ unsubscribe = hub.subscribe(async (event) => {
119
+ if (event.transition === transition) {
120
+ await answer(event.state, event.error, event.record);
121
+ }
122
+ });
123
+ const poll = async () => {
124
+ if (done) {
125
+ return;
126
+ }
127
+ try {
128
+ const status = await hub.status(transition);
129
+ if (await answer(status.state, status.error, status.card)) {
130
+ return;
131
+ }
132
+ }
133
+ catch (error) {
134
+ finish(() => reject(error));
135
+ return;
136
+ }
137
+ if (!done) {
138
+ poller = setTimeout(() => { void poll(); }, ladder[Math.min(step++, ladder.length - 1)]);
139
+ }
140
+ };
141
+ void poll();
142
+ });
143
+ },
144
+ };
145
+ return hub;
146
+ };
147
+ //# sourceMappingURL=commits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commits.js","sourceRoot":"","sources":["../../src/store/commits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAEvH,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAKxE,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAE,MAAqB,EAAW,EAAE,CACrE,MAAM,IAAI,IAAI,IAAI,CAChB,CAAC,MAAM,CAAC,QAAQ,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC;OAC5D,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,CAAC;OAC5D,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC;OACnD,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CACvD,CAAA;AAEH,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAW,EAAE,CAAC,KAAK,KAAK,WAAW,CAAC,OAAO,CAAA;AAE9E,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,KAAc,EAAgB,EAAE,CACrE,IAAI,YAAY,CAAC,GAAG,UAAU,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC,CAAA;AAEzD;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,OAAyB,EAAa,EAAE;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiD,CAAA;IAC1E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,qBAAqB,CAAA;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAA;IAExG,MAAM,UAAU,GAAG,CAAC,KAAkB,EAAQ,EAAE;QAC9C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAC3C,OAAM;QACR,CAAC;QACD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;QAC/B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;QACnC,OAAO,MAAM,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAA;YACzC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,MAAK;YACP,CAAC;YACD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,GAAG,GAAc;QACrB,OAAO,EAAE,KAAK,EAAC,KAAK,EAAC,EAAE;YACrB,UAAU,CAAC,KAAK,CAAC,CAAA;YACjB,MAAM,OAAO,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;YAC5E,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE,CAAC,MAAM,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACjG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBACvB,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBACjC,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;gBACnE,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QAE5C,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI;QAE/B,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;YAClC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YAEpB,MAAM,WAAW,GAAgB,GAAG,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,CAAC,CAAC,CAAA;YAClE,OAAO,WAAW,CAAA;QACpB,CAAC;QAED,MAAM,EAAE,KAAK,EAAC,UAAU,EAAC,EAAE;YACzB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;YAC9C,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,OAAO,KAAK,CAAA;YACd,CAAC;YACD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;YACpC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAiB,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAA;gBAC7E,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;oBACxB,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;gBAC5B,CAAC;gBACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAC/B,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,CAAA;gBAC5B,CAAC;gBACD,OAAO,MAAM,CAAA;YACf,CAAC;YAED,MAAM,IAAI,gBAAgB,CAAC,cAAc,UAAU,EAAE,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;YAC/B,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,sBAAsB,CAAA;YAEvD,OAAO,MAAM,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC5D,IAAI,IAAI,GAAG,KAAK,CAAA;gBAChB,IAAI,IAAI,GAAG,CAAC,CAAA;gBACZ,IAAI,MAAiD,CAAA;gBACrD,IAAI,WAAW,GAAgB,GAAG,EAAE,CAAC,SAAS,CAAA;gBAE9C,MAAM,MAAM,GAAG,CAAC,MAAkB,EAAQ,EAAE;oBAC1C,IAAI,IAAI,EAAE,CAAC;wBACT,OAAM;oBACR,CAAC;oBACD,IAAI,GAAG,IAAI,CAAA;oBACX,YAAY,CAAC,QAAQ,CAAC,CAAA;oBACtB,YAAY,CAAC,MAAM,CAAC,CAAA;oBACpB,WAAW,EAAE,CAAA;oBACb,MAAM,EAAE,CAAA;gBACV,CAAC,CAAA;gBAED,MAAM,aAAa,GAAG,KAAK,EAAE,MAAwB,EAA4B,EAAE;oBACjF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBACzB,OAAO,MAAM,CAAA;oBACf,CAAC;oBACD,IAAI,CAAC;wBACH,OAAO,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,CAAA;oBACpD,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,IAAI,CAAA;oBACb,CAAC;gBACH,CAAC,CAAA;gBAED,MAAM,MAAM,GAAG,KAAK,EAAE,KAAkB,EAAE,KAAc,EAAE,MAAwB,EAAoB,EAAE;oBACtG,IAAI,KAAK,KAAK,WAAW,CAAC,SAAS,EAAE,CAAC;wBACpC,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,CAAA;wBACxC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;wBAC3B,OAAO,IAAI,CAAA;oBACb,CAAC;oBACD,IAAI,KAAK,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC;wBACjC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;wBAClD,OAAO,IAAI,CAAA;oBACb,CAAC;oBACD,OAAO,KAAK,CAAA;gBACd,CAAC,CAAA;gBAED,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;gBAE/F,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,KAAK,EAAC,KAAK,EAAC,EAAE;oBACxC,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;wBACpC,MAAM,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;oBACtD,CAAC;gBACH,CAAC,CAAgB,CAAA;gBAEjB,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;oBACrC,IAAI,IAAI,EAAE,CAAC;wBACT,OAAM;oBACR,CAAC;oBACD,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;wBAC3C,IAAI,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;4BAC1D,OAAM;wBACR,CAAC;oBACH,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;wBAC3B,OAAM;oBACR,CAAC;oBACD,IAAI,CAAC,IAAI,EAAE,CAAC;wBACV,MAAM,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,EAAE,CAAA,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;oBACzF,CAAC;gBACH,CAAC,CAAA;gBAED,KAAK,IAAI,EAAE,CAAA;YACb,CAAC,CAAC,CAAA;QACJ,CAAC;KACF,CAAA;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { PlanningStore } from '@owlmeans/planning';
2
+ import type { StoreRoute } from './types.js';
3
+ /**
4
+ * One `PlanningStore` over a default store and the stores plugins OWN.
5
+ *
6
+ * Writes that name a type go to the owning store; a read by id asks the default store first and
7
+ * then each owner; a list whose criteria names one owned type (or several owned by one store) goes
8
+ * there, and every other list is the default store's — a cross-type query is answered by the
9
+ * default store alone, never merged. Relationship lists and commit subscriptions span every store.
10
+ */
11
+ export declare const makeCompositeStore: (routes: StoreRoute[], fallback: PlanningStore) => PlanningStore;
12
+ //# sourceMappingURL=composite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite.d.ts","sourceRoot":"","sources":["../../src/store/composite.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACI,aAAa,EAE5B,MAAM,oBAAoB,CAAA;AAG3B,OAAO,KAAK,EAAa,UAAU,EAAE,MAAM,YAAY,CAAA;AAiBvD;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,WAAY,UAAU,EAAE,YAAY,aAAa,KAAG,aA0IlF,CAAA"}
@@ -0,0 +1,150 @@
1
+ import { WorkcardNotFound } from '@owlmeans/planning';
2
+ import { applyQuery } from '@owlmeans/resource';
3
+ const firstOf = async (stores, read) => {
4
+ for (const store of stores) {
5
+ const found = await read(store);
6
+ if (found != null) {
7
+ return found;
8
+ }
9
+ }
10
+ return null;
11
+ };
12
+ const sum = async (stores, run) => (await Promise.all(stores.map(run))).reduce((total, count) => total + count, 0);
13
+ /**
14
+ * One `PlanningStore` over a default store and the stores plugins OWN.
15
+ *
16
+ * Writes that name a type go to the owning store; a read by id asks the default store first and
17
+ * then each owner; a list whose criteria names one owned type (or several owned by one store) goes
18
+ * there, and every other list is the default store's — a cross-type query is answered by the
19
+ * default store alone, never merged. Relationship lists and commit subscriptions span every store.
20
+ */
21
+ export const makeCompositeStore = (routes, fallback) => {
22
+ const all = [...new Set([fallback, ...routes.map(route => route.store)])];
23
+ if (all.length === 1) {
24
+ return fallback;
25
+ }
26
+ const byType = (type) => type == null ? fallback : routes.find(route => route.owns(type))?.store ?? fallback;
27
+ const byCriteria = (where) => {
28
+ const type = where?.type;
29
+ if (typeof type === 'string') {
30
+ return byType(type);
31
+ }
32
+ if (Array.isArray(type) && type.length > 0) {
33
+ const targets = new Set(type.map(entry => byType(`${entry}`)));
34
+ return targets.size === 1 ? [...targets][0] : fallback;
35
+ }
36
+ return fallback;
37
+ };
38
+ const logged = all.filter(store => store.transitions != null);
39
+ const byCard = async (card) => {
40
+ for (const store of logged) {
41
+ if (await store.transitions.head(card) > 0) {
42
+ return store;
43
+ }
44
+ }
45
+ return fallback;
46
+ };
47
+ const cards = {
48
+ get: (id, entityId) => firstOf(all, store => store.cards.get(id, entityId)),
49
+ list: (where, opts) => byCriteria(where).cards.list(where, opts),
50
+ count: where => byCriteria(where).cards.count(where),
51
+ summary: (parents, where) => byCriteria(where).cards.summary(parents, where),
52
+ put: card => byType(card.type).cards.put(card),
53
+ drop: async (id, entityId) => { await Promise.all(all.map(store => store.cards.drop(id, entityId))); },
54
+ project: async (card, hint) => { await (await byCard(card)).cards.project(card, hint); },
55
+ purge: (project, entityId) => sum(all, store => store.cards.purge(project, entityId)),
56
+ };
57
+ const transitions = logged.length === 0 ? undefined : {
58
+ append: transition => (byType(transition.type).transitions ?? fallback.transitions).append(transition),
59
+ get: id => firstOf(logged, store => store.transitions.get(id)),
60
+ byKey: (entityId, key) => firstOf(logged, store => store.transitions.byKey(entityId, key)),
61
+ list: async (where, opts) => {
62
+ const store = typeof where.card === 'string' ? await byCard(where.card) : fallback;
63
+ return await (store.transitions ?? logged[0].transitions).list(where, opts);
64
+ },
65
+ nextSeq: async (card, expect) => (await byCard(card)).transitions.nextSeq(card, expect),
66
+ head: async (card) => (await byCard(card)).transitions?.head(card) ?? 0,
67
+ commit: async (id, commit) => {
68
+ for (const store of logged) {
69
+ if (await store.transitions.get(id) != null) {
70
+ await store.transitions.commit(id, commit);
71
+ return;
72
+ }
73
+ }
74
+ },
75
+ purge: where => sum(logged, store => store.transitions.purge(where)),
76
+ };
77
+ const specified = all.filter(store => store.specs != null);
78
+ const specs = specified.length === 0 ? undefined : {
79
+ current: (parent, category, entityId) => firstOf(specified, store => store.specs.current(parent, category, entityId)),
80
+ list: async (parent, entityId, query) => {
81
+ for (const store of specified) {
82
+ const result = await store.specs.list(parent, entityId, query);
83
+ if (result.total > 0) {
84
+ return result;
85
+ }
86
+ }
87
+ return { items: [], total: 0 };
88
+ },
89
+ revisions: async (id, entityId, limit) => {
90
+ for (const store of specified) {
91
+ const result = await store.specs.revisions(id, entityId, limit);
92
+ if (result.length > 0) {
93
+ return result;
94
+ }
95
+ }
96
+ return [];
97
+ },
98
+ };
99
+ const linked = all.filter(store => store.links != null);
100
+ const links = linked.length === 0 ? undefined : {
101
+ list: async (where, opts) => {
102
+ const results = await Promise.all(linked.map(store => store.links.list(where, { size: 0 })));
103
+ const items = results.flatMap((result) => result.items);
104
+ return applyQuery(items, undefined, opts);
105
+ },
106
+ put: link => (fallback.links ?? linked[0].links).put(link),
107
+ drop: where => sum(linked, store => store.links.drop(where)),
108
+ };
109
+ const committing = all.filter(store => store.commits != null);
110
+ const statusStore = async (transition) => {
111
+ for (const store of committing) {
112
+ try {
113
+ await store.commits.status(transition);
114
+ return store.commits;
115
+ }
116
+ catch {
117
+ // not this store's transition
118
+ }
119
+ }
120
+ throw new WorkcardNotFound(`transition:${transition}`);
121
+ };
122
+ const commits = committing.length === 0 ? undefined : {
123
+ status: async (transition) => await (await statusStore(transition)).status(transition),
124
+ wait: async (transition, opts) => await (await statusStore(transition)).wait(transition, opts),
125
+ subscribe: async (listener, filter) => {
126
+ const releases = await Promise.all(committing.map(store => store.commits.subscribe(listener, filter)));
127
+ const unsubscribe = () => releases.forEach(release => release());
128
+ return unsubscribe;
129
+ },
130
+ recall: transition => {
131
+ for (const store of committing) {
132
+ const event = store.commits.recall?.(transition);
133
+ if (event != null) {
134
+ return event;
135
+ }
136
+ }
137
+ return undefined;
138
+ },
139
+ };
140
+ return {
141
+ alias: `composite:${fallback.alias ?? 'default'}`,
142
+ newId: fallback.newId,
143
+ cards,
144
+ ...(transitions != null ? { transitions } : {}),
145
+ ...(specs != null ? { specs } : {}),
146
+ ...(links != null ? { links } : {}),
147
+ ...(commits != null ? { commits } : {}),
148
+ };
149
+ };
150
+ //# sourceMappingURL=composite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composite.js","sourceRoot":"","sources":["../../src/store/composite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { CommitState } from '@owlmeans/planning';
2
+ import type { CommitEvent, PlanningStore, SpecificationRevision, Transition, Workcard } from '@owlmeans/planning';
3
+ import type { FoldOptions, FoldResult } from './types.js';
4
+ /** The event a settled transition publishes. `record` is in-process only — strip it before a bus. */
5
+ export declare const commitEventOf: (transition: Transition, state: CommitState, at: string, extra?: {
6
+ error?: string;
7
+ record?: Workcard | null;
8
+ }) => CommitEvent;
9
+ /**
10
+ * Fold every pending transition of one card — the projection body every store reuses.
11
+ *
12
+ * Transitions are read in `seq` order past the card's own `seq`, and only `pending` ones are
13
+ * applied, each with `applyTransition` and nothing else. Per transition: write the record (a
14
+ * `delete` drops it, a project `delete` purges everything under it), fold its relationships, mark
15
+ * it `committed`, `publish` the event, then run `onCommitted` — so the `after` chain runs in THIS
16
+ * process, exactly once per committed transition. A transition that cannot be folded is marked
17
+ * `failed` with the reason and a failed event is published, and the fold goes PAST it: the card's
18
+ * `seq` advances to the failed transition with every other value as it was, so the next
19
+ * transition applies normally. Nothing is removed from the log. A create that fails leaves no card
20
+ * to advance, so what follows it fails too; a store that refuses the advancing write itself stops
21
+ * the fold there and reports `followUp`, leaving the rest pending for a retry.
22
+ *
23
+ * The caller owns single flight: two folds of one card running at once would both publish.
24
+ *
25
+ * @throws {PlanningUnsupported} for a store without a transition log
26
+ */
27
+ export declare const foldPending: (store: PlanningStore, cardId: string, entityId: string, opts?: FoldOptions) => Promise<FoldResult>;
28
+ /**
29
+ * Mark every pending transition of a card `failed` and publish a failed event for each — what a
30
+ * queued store does when its projection job is dead, or waiters hang until their timeout.
31
+ */
32
+ export declare const failPending: (store: PlanningStore, cardId: string, entityId: string, reason: string, opts?: Pick<FoldOptions, 'publish' | 'now'>) => Promise<number>;
33
+ /**
34
+ * A specification's history, replayed from its log: one entry per create and per committed
35
+ * content change, newest first. The fold is `applyTransition` itself, so an entry's `body` is the
36
+ * body AT that revision even when the transition changed only `ref`.
37
+ */
38
+ export declare const revisionsFromLog: (log: Transition[], limit?: number) => SpecificationRevision[];
39
+ //# sourceMappingURL=fold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.d.ts","sourceRoot":"","sources":["../../src/store/fold.ts"],"names":[],"mappings":"AAAA,OAAO,EAC+B,WAAW,EAChD,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EACV,WAAW,EAAE,aAAa,EAAgB,qBAAqB,EAAE,UAAU,EAAE,QAAQ,EACtF,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAkBzD,qGAAqG;AACrG,eAAO,MAAM,aAAa,eACZ,UAAU,SAAS,WAAW,MAAM,MAAM,UAAU;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,KAC3G,WAaD,CAAA;AAqDF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,WAAW,UACf,aAAa,UAAU,MAAM,YAAY,MAAM,SAAQ,WAAW,KACxE,OAAO,CAAC,UAAU,CAiEpB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,UACf,aAAa,UAAU,MAAM,YAAY,MAAM,UAAU,MAAM,SAChE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,KAAK,CAAC,KACzC,OAAO,CAAC,MAAM,CAiBhB,CAAA;AAID;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAS,UAAU,EAAE,UAAU,MAAM,KAAG,qBAAqB,EA2CzF,CAAA"}
@@ -0,0 +1,220 @@
1
+ import { applyRelationship, applyTransition, CommitState, isProject, PlanningUnsupported, TransitionAction, } from '@owlmeans/planning';
2
+ const isoNow = () => new Date().toISOString();
3
+ const clean = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
4
+ const errorText = (error) => error instanceof Error ? error.message : `${error}`;
5
+ const safely = async (label, run) => {
6
+ try {
7
+ await run();
8
+ }
9
+ catch (error) {
10
+ console.error(`planning: ${label} failed:`, error);
11
+ }
12
+ };
13
+ /** The event a settled transition publishes. `record` is in-process only — strip it before a bus. */
14
+ export const commitEventOf = (transition, state, at, extra) => clean({
15
+ transition: transition.id,
16
+ card: transition.card,
17
+ entityId: transition.entityId,
18
+ project: transition.project,
19
+ kind: transition.kind,
20
+ type: transition.type,
21
+ seq: transition.seq,
22
+ action: transition.action,
23
+ state,
24
+ at,
25
+ error: extra?.error,
26
+ record: extra?.record,
27
+ });
28
+ const bearsRelationships = (transition) => transition.action === TransitionAction.Link
29
+ || transition.action === TransitionAction.Unlink
30
+ || transition.action === TransitionAction.Delete
31
+ || (transition.action === TransitionAction.Create && (transition.links?.length ?? 0) > 0);
32
+ const foldRelationships = async (store, transition) => {
33
+ const links = store.links;
34
+ if (links == null || !bearsRelationships(transition)) {
35
+ return;
36
+ }
37
+ const where = { entityId: transition.entityId };
38
+ const [outgoing, incoming] = await Promise.all([
39
+ links.list({ ...where, from: transition.card }, { size: 0 }),
40
+ links.list({ ...where, to: transition.card }, { size: 0 }),
41
+ ]);
42
+ const before = [...new Map([...outgoing.items, ...incoming.items].map(link => [link.id, link])).values()];
43
+ const after = applyRelationship(before, transition);
44
+ const kept = new Set(after.filter(link => link.id != null).map(link => link.id));
45
+ for (const link of before) {
46
+ if (link.id != null && !kept.has(link.id)) {
47
+ await links.drop({ entityId: transition.entityId, id: link.id });
48
+ }
49
+ }
50
+ for (const link of after) {
51
+ if (link.id == null) {
52
+ await links.put(link);
53
+ }
54
+ }
55
+ };
56
+ const writeFold = async (store, before, after, transition) => {
57
+ if (transition.action === TransitionAction.Delete) {
58
+ if (before != null && isProject(before)) {
59
+ // A project takes everything under it, its own log included — the hub remembers the commit.
60
+ await store.cards.purge(transition.card, transition.entityId);
61
+ return;
62
+ }
63
+ await foldRelationships(store, transition);
64
+ await store.cards.drop(transition.card, transition.entityId);
65
+ return;
66
+ }
67
+ if (after != null) {
68
+ await store.cards.put(after);
69
+ }
70
+ await foldRelationships(store, transition);
71
+ };
72
+ /**
73
+ * Fold every pending transition of one card — the projection body every store reuses.
74
+ *
75
+ * Transitions are read in `seq` order past the card's own `seq`, and only `pending` ones are
76
+ * applied, each with `applyTransition` and nothing else. Per transition: write the record (a
77
+ * `delete` drops it, a project `delete` purges everything under it), fold its relationships, mark
78
+ * it `committed`, `publish` the event, then run `onCommitted` — so the `after` chain runs in THIS
79
+ * process, exactly once per committed transition. A transition that cannot be folded is marked
80
+ * `failed` with the reason and a failed event is published, and the fold goes PAST it: the card's
81
+ * `seq` advances to the failed transition with every other value as it was, so the next
82
+ * transition applies normally. Nothing is removed from the log. A create that fails leaves no card
83
+ * to advance, so what follows it fails too; a store that refuses the advancing write itself stops
84
+ * the fold there and reports `followUp`, leaving the rest pending for a retry.
85
+ *
86
+ * The caller owns single flight: two folds of one card running at once would both publish.
87
+ *
88
+ * @throws {PlanningUnsupported} for a store without a transition log
89
+ */
90
+ export const foldPending = async (store, cardId, entityId, opts = {}) => {
91
+ const transitions = store.transitions;
92
+ if (transitions == null) {
93
+ throw new PlanningUnsupported(`fold:${store.alias ?? 'store'}`);
94
+ }
95
+ const now = opts.now ?? isoNow;
96
+ let card = await store.cards.get(cardId, entityId);
97
+ const listed = await transitions.list({ entityId, card: cardId, sinceSeq: card?.seq ?? 0, state: CommitState.Pending }, { sort: ['seq'], size: opts.limit ?? 0 });
98
+ let folded = 0;
99
+ let failed = 0;
100
+ for (const transition of listed.items) {
101
+ if (transition.commit.state !== CommitState.Pending || transition.id == null) {
102
+ continue;
103
+ }
104
+ await opts.touch?.();
105
+ const at = now();
106
+ let next;
107
+ try {
108
+ next = applyTransition(card, transition);
109
+ if (card != null && next === card) {
110
+ // Already applied by another folder, which owns its commit and its event.
111
+ continue;
112
+ }
113
+ await writeFold(store, card, next, transition);
114
+ }
115
+ catch (error) {
116
+ failed++;
117
+ const message = errorText(error);
118
+ if (card != null && transition.seq > card.seq) {
119
+ // Fold PAST it: the record keeps its previous values and only its cursor moves, so the
120
+ // next transition still applies. The card is re-written whole, which also undoes a write
121
+ // that got half way before it threw.
122
+ const skipped = { ...card, seq: transition.seq, head: Math.max(card.head ?? card.seq, transition.seq) };
123
+ try {
124
+ await store.cards.put(skipped);
125
+ card = skipped;
126
+ }
127
+ catch (advance) {
128
+ // The store itself refuses writes: leave the rest pending for a retry rather than
129
+ // failing every later transition as out of order.
130
+ console.error(`planning: cannot advance ${cardId} past failed seq ${transition.seq}:`, advance);
131
+ await safely('commit failure', () => transitions.commit(transition.id, { state: CommitState.Failed, at, error: message }));
132
+ await safely('publish', () => opts.publish?.(commitEventOf(transition, CommitState.Failed, at, { error: message })));
133
+ return { card, folded, failed, followUp: true };
134
+ }
135
+ }
136
+ await safely('commit failure', () => transitions.commit(transition.id, { state: CommitState.Failed, at, error: message }));
137
+ const event = commitEventOf(transition, CommitState.Failed, at, { error: message });
138
+ await safely('publish', () => opts.publish?.(event));
139
+ continue;
140
+ }
141
+ card = next;
142
+ folded++;
143
+ await safely('commit', () => transitions.commit(transition.id, { state: CommitState.Committed, at }));
144
+ const event = commitEventOf(transition, CommitState.Committed, at, { record: next });
145
+ await safely('publish', () => opts.publish?.(event));
146
+ await safely('onCommitted', () => opts.onCommitted?.(event));
147
+ }
148
+ return { card, folded, failed, followUp: listed.total > listed.items.length };
149
+ };
150
+ /**
151
+ * Mark every pending transition of a card `failed` and publish a failed event for each — what a
152
+ * queued store does when its projection job is dead, or waiters hang until their timeout.
153
+ */
154
+ export const failPending = async (store, cardId, entityId, reason, opts = {}) => {
155
+ const transitions = store.transitions;
156
+ if (transitions == null) {
157
+ return 0;
158
+ }
159
+ const at = (opts.now ?? isoNow)();
160
+ const pending = await transitions.list({ entityId, card: cardId, state: CommitState.Pending }, { sort: ['seq'], size: 0 });
161
+ for (const transition of pending.items) {
162
+ if (transition.id == null) {
163
+ continue;
164
+ }
165
+ await transitions.commit(transition.id, { state: CommitState.Failed, at, error: reason });
166
+ const event = commitEventOf(transition, CommitState.Failed, at, { error: reason });
167
+ await safely('publish', () => opts.publish?.(event));
168
+ }
169
+ return pending.items.length;
170
+ };
171
+ const CONTENT_KEYS = ['body', 'ref', 'format', 'version'];
172
+ /**
173
+ * A specification's history, replayed from its log: one entry per create and per committed
174
+ * content change, newest first. The fold is `applyTransition` itself, so an entry's `body` is the
175
+ * body AT that revision even when the transition changed only `ref`.
176
+ */
177
+ export const revisionsFromLog = (log, limit) => {
178
+ const ordered = log.filter(transition => transition.commit.state !== CommitState.Pending)
179
+ .sort((left, right) => left.seq - right.seq);
180
+ const entries = [];
181
+ let state = null;
182
+ for (const transition of ordered) {
183
+ if (transition.commit.state === CommitState.Failed) {
184
+ // The fold went past it; so does the replay.
185
+ if (state != null && transition.seq > state.seq) {
186
+ state = { ...state, seq: transition.seq };
187
+ }
188
+ continue;
189
+ }
190
+ try {
191
+ state = applyTransition(state, transition);
192
+ }
193
+ catch {
194
+ break;
195
+ }
196
+ if (state == null) {
197
+ break;
198
+ }
199
+ const changed = transition.action === TransitionAction.Create
200
+ || CONTENT_KEYS.some(key => transition.changes[key] !== undefined
201
+ || transition.unset?.includes(key) === true);
202
+ if (!changed) {
203
+ continue;
204
+ }
205
+ const spec = state;
206
+ entries.push(clean({
207
+ revision: spec.revision ?? entries.length + 1,
208
+ body: spec.body,
209
+ ref: spec.ref,
210
+ bodyChars: spec.bodyChars,
211
+ version: spec.version,
212
+ at: transition.at,
213
+ by: transition.actor,
214
+ transition: transition.id,
215
+ }));
216
+ }
217
+ const newest = entries.reverse();
218
+ return limit != null && limit > 0 ? newest.slice(0, limit) : newest;
219
+ };
220
+ //# sourceMappingURL=fold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fold.js","sourceRoot":"","sources":["../../src/store/fold.ts"],"names":[],"mappings":"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"}