@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,136 @@
1
+ import { CardTypeNotAllowed, isProject, normalizeParents, ParentNotFound, PlanningError, PlanningScopeMismatch, primaryFlowOf, projectOf, slotOf, TransitionAction, UnknownStatusFlow, WorkcardKind, WorkcardNotFound, } from '@owlmeans/planning';
2
+ const trimmed = (value) => typeof value === 'string' ? value.trim() : value;
3
+ const TRIMMED = ['title', 'description', 'code'];
4
+ const trim = (record) => {
5
+ if (record == null) {
6
+ return record;
7
+ }
8
+ const copy = { ...record };
9
+ for (const key of TRIMMED) {
10
+ if (typeof copy[key] === 'string') {
11
+ copy[key] = trimmed(copy[key]);
12
+ }
13
+ }
14
+ return copy;
15
+ };
16
+ /**
17
+ * Step 1: a deep copy with trimmed text, `parents ∋ parent` on a draft, and no duplicate `unset`
18
+ * paths. The caller's object is never touched.
19
+ */
20
+ export const normalizeExecution = (input) => {
21
+ const exec = structuredClone(input);
22
+ if (exec.card != null && typeof exec.card === 'object') {
23
+ const draft = trim(exec.card);
24
+ const parents = normalizeParents(draft.parent, draft.parents);
25
+ exec.card = { ...draft, ...(parents.length > 0 ? { parents, parent: draft.parent ?? parents[0] } : {}) };
26
+ }
27
+ if (exec.changes != null) {
28
+ exec.changes = trim(exec.changes);
29
+ }
30
+ if (exec.unset != null) {
31
+ exec.unset = [...new Set(exec.unset)];
32
+ }
33
+ return exec;
34
+ };
35
+ /** The parent type's rule for a child of `kind`/`type`. @throws {CardTypeNotAllowed} */
36
+ export const assertChildAllowed = (runtime, parent, kind, type) => {
37
+ if (kind === WorkcardKind.Specification) {
38
+ return;
39
+ }
40
+ if (!isProject(parent)) {
41
+ throw new CardTypeNotAllowed(`${parent.type}:${type}`);
42
+ }
43
+ const parentType = runtime.service().schemas.type(parent.type);
44
+ const allowed = kind === WorkcardKind.Project ? parentType.projectTypes ?? [] : parentType.cardTypes ?? [];
45
+ if (!allowed.includes(type)) {
46
+ throw new CardTypeNotAllowed(`${parent.type}:${type}`);
47
+ }
48
+ };
49
+ /**
50
+ * Step 4: the card, its type and flow, its parent and — for a specification — its slot.
51
+ *
52
+ * @throws {WorkcardNotFound | PlanningScopeMismatch | UnknownWorkcardType | UnknownStatusFlow}
53
+ * @throws {ParentNotFound | CardTypeNotAllowed | PlanningError}
54
+ */
55
+ export const resolveExecution = async (runtime, facade, exec) => {
56
+ const service = runtime.service();
57
+ const schemas = service.schemas;
58
+ const entityId = facade.scope.entityId;
59
+ const create = exec.action === TransitionAction.Create;
60
+ let card;
61
+ let type;
62
+ let parent;
63
+ if (create) {
64
+ if (exec.card == null || typeof exec.card !== 'object') {
65
+ throw new PlanningError('malformed:create-without-draft');
66
+ }
67
+ const draft = exec.card;
68
+ type = schemas.type(draft.type);
69
+ if (type.kind !== draft.kind) {
70
+ throw new PlanningError(`malformed:kind:${draft.type}:${draft.kind}`);
71
+ }
72
+ // Normalized: the primary parent is first. It must accept the child; so must every project
73
+ // among the secondary parents.
74
+ for (const [index, id] of normalizeParents(draft.parent, draft.parents).entries()) {
75
+ const found = await facade.cards.load(id);
76
+ if (found == null) {
77
+ throw new ParentNotFound(id);
78
+ }
79
+ if (index === 0) {
80
+ parent = found;
81
+ }
82
+ if (index === 0 || isProject(found)) {
83
+ assertChildAllowed(runtime, found, draft.kind, draft.type);
84
+ }
85
+ }
86
+ if (draft.kind === WorkcardKind.Specification && parent == null) {
87
+ throw new PlanningError('malformed:specification-without-parent');
88
+ }
89
+ }
90
+ else {
91
+ if (typeof exec.card !== 'string' || exec.card === '') {
92
+ throw new PlanningError(`malformed:${exec.action}-without-card`);
93
+ }
94
+ const found = await runtime.reader().cards.get(exec.card, entityId);
95
+ if (found == null) {
96
+ throw new WorkcardNotFound(exec.card);
97
+ }
98
+ if (found.entityId !== entityId) {
99
+ throw new PlanningScopeMismatch(exec.card);
100
+ }
101
+ card = found;
102
+ type = schemas.type(card.type);
103
+ parent = card.parent != null ? await facade.cards.load(card.parent) ?? undefined : undefined;
104
+ }
105
+ const flowId = exec.flow ?? primaryFlowOf(type);
106
+ if (!type.flows.includes(flowId)) {
107
+ throw new UnknownStatusFlow(`${type.type}:${flowId}`);
108
+ }
109
+ const kind = create ? exec.card.kind : card.kind;
110
+ const category = create ? exec.card.category : card?.category;
111
+ const slot = kind === WorkcardKind.Specification && parent != null && category != null
112
+ ? slotOf(schemas.type(parent.type), category)
113
+ : undefined;
114
+ return {
115
+ create,
116
+ ...(card != null ? { card } : {}),
117
+ type,
118
+ flowId,
119
+ flow: schemas.flow(flowId),
120
+ ...(parent != null ? { parent } : {}),
121
+ ...(slot != null ? { slot } : {}),
122
+ store: service.store(type.type),
123
+ };
124
+ };
125
+ /** The project a transition is filed under: a project's own id, else its parent's project. */
126
+ export const projectFor = (resolved, exec, cardId) => {
127
+ if (resolved.card != null) {
128
+ return isProject(resolved.card) ? resolved.card.id : projectOf(resolved.card, resolved.parent);
129
+ }
130
+ const draft = exec.card;
131
+ if (draft.kind === WorkcardKind.Project) {
132
+ return cardId;
133
+ }
134
+ return projectOf({ kind: draft.kind, parent: draft.parent, parents: draft.parents ?? [] }, resolved.parent);
135
+ };
136
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/executor/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { PlanningFacade, TransitionExecution } from '@owlmeans/planning';
2
+ import type { PlanningRuntime } from '../service.js';
3
+ import type { Resolved } from './resolve.js';
4
+ /**
5
+ * Step 6: shape, flow rule, immutables, `fields`, labels, parent moves, the specification slot and
6
+ * relationships — in that order. Nothing is written by a refusal here.
7
+ *
8
+ * @throws {PlanningError} `malformed:*` / `immutable:*`
9
+ * @throws {IllegalTransition | FieldsInvalid | LabelNotAllowed | ParentNotFound | CardTypeNotAllowed}
10
+ * @throws {SpecificationSlotUnknown | SpecificationRevisionConflict | RelationshipRefused}
11
+ */
12
+ export declare const validateExecution: (runtime: PlanningRuntime, facade: PlanningFacade, exec: TransitionExecution, resolved: Resolved) => Promise<void>;
13
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/executor/validate.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EAAoC,mBAAmB,EACtE,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AA8N5C;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,YACnB,eAAe,UAAU,cAAc,QAAQ,mBAAmB,YAAY,QAAQ,KAC9F,OAAO,CAAC,IAAI,CASd,CAAA"}
@@ -0,0 +1,222 @@
1
+ import { applyUnset, assertMutable, BODY_MAX, CODE_MAX, DESCRIPTION_MAX, IllegalTransition, LabelNotAllowed, MAX_LABELS, MAX_PARENTS, mergeFields, normalizeParents, ParentNotFound, PlanningError, RelationshipRefused, ruleOf, SpecificationRevisionConflict, SpecificationSlotUnknown, slotOf, TITLE_MAX, TransitionAction, validateFields, validateSpecificationBody, WorkcardKind, } from '@owlmeans/planning';
2
+ import { assertChildAllowed } from './resolve.js';
3
+ const ACTIONS = new Set(Object.values(TransitionAction));
4
+ const malformed = (what) => new PlanningError(`malformed:${what}`);
5
+ const assertText = (name, value, max, required) => {
6
+ if (value === undefined || value === null) {
7
+ if (required) {
8
+ throw malformed(name);
9
+ }
10
+ return;
11
+ }
12
+ if (typeof value !== 'string' || (required && value === '') || value.length > max) {
13
+ throw malformed(name);
14
+ }
15
+ };
16
+ const assertShape = (exec, resolved) => {
17
+ if (!ACTIONS.has(exec.action)) {
18
+ throw malformed(`action:${exec.action}`);
19
+ }
20
+ if (exec.links != null && exec.action !== TransitionAction.Create) {
21
+ throw malformed('links-outside-create');
22
+ }
23
+ if (exec.action === TransitionAction.Transit && (exec.transition == null || exec.transition === '')) {
24
+ throw malformed('transit-without-transition');
25
+ }
26
+ if ((exec.action === TransitionAction.Link || exec.action === TransitionAction.Unlink)
27
+ && (exec.link?.to == null || exec.link.to === '' || exec.link.type == null || exec.link.type === '')) {
28
+ throw malformed(`${exec.action}-without-link`);
29
+ }
30
+ if (resolved.create) {
31
+ const draft = exec.card;
32
+ assertText('title', draft.title, TITLE_MAX, true);
33
+ assertText('description', draft.description, DESCRIPTION_MAX, false);
34
+ assertText('code', draft.code, CODE_MAX, false);
35
+ if ((draft.parents?.length ?? 0) > MAX_PARENTS) {
36
+ throw malformed('parents');
37
+ }
38
+ }
39
+ const changes = exec.changes ?? {};
40
+ if (changes.title !== undefined) {
41
+ assertText('title', changes.title, TITLE_MAX, true);
42
+ }
43
+ assertText('description', changes.description ?? undefined, DESCRIPTION_MAX, false);
44
+ assertText('code', changes.code ?? undefined, CODE_MAX, false);
45
+ };
46
+ const assertFlow = (exec, resolved, runtime) => {
47
+ if (resolved.create) {
48
+ const status = exec.card.status;
49
+ const primary = runtime.service().schemas.primaryFlow(resolved.type.type);
50
+ if (status != null && !primary.statuses.some(definition => definition.key === status)) {
51
+ throw new IllegalTransition(`${primary.id}:create:${status}`);
52
+ }
53
+ return;
54
+ }
55
+ if (exec.action !== TransitionAction.Transit) {
56
+ return;
57
+ }
58
+ const card = resolved.card;
59
+ const from = card.flows[resolved.flowId] ?? card.status;
60
+ if (ruleOf(resolved.flow, exec.transition, from) == null) {
61
+ throw new IllegalTransition(`${resolved.flowId}:${exec.transition}:${from}`);
62
+ }
63
+ };
64
+ const assertFields = (exec, resolved, runtime) => {
65
+ const schemas = runtime.service().schemas;
66
+ if (resolved.create) {
67
+ const draft = exec.card;
68
+ validateFields(schemas, resolved.type.type, mergeFields(draft.fields, exec.changes?.fields));
69
+ return;
70
+ }
71
+ const clears = (exec.unset ?? []).filter(path => path.startsWith('fields.'));
72
+ if (exec.changes?.fields == null && clears.length === 0) {
73
+ return;
74
+ }
75
+ const merged = applyUnset({ fields: mergeFields(resolved.card.fields, exec.changes?.fields) }, clears);
76
+ validateFields(schemas, resolved.type.type, merged.fields);
77
+ };
78
+ const assertLabels = (exec, resolved) => {
79
+ const labels = [
80
+ ...(resolved.create ? exec.card.labels ?? [] : []),
81
+ ...(exec.changes?.labels ?? []),
82
+ ];
83
+ if (labels.length === 0) {
84
+ return;
85
+ }
86
+ if (new Set(labels).size > MAX_LABELS) {
87
+ throw new LabelNotAllowed(`too-many:${labels.length}`);
88
+ }
89
+ const allowed = resolved.type.labels;
90
+ const refused = allowed == null ? undefined : labels.find(label => !allowed.includes(label));
91
+ if (refused != null) {
92
+ throw new LabelNotAllowed(refused);
93
+ }
94
+ };
95
+ const assertParentMove = async (exec, resolved, runtime, facade) => {
96
+ if (resolved.create) {
97
+ return;
98
+ }
99
+ const changes = exec.changes ?? {};
100
+ const moved = [...new Set(normalizeParents(changes.parent, changes.parents))]
101
+ .filter(id => id !== resolved.card.parent && !resolved.card.parents.includes(id));
102
+ for (const id of moved) {
103
+ if (id === resolved.card.id) {
104
+ throw malformed('parent-self');
105
+ }
106
+ const found = await facade.cards.load(id);
107
+ if (found == null) {
108
+ throw new ParentNotFound(id);
109
+ }
110
+ assertChildAllowed(runtime, found, resolved.card.kind, resolved.card.type);
111
+ }
112
+ };
113
+ const assertSpecification = async (exec, resolved, runtime, facade) => {
114
+ const kind = resolved.create ? exec.card.kind : resolved.card.kind;
115
+ if (kind !== WorkcardKind.Specification) {
116
+ return;
117
+ }
118
+ const schemas = runtime.service().schemas;
119
+ if (resolved.create) {
120
+ const draft = exec.card;
121
+ const parent = resolved.parent;
122
+ if (draft.category == null || draft.category === '') {
123
+ throw malformed('specification-without-category');
124
+ }
125
+ const slot = slotOf(schemas.type(parent.type), draft.category);
126
+ if (slot == null) {
127
+ throw new SpecificationSlotUnknown(`${parent.type}:${draft.category}`);
128
+ }
129
+ if (draft.format != null && draft.format !== slot.format) {
130
+ throw malformed(`format:${draft.category}:${draft.format}`);
131
+ }
132
+ assertText('body', draft.body, BODY_MAX, false);
133
+ validateSpecificationBody(slot, draft.body);
134
+ if (slot.multiple !== true && await facade.specifications.current(parent.id, draft.category) != null) {
135
+ throw new SpecificationRevisionConflict(`${parent.id}:${draft.category}`);
136
+ }
137
+ return;
138
+ }
139
+ const spec = resolved.card;
140
+ const changes = exec.changes ?? {};
141
+ if (changes.category !== undefined && changes.category !== spec.category) {
142
+ throw new PlanningError('immutable:category');
143
+ }
144
+ const slot = resolved.slot;
145
+ if (slot == null) {
146
+ return;
147
+ }
148
+ if (changes.format != null && changes.format !== slot.format) {
149
+ throw malformed(`format:${spec.category}:${changes.format}`);
150
+ }
151
+ if (changes.body != null) {
152
+ assertText('body', changes.body, BODY_MAX, false);
153
+ validateSpecificationBody(slot, changes.body);
154
+ }
155
+ };
156
+ const assertRelationships = async (exec, resolved, facade) => {
157
+ const drafts = exec.action === TransitionAction.Create
158
+ ? exec.links ?? []
159
+ : exec.action === TransitionAction.Link || exec.action === TransitionAction.Unlink ? [exec.link] : [];
160
+ if (drafts.length === 0) {
161
+ return;
162
+ }
163
+ const cardId = resolved.card?.id;
164
+ const declared = resolved.type.relationships ?? [];
165
+ const counted = new Map();
166
+ for (const draft of drafts) {
167
+ const rule = declared.find(entry => entry.name === draft.type);
168
+ if (rule == null) {
169
+ throw new RelationshipRefused(`unknown:${draft.type}`);
170
+ }
171
+ if (draft.from != null && draft.from !== cardId) {
172
+ throw new RelationshipRefused(`from:${draft.from}`);
173
+ }
174
+ if (exec.action === TransitionAction.Unlink) {
175
+ const existing = await facade.relationships.list({ from: cardId, to: draft.to, type: draft.type });
176
+ if (existing.total === 0) {
177
+ throw new RelationshipRefused(`absent:${draft.type}:${draft.to}`);
178
+ }
179
+ continue;
180
+ }
181
+ const target = await facade.cards.load(draft.to);
182
+ if (target == null) {
183
+ throw new RelationshipRefused(`to:${draft.to}`);
184
+ }
185
+ if (rule.from != null && !rule.from.includes(resolved.type.type)) {
186
+ throw new RelationshipRefused(`from-type:${draft.type}:${resolved.type.type}`);
187
+ }
188
+ if (rule.to != null && !rule.to.includes(target.type)) {
189
+ throw new RelationshipRefused(`to-type:${draft.type}:${target.type}`);
190
+ }
191
+ if (rule.single === true) {
192
+ const count = (counted.get(draft.type) ?? 0) + 1;
193
+ counted.set(draft.type, count);
194
+ const existing = cardId == null
195
+ ? 0
196
+ : (await facade.relationships.list({ from: cardId, type: draft.type })).items
197
+ .filter(link => link.to !== draft.to).length;
198
+ if (count + existing > 1) {
199
+ throw new RelationshipRefused(`single:${draft.type}`);
200
+ }
201
+ }
202
+ }
203
+ };
204
+ /**
205
+ * Step 6: shape, flow rule, immutables, `fields`, labels, parent moves, the specification slot and
206
+ * relationships — in that order. Nothing is written by a refusal here.
207
+ *
208
+ * @throws {PlanningError} `malformed:*` / `immutable:*`
209
+ * @throws {IllegalTransition | FieldsInvalid | LabelNotAllowed | ParentNotFound | CardTypeNotAllowed}
210
+ * @throws {SpecificationSlotUnknown | SpecificationRevisionConflict | RelationshipRefused}
211
+ */
212
+ export const validateExecution = async (runtime, facade, exec, resolved) => {
213
+ assertShape(exec, resolved);
214
+ assertFlow(exec, resolved, runtime);
215
+ assertMutable(exec, resolved.type);
216
+ assertFields(exec, resolved, runtime);
217
+ assertLabels(exec, resolved);
218
+ await assertParentMove(exec, resolved, runtime, facade);
219
+ await assertSpecification(exec, resolved, runtime, facade);
220
+ await assertRelationships(exec, resolved, facade);
221
+ };
222
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/executor/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { ExecuteOptions, PlanningFacade, TransitionExecution, TransitionReceipt } from '@owlmeans/planning';
2
+ import type { PlanningRuntime } from './service.js';
3
+ /**
4
+ * THE write path. Nothing is appended before step 11, so every refusal leaves the log untouched.
5
+ *
6
+ * 1 normalize → 2 scope → 3 idempotency (a known `key` answers its first receipt, before any
7
+ * validation) → 4 resolve → 5 the plugins' `before` chain (re-resolved once when it moved the type
8
+ * or the parent) → 6 validate → 7 allocate the card id → 8 code → 9 changes (an update changing
9
+ * nothing answers the current receipt and appends nothing) → 10 seq, a CAS against the head →
10
+ * 11 append → 12 request the projection → 13 receipt → 14 `wait`.
11
+ *
12
+ * `after` hooks are NOT run here — the process that folds runs them, once per commit.
13
+ */
14
+ export declare const executeTransition: (runtime: PlanningRuntime, facade: PlanningFacade, input: TransitionExecution, opts?: ExecuteOptions) => Promise<TransitionReceipt>;
15
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,cAAc,EAAuB,cAAc,EACnD,mBAAmB,EAAE,iBAAiB,EACvC,MAAM,oBAAoB,CAAA;AAO3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAkDnD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,iBAAiB,YACnB,eAAe,UAAU,cAAc,SAAS,mBAAmB,SAAS,cAAc,KAClG,OAAO,CAAC,iBAAiB,CAwE3B,CAAA"}
@@ -0,0 +1,113 @@
1
+ import { uuid } from '@owlmeans/basic-ids';
2
+ import { PlanningError, PlanningUnsupported, WorkcardConflict } from '@owlmeans/planning';
3
+ import { changeSetOf, transitionOf } from './executor/changes.js';
4
+ import { assignCode } from './executor/code.js';
5
+ import { makeReceipt } from './executor/receipt.js';
6
+ import { normalizeExecution, projectFor, resolveExecution } from './executor/resolve.js';
7
+ import { validateExecution } from './executor/validate.js';
8
+ const isoNow = () => new Date().toISOString();
9
+ /** What a type/parent change by a middleware is judged by. */
10
+ const identityOf = (exec) => typeof exec.card === 'string'
11
+ ? `${exec.action}|${exec.card}|${exec.flow ?? ''}|${exec.changes?.parent ?? ''}`
12
+ : `${exec.action}|${exec.card.kind}|${exec.card.type}|${exec.card.parent ?? ''}|${(exec.card.parents ?? []).join(',')}|${exec.flow ?? ''}`;
13
+ const execContextOf = (runtime, facade, resolved) => (plugin) => ({
14
+ context: runtime.context(),
15
+ scope: facade.scope,
16
+ schemas: runtime.service().schemas,
17
+ store: resolved.store,
18
+ facade,
19
+ plugin,
20
+ type: resolved.type,
21
+ flow: resolved.flow,
22
+ ...(resolved.card != null ? { card: resolved.card } : {}),
23
+ ...(resolved.parent != null ? { parent: resolved.parent } : {}),
24
+ });
25
+ const findByKey = async (runtime, entityId, key) => {
26
+ for (const store of runtime.stores()) {
27
+ const transition = await store.transitions?.byKey(entityId, key);
28
+ if (transition != null) {
29
+ return { store, transition };
30
+ }
31
+ }
32
+ return null;
33
+ };
34
+ /** The receipt an update that changes nothing answers with: the card's latest transition. */
35
+ const currentReceipt = async (store, resolved, entityId, opts) => {
36
+ const latest = await store.transitions.list({ entityId, card: resolved.card.id }, { sort: [{ field: 'seq', order: 'desc' }], size: 1 });
37
+ const transition = latest.items[0];
38
+ if (transition == null) {
39
+ throw new PlanningUnsupported(`empty-update-without-log:${resolved.card.id}`);
40
+ }
41
+ return await makeReceipt(store, transition, opts);
42
+ };
43
+ /**
44
+ * THE write path. Nothing is appended before step 11, so every refusal leaves the log untouched.
45
+ *
46
+ * 1 normalize → 2 scope → 3 idempotency (a known `key` answers its first receipt, before any
47
+ * validation) → 4 resolve → 5 the plugins' `before` chain (re-resolved once when it moved the type
48
+ * or the parent) → 6 validate → 7 allocate the card id → 8 code → 9 changes (an update changing
49
+ * nothing answers the current receipt and appends nothing) → 10 seq, a CAS against the head →
50
+ * 11 append → 12 request the projection → 13 receipt → 14 `wait`.
51
+ *
52
+ * `after` hooks are NOT run here — the process that folds runs them, once per commit.
53
+ */
54
+ export const executeTransition = async (runtime, facade, input, opts) => {
55
+ const scope = facade.scope;
56
+ const service = runtime.service();
57
+ const at = (runtime.options.now ?? isoNow)();
58
+ let exec = normalizeExecution(input);
59
+ if (scope.entityId == null || scope.entityId === '') {
60
+ throw new PlanningError('malformed:scope-without-entity');
61
+ }
62
+ if (exec.key != null && exec.key !== '') {
63
+ const found = await findByKey(runtime, scope.entityId, exec.key);
64
+ if (found != null) {
65
+ return await makeReceipt(found.store, found.transition, opts);
66
+ }
67
+ }
68
+ let resolved = await resolveExecution(runtime, facade, exec);
69
+ const before = identityOf(exec);
70
+ exec = normalizeExecution(await runtime.registry.before(exec, execContextOf(runtime, facade, resolved)));
71
+ if (identityOf(exec) !== before) {
72
+ resolved = await resolveExecution(runtime, facade, exec);
73
+ }
74
+ await validateExecution(runtime, facade, exec, resolved);
75
+ const store = resolved.store;
76
+ const transitions = store.transitions;
77
+ if (transitions == null) {
78
+ throw new PlanningUnsupported(`transitions:${store.alias ?? resolved.type.type}`);
79
+ }
80
+ const cardId = resolved.create
81
+ ? store.newId?.() ?? runtime.options.ids?.() ?? uuid()
82
+ : resolved.card.id;
83
+ exec = await assignCode(exec, resolved, scope, runtime.registry, execContextOf(runtime, facade, resolved));
84
+ const { set, empty } = changeSetOf(exec, resolved, service.schemas, at);
85
+ if (empty) {
86
+ return await currentReceipt(store, resolved, scope.entityId, opts);
87
+ }
88
+ const seq = await transitions.nextSeq(cardId, resolved.create ? null : exec.expectSeq ?? null);
89
+ if (resolved.create && seq !== 1) {
90
+ throw new WorkcardConflict(`${cardId}:create:${seq}`);
91
+ }
92
+ const transition = transitionOf({
93
+ exec, resolved, scope, set, cardId, seq, at,
94
+ project: projectFor(resolved, exec, cardId),
95
+ });
96
+ let appended;
97
+ try {
98
+ appended = await transitions.append(transition);
99
+ }
100
+ catch (error) {
101
+ // A lost race on the idempotency key: the winner's receipt is the answer.
102
+ if (exec.key != null && exec.key !== '') {
103
+ const winner = await transitions.byKey(scope.entityId, exec.key);
104
+ if (winner != null) {
105
+ return await makeReceipt(store, winner, opts);
106
+ }
107
+ }
108
+ throw error;
109
+ }
110
+ await store.cards.project(cardId, appended.id != null ? { transition: appended.id } : undefined);
111
+ return await makeReceipt(store, appended, opts);
112
+ };
113
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../src/executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAE1C,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAKzF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAExF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAG1D,MAAM,MAAM,GAAG,GAAW,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AAErD,8DAA8D;AAC9D,MAAM,UAAU,GAAG,CAAC,IAAyB,EAAU,EAAE,CAAC,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;IACrF,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE,EAAE;IAChF,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAA;AAE5I,MAAM,aAAa,GAAG,CACpB,OAAwB,EAAE,MAAsB,EAAE,QAAkB,EACpE,EAAE,CAAC,CAAC,MAAsB,EAAuB,EAAE,CAAC,CAAC;IACrD,OAAO,EAAE,OAAO,CAAC,OAAO,EAA+B;IACvD,KAAK,EAAE,MAAM,CAAC,KAAK;IACnB,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,OAAO;IAClC,KAAK,EAAE,QAAQ,CAAC,KAAK;IACrB,MAAM;IACN,MAAM;IACN,IAAI,EAAE,QAAQ,CAAC,IAAI;IACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;IACnB,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,GAAG,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAChE,CAAC,CAAA;AAEF,MAAM,SAAS,GAAG,KAAK,EACrB,OAAwB,EAAE,QAAgB,EAAE,GAAW,EACW,EAAE;IACpE,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAA;QAChE,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,6FAA6F;AAC7F,MAAM,cAAc,GAAG,KAAK,EAC1B,KAAoB,EAAE,QAAkB,EAAE,QAAgB,EAAE,IAAqB,EACrD,EAAE;IAC9B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,WAAY,CAAC,IAAI,CAC1C,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAK,CAAC,EAAG,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAC7F,CAAA;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAClC,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,QAAQ,CAAC,IAAK,CAAC,EAAE,EAAE,CAAC,CAAA;IAChF,CAAC;IACD,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,CAAA;AACnD,CAAC,CAAA;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,OAAwB,EAAE,MAAsB,EAAE,KAA0B,EAAE,IAAqB,EACvE,EAAE;IAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAA;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;IACjC,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,MAAM,CAAC,EAAE,CAAA;IAE5C,IAAI,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAEpC,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QACpD,MAAM,IAAI,aAAa,CAAC,gCAAgC,CAAC,CAAA;IAC3D,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;QAChE,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;QAC/D,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IAE5D,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAC/B,IAAI,GAAG,kBAAkB,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACxG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC;QAChC,QAAQ,GAAG,MAAM,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAA;IAExD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAA;IAC5B,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CAAA;IACrC,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,mBAAmB,CAAC,eAAe,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IACnF,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM;QAC5B,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,IAAI,EAAE;QACtD,CAAC,CAAC,QAAQ,CAAC,IAAK,CAAC,EAAG,CAAA;IAEtB,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE1G,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACvE,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,MAAM,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IACpE,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,CAAA;IAC9F,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,gBAAgB,CAAC,GAAG,MAAM,WAAW,GAAG,EAAE,CAAC,CAAA;IACvD,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,CAAC;QAC9B,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,OAAO,EAAE,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC;KAC5C,CAAC,CAAA;IAEF,IAAI,QAAoB,CAAA;IACxB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,0EAA0E;QAC1E,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;YAChE,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;gBACnB,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;YAC/C,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;IAED,MAAM,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;IAEhG,OAAO,MAAM,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;AACjD,CAAC,CAAA"}
@@ -0,0 +1,12 @@
1
+ import type { PlanningFacade, PlanningScope } from '@owlmeans/planning';
2
+ import type { PlanningRuntime } from './service.js';
3
+ /**
4
+ * The scoped facade over the service's stores.
5
+ *
6
+ * Every read carries the scope's `entityId` into the store and re-checks it on what comes back, so
7
+ * a card of another entity is simply absent — `load` answers `null`, `get` throws
8
+ * `WorkcardNotFound`, exactly as for an id that never existed. Reads go through the composite
9
+ * store (the default store plus the stores plugins own); writes go through the executor.
10
+ */
11
+ export declare const makeStoreFacade: (runtime: PlanningRuntime, scope: PlanningScope) => PlanningFacade;
12
+ //# sourceMappingURL=facade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACI,cAAc,EAAE,aAAa,EAC5C,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAGnD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,YAAa,eAAe,SAAS,aAAa,KAAG,cA8IhF,CAAA"}