@astrale-os/sdk 0.6.0-beta.41 → 0.6.0-beta.43

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 (177) hide show
  1. package/README.md +22 -2
  2. package/dist/application/action/context.d.ts +49 -18
  3. package/dist/application/action/index.d.ts +1 -1
  4. package/dist/application/error/error.d.ts +16 -1
  5. package/dist/application/error/error.js +39 -5
  6. package/dist/application/error/index.d.ts +1 -1
  7. package/dist/application/error/index.js +1 -1
  8. package/dist/application/mutation/authoring/builder.d.ts +81 -33
  9. package/dist/application/mutation/authoring/builder.js +100 -30
  10. package/dist/application/mutation/authoring/guard.d.ts +37 -0
  11. package/dist/application/mutation/authoring/guard.js +150 -0
  12. package/dist/application/mutation/authoring/index.d.ts +5 -2
  13. package/dist/application/mutation/authoring/index.js +2 -1
  14. package/dist/application/mutation/authoring/names.d.ts +19 -0
  15. package/dist/application/mutation/authoring/names.js +83 -0
  16. package/dist/application/mutation/authoring/transition.d.ts +3 -2
  17. package/dist/application/mutation/define.d.ts +24 -10
  18. package/dist/application/mutation/define.js +49 -53
  19. package/dist/application/mutation/execution/execute.d.ts +2 -2
  20. package/dist/application/mutation/execution/execute.js +78 -7
  21. package/dist/application/mutation/execution/executor.d.ts +4 -1
  22. package/dist/application/mutation/execution/executor.js +6 -1
  23. package/dist/application/mutation/failure.d.ts +11 -1
  24. package/dist/application/mutation/failure.js +18 -3
  25. package/dist/application/mutation/index.d.ts +8 -4
  26. package/dist/application/mutation/index.js +5 -2
  27. package/dist/application/mutation/legacy/v6/builder.d.ts +84 -0
  28. package/dist/application/mutation/legacy/v6/define.d.ts +18 -0
  29. package/dist/application/mutation/legacy/v6/define.js +56 -0
  30. package/dist/application/mutation/legacy/v6/mutation.d.ts +28 -0
  31. package/dist/application/mutation/legacy/v6/mutation.js +1 -0
  32. package/dist/application/mutation/{authoring → legacy/v6}/precondition.d.ts +4 -0
  33. package/dist/application/mutation/mutation.d.ts +30 -19
  34. package/dist/application/query/answer/answer.d.ts +117 -0
  35. package/dist/application/query/answer/answer.js +1 -0
  36. package/dist/application/query/answer/conformance.d.ts +4 -0
  37. package/dist/application/query/answer/conformance.js +27 -0
  38. package/dist/application/query/answer/facts.d.ts +17 -0
  39. package/dist/application/query/answer/facts.js +57 -0
  40. package/dist/application/query/composite/builder.d.ts +1 -1
  41. package/dist/application/query/composite/builder.js +1 -1
  42. package/dist/application/query/composite/plan.d.ts +1 -1
  43. package/dist/application/query/composite/plan.js +1 -1
  44. package/dist/application/query/composite/query.d.ts +1 -2
  45. package/dist/application/query/define.d.ts +2 -33
  46. package/dist/application/query/define.js +3 -130
  47. package/dist/application/query/definition.d.ts +12 -0
  48. package/dist/application/query/definition.js +47 -0
  49. package/dist/application/query/execution/bounds.d.ts +22 -0
  50. package/dist/application/query/execution/bounds.js +88 -0
  51. package/dist/application/query/execution/crossings.d.ts +25 -0
  52. package/dist/application/query/execution/crossings.js +192 -0
  53. package/dist/application/query/execution/error.d.ts +68 -0
  54. package/dist/application/query/execution/error.js +50 -0
  55. package/dist/application/query/execution/execute.d.ts +2 -7
  56. package/dist/application/query/execution/execute.js +3 -51
  57. package/dist/application/query/execution/recipe.d.ts +85 -0
  58. package/dist/application/query/execution/recipe.js +324 -0
  59. package/dist/application/query/execution/refusal.d.ts +37 -0
  60. package/dist/application/query/execution/refusal.js +80 -0
  61. package/dist/application/query/execution/rows.d.ts +42 -0
  62. package/dist/application/query/execution/rows.js +308 -0
  63. package/dist/application/query/execution/split.d.ts +24 -0
  64. package/dist/application/query/execution/split.js +190 -0
  65. package/dist/application/query/handles/build.d.ts +10 -0
  66. package/dist/application/query/handles/build.js +53 -0
  67. package/dist/application/query/handles/conditions.d.ts +94 -0
  68. package/dist/application/query/handles/conditions.js +1 -0
  69. package/dist/application/query/handles/domain.d.ts +157 -0
  70. package/dist/application/query/handles/domain.js +1 -0
  71. package/dist/application/query/handles/handles.d.ts +268 -0
  72. package/dist/application/query/handles/handles.js +1 -0
  73. package/dist/application/query/handles/model.d.ts +96 -0
  74. package/dist/application/query/handles/model.js +246 -0
  75. package/dist/application/query/handles/plan.d.ts +99 -0
  76. package/dist/application/query/handles/plan.js +37 -0
  77. package/dist/application/query/handles/reads.d.ts +106 -0
  78. package/dist/application/query/handles/reads.js +839 -0
  79. package/dist/application/query/handles/relations.d.ts +100 -0
  80. package/dist/application/query/handles/relations.js +1 -0
  81. package/dist/application/query/handles/rows.d.ts +94 -0
  82. package/dist/application/query/handles/rows.js +4 -0
  83. package/dist/application/query/handles/terms.d.ts +103 -0
  84. package/dist/application/query/handles/terms.js +282 -0
  85. package/dist/application/query/index.d.ts +10 -7
  86. package/dist/application/query/index.js +9 -4
  87. package/dist/application/query/language/index.d.ts +2 -0
  88. package/dist/application/query/language/index.js +2 -0
  89. package/dist/application/query/language/query.d.ts +323 -0
  90. package/dist/application/query/language/query.js +2 -0
  91. package/dist/application/query/{collection → legacy/v6/collection}/identity.d.ts +2 -2
  92. package/dist/application/query/{collection → legacy/v6/collection}/metadata.d.ts +1 -1
  93. package/dist/application/query/{collection → legacy/v6/collection}/union.d.ts +3 -3
  94. package/dist/application/query/{collection → legacy/v6/collection}/union.js +1 -1
  95. package/dist/application/query/{conformance.d.ts → legacy/v6/conformance.d.ts} +3 -3
  96. package/dist/application/query/{conformance.js → legacy/v6/conformance.js} +1 -1
  97. package/dist/application/query/legacy/v6/define.d.ts +37 -0
  98. package/dist/application/query/legacy/v6/define.js +90 -0
  99. package/dist/application/query/legacy/v6/execution/execute.d.ts +16 -0
  100. package/dist/application/query/legacy/v6/execution/execute.js +50 -0
  101. package/dist/application/query/legacy/v6/index.d.ts +6 -0
  102. package/dist/application/query/legacy/v6/index.js +3 -0
  103. package/dist/application/query/legacy/v6/kernel.d.ts +6 -0
  104. package/dist/application/query/legacy/v6/kernel.js +5 -0
  105. package/dist/application/query/{single → legacy/v6/single}/pagination.js +1 -1
  106. package/dist/application/query/{single → legacy/v6/single}/query.d.ts +2 -14
  107. package/dist/application/query/legacy/v6/single/query.js +1 -0
  108. package/dist/application/query/query.d.ts +16 -1
  109. package/dist/application/query/recipe/define.d.ts +44 -0
  110. package/dist/application/query/recipe/define.js +95 -0
  111. package/dist/application/query/recipe/recipe.d.ts +134 -0
  112. package/dist/application/query/recipe/recipe.js +1 -0
  113. package/dist/application/workflow/durable.d.ts +22 -8
  114. package/dist/deployment/build/build.d.ts +8 -1
  115. package/dist/deployment/build/material.js +3 -0
  116. package/dist/execution/invocation/capabilities/bind.d.ts +6 -4
  117. package/dist/execution/invocation/capabilities/bind.js +39 -3
  118. package/dist/execution/invocation/dispatch/action.js +4 -2
  119. package/dist/execution/invocation/dispatch/context.js +1 -1
  120. package/dist/execution/invocation/dispatch/workflow.js +4 -2
  121. package/dist/execution/invocation/result/index.d.ts +1 -0
  122. package/dist/execution/invocation/result/index.js +1 -0
  123. package/dist/execution/invocation/result/recipe.d.ts +6 -0
  124. package/dist/execution/invocation/result/recipe.js +17 -0
  125. package/dist/execution/service/create.js +1 -0
  126. package/dist/execution/workflows/failure.d.ts +23 -6
  127. package/dist/execution/workflows/failure.js +78 -18
  128. package/dist/execution/workflows/receiver.d.ts +3 -0
  129. package/dist/execution/workflows/receiver.js +1 -0
  130. package/dist/execution/workflows/run.js +13 -9
  131. package/dist/execution/workflows/steps.d.ts +3 -0
  132. package/dist/execution/workflows/steps.js +2 -2
  133. package/dist/platform/schema/kernel-compiled.d.ts +2 -0
  134. package/dist/platform/schema/kernel-compiled.js +2 -0
  135. package/dist/testing/index.d.ts +2 -0
  136. package/dist/testing/index.js +1 -0
  137. package/dist/testing/recipe.d.ts +17 -0
  138. package/dist/testing/recipe.js +34 -0
  139. package/dist/tooling/cli/orchestrate.js +6 -2
  140. package/dist/tooling/linter/adapters/typescript/index.d.ts +2 -1
  141. package/dist/tooling/linter/adapters/typescript/index.js +2 -1
  142. package/dist/tooling/linter/adapters/typescript/query-observation.js +37 -12
  143. package/dist/tooling/linter/adapters/typescript/recipe-definitions.d.ts +34 -0
  144. package/dist/tooling/linter/adapters/typescript/recipe-definitions.js +88 -0
  145. package/dist/tooling/linter/adapters/typescript/type-analysis.d.ts +2 -0
  146. package/dist/tooling/linter/adapters/typescript/type-analysis.js +10 -0
  147. package/dist/tooling/linter/implementations/source/global.js +15 -9
  148. package/dist/tooling/linter/implementations/source/mutations.js +128 -19
  149. package/dist/tooling/linter/implementations/source/policy-edges.d.ts +2 -0
  150. package/dist/tooling/linter/implementations/source/policy-edges.js +113 -0
  151. package/dist/tooling/linter/implementations/source/recipes.d.ts +2 -0
  152. package/dist/tooling/linter/implementations/source/recipes.js +425 -0
  153. package/dist/tooling/linter/implementations/source/shared.d.ts +7 -1
  154. package/dist/tooling/linter/implementations/source/shared.js +31 -10
  155. package/dist/tooling/linter/implementations/source/verifiers.js +4 -0
  156. package/dist/tooling/linter/policy/generated.js +2 -2
  157. package/dist/tooling/linter/requirements/registry.js +4 -0
  158. package/docs/durable-workflows.md +48 -20
  159. package/docs/handler-dependencies.md +76 -4
  160. package/docs/legacy/query-v6.md +62 -0
  161. package/docs/queries.md +442 -0
  162. package/package.json +11 -8
  163. /package/dist/application/{query/single/query.js → mutation/legacy/v6/builder.js} +0 -0
  164. /package/dist/application/mutation/{authoring → legacy/v6}/precondition.js +0 -0
  165. /package/dist/application/query/{collection → legacy/v6/collection}/identity.js +0 -0
  166. /package/dist/application/query/{collection → legacy/v6/collection}/limits.d.ts +0 -0
  167. /package/dist/application/query/{collection → legacy/v6/collection}/limits.js +0 -0
  168. /package/dist/application/query/{collection → legacy/v6/collection}/metadata.js +0 -0
  169. /package/dist/application/query/{execution → legacy/v6/execution}/pages.d.ts +0 -0
  170. /package/dist/application/query/{execution → legacy/v6/execution}/pages.js +0 -0
  171. /package/dist/application/query/{single → legacy/v6/single}/index.d.ts +0 -0
  172. /package/dist/application/query/{single → legacy/v6/single}/index.js +0 -0
  173. /package/dist/application/query/{single → legacy/v6/single}/node.d.ts +0 -0
  174. /package/dist/application/query/{single → legacy/v6/single}/node.js +0 -0
  175. /package/dist/application/query/{single → legacy/v6/single}/pagination.d.ts +0 -0
  176. /package/dist/application/query/{single → legacy/v6/single}/selection.d.ts +0 -0
  177. /package/dist/application/query/{single → legacy/v6/single}/selection.js +0 -0
@@ -0,0 +1,246 @@
1
+ import { load } from '@astrale-os/kernel-dsl/v1/compiled/generated';
2
+ import { kernelCompiledSchema } from '../../../platform/schema/kernel-compiled.js';
3
+ /** The key of the graph's root Class, which every Node Class satisfies. */
4
+ export const NODE_ROOT = 'kernel.astrale.ai:class.Node';
5
+ /** An end names its relation only if it accepts specific Classes (S2). */
6
+ const GENERIC = new Set([NODE_ROOT, 'kernel.astrale.ai:class.Identity']);
7
+ const TO_ONE = new Set(['0..1', '1']);
8
+ /**
9
+ * Names a Node handle owns (`HandleMembers`): a Property of the same name goes under `$prop`. The
10
+ * list is frozen, as `SDK_KEYS` is, so no SDK release moves a Property or an owner group.
11
+ */
12
+ export const HANDLE_MEMBERS = new Set(['id', 'path', 'is', 'isExactly', 'via']);
13
+ /** The group of the Properties whose name a handle member, a row key or an Edge role takes. */
14
+ export const PROP_GROUP = '$prop';
15
+ /**
16
+ * The keys the SDK writes on rows besides `id` (`SdkKeys`), all named with `$`: `$class`, `$edge`
17
+ * on a row read `.withEdge()`, `$source` and `$target` on an Edge root's row, `$withheld` on a row
18
+ * the reader may not read, and the `$prop` group. Frozen; an owner group named as one of them
19
+ * goes under `$` and that name (`ownerGroup`).
20
+ */
21
+ export const SDK_KEYS = ['$class', '$edge', '$source', '$target', '$withheld', PROP_GROUP];
22
+ /**
23
+ * Names a row owns (`RowKeys`): `id` and the SDK's keys. A Property named `id` goes under `$prop`;
24
+ * no Property name starts with `$`. Frozen as `HANDLE_MEMBERS` is.
25
+ */
26
+ export const ROW_KEYS = new Set(['id', ...SDK_KEYS]);
27
+ const OWNER = /:class\.([^.]+)\.property\./;
28
+ let kernel;
29
+ /**
30
+ * The Kernel's Classes, realized once from its compiled Schema reduced to them: a Worker reaches
31
+ * them without the Kernel's builder or its Functions' value programs.
32
+ */
33
+ export function kernelClasses() {
34
+ kernel ??= load(JSON.parse(kernelCompiledSchema))
35
+ .classes;
36
+ return kernel;
37
+ }
38
+ /** The Class model of one resolved Domain. */
39
+ export class Model {
40
+ origin;
41
+ #byKey = new Map();
42
+ #edges = [];
43
+ #satisfied = new Map();
44
+ #ends = new Map();
45
+ #relations = new Map();
46
+ #layouts = new Map();
47
+ constructor(domain) {
48
+ this.origin = domain.origin;
49
+ const add = (c) => {
50
+ if (this.#byKey.has(c.key))
51
+ return;
52
+ this.#byKey.set(c.key, c);
53
+ if (c.kind === 'edge')
54
+ this.#edges.push(c);
55
+ };
56
+ Object.values(domain.classes).forEach(add);
57
+ for (const dependency of Object.values(domain.dependencies))
58
+ Object.values(dependency.classes).forEach(add);
59
+ Object.values(kernelClasses()).forEach(add);
60
+ }
61
+ /** One Class of the model, by key. */
62
+ classOf(key) {
63
+ const c = this.#byKey.get(key);
64
+ if (c === undefined)
65
+ throw new TypeError(`${key} is not a Class this Domain declares or depends on`);
66
+ return c;
67
+ }
68
+ /** The keys a Class satisfies: its own and its parents', transitively, and the graph root. */
69
+ satisfies(c) {
70
+ const cached = this.#satisfied.get(c.key);
71
+ if (cached !== undefined)
72
+ return cached;
73
+ const keys = new Set(c.kind === 'node' ? [NODE_ROOT] : []);
74
+ const walk = (k) => {
75
+ if (keys.has(k.key))
76
+ return;
77
+ keys.add(k.key);
78
+ for (const parent of k.extends)
79
+ walk(parent);
80
+ };
81
+ walk(c);
82
+ this.#satisfied.set(c.key, keys);
83
+ return keys;
84
+ }
85
+ /** Both ends of an Edge Class. */
86
+ ends(edge) {
87
+ const cached = this.#ends.get(edge.key);
88
+ if (cached !== undefined)
89
+ return cached;
90
+ if (edge.kind !== 'edge')
91
+ throw new TypeError(`${edge.key} is not an Edge Class`);
92
+ const endpoints = edge.definition.endpoints;
93
+ const [source, target] = Array.isArray(endpoints)
94
+ ? endpoints
95
+ : [
96
+ endpoints.source,
97
+ endpoints.target,
98
+ ];
99
+ const end = (e) => ({
100
+ role: e.role,
101
+ accepts: e.accepts.map((a) => `${a.origin}:class.${a.name}`),
102
+ count: e.outgoing ?? e.incoming ?? e.incident ?? '',
103
+ });
104
+ const ends = { source: end(source), target: end(target) };
105
+ this.#ends.set(edge.key, ends);
106
+ return ends;
107
+ }
108
+ /** The Classes an end accepts that the Domain can name. */
109
+ far(end) {
110
+ return end.accepts.flatMap((key) => this.#byKey.get(key) ?? []);
111
+ }
112
+ /** Whether an end accepts one of `classes`, or one of their parents. */
113
+ touches(classes, end) {
114
+ return classes.some((c) => end.accepts.some((key) => this.satisfies(c).has(key)));
115
+ }
116
+ /** The Classes a traversal of `edges` in `direction` reaches. */
117
+ reached(edges, direction) {
118
+ const out = new Set();
119
+ for (const edge of edges) {
120
+ const { source, target } = this.ends(edge);
121
+ if (direction !== 'incoming')
122
+ this.far(target).forEach((c) => out.add(c));
123
+ if (direction !== 'outgoing')
124
+ this.far(source).forEach((c) => out.add(c));
125
+ }
126
+ return [...out];
127
+ }
128
+ /** Every Property name of a Class, flat or grouped: a relation or a `.with` name avoids them. */
129
+ propertyNames(c) {
130
+ return new Set([...c.properties].map((p) => p.name));
131
+ }
132
+ /**
133
+ * The named to-one relations of a Class (S2): one per to-one end that accepts the Class or a
134
+ * parent, named by the far end's role when that end accepts specific Classes. The Domain's own
135
+ * relations shadow its dependencies'; a name that clashes with a Property or a handle member
136
+ * names nothing, and a name several ends claim is ambiguous.
137
+ */
138
+ relations(c) {
139
+ const cached = this.#relations.get(c.key);
140
+ if (cached !== undefined)
141
+ return cached;
142
+ const satisfied = this.satisfies(c);
143
+ const candidates = [];
144
+ const specific = (end) => !end.accepts.some((key) => GENERIC.has(key));
145
+ const accepts = (end) => end.accepts.some((key) => satisfied.has(key));
146
+ for (const edge of this.#edges) {
147
+ const { source, target } = this.ends(edge);
148
+ const own = edge.key.startsWith(`${this.origin}:`);
149
+ if (TO_ONE.has(source.count) && accepts(source) && specific(target))
150
+ candidates.push({
151
+ name: target.role,
152
+ edge,
153
+ direction: 'outgoing',
154
+ far: this.far(target),
155
+ own,
156
+ });
157
+ if (TO_ONE.has(target.count) && accepts(target) && specific(source))
158
+ candidates.push({
159
+ name: source.role,
160
+ edge,
161
+ direction: 'incoming',
162
+ far: this.far(source),
163
+ own,
164
+ });
165
+ }
166
+ const ownNames = new Set(candidates.filter((x) => x.own).map((x) => x.name));
167
+ const kept = candidates.filter((x) => x.own || !ownNames.has(x.name));
168
+ const taken = this.propertyNames(c);
169
+ const out = new Map();
170
+ for (const x of kept) {
171
+ if (taken.has(x.name) || HANDLE_MEMBERS.has(x.name))
172
+ continue;
173
+ const previous = out.get(x.name);
174
+ if (previous === undefined)
175
+ out.set(x.name, x);
176
+ else if ('ambiguous' in previous || !sameRelation(previous, x))
177
+ out.set(x.name, { name: x.name, ambiguous: true });
178
+ }
179
+ this.#relations.set(c.key, out);
180
+ return out;
181
+ }
182
+ /**
183
+ * Where each Property of a Class goes when `taken` names are a row's or a handle's (F6). A name
184
+ * keeps its only Property, or the Class's own among inherited duplicates: flat, or under
185
+ * `$prop` when the name is taken. Each duplicate it does not keep goes under its owner.
186
+ */
187
+ layout(c, taken) {
188
+ const id = `${c.key}\u0000${[...taken].sort().join(',')}`;
189
+ const cached = this.#layouts.get(id);
190
+ if (cached !== undefined)
191
+ return cached;
192
+ const byName = new Map();
193
+ for (const p of c.properties) {
194
+ const keys = byName.get(p.name) ?? [];
195
+ if (!keys.includes(p.key))
196
+ keys.push(p.key);
197
+ byName.set(p.name, keys);
198
+ }
199
+ const flat = new Map();
200
+ const groups = new Map();
201
+ const add = (group, name, key) => {
202
+ const members = groups.get(group) ?? new Map();
203
+ members.set(name, key);
204
+ groups.set(group, members);
205
+ };
206
+ for (const [name, keys] of byName) {
207
+ const own = keys.filter((key) => key.startsWith(`${c.key}.property.`));
208
+ const kept = keys.length === 1 ? keys[0] : own.length === 1 ? own[0] : undefined;
209
+ if (kept !== undefined && taken.has(name))
210
+ add(PROP_GROUP, name, kept);
211
+ else if (kept !== undefined)
212
+ flat.set(name, kept);
213
+ for (const key of keys) {
214
+ const owner = key === kept ? undefined : OWNER.exec(key)?.[1];
215
+ if (owner !== undefined)
216
+ add(ownerGroup(owner), name, key);
217
+ }
218
+ }
219
+ const layout = { flat, groups };
220
+ this.#layouts.set(id, layout);
221
+ return layout;
222
+ }
223
+ }
224
+ /**
225
+ * The group of an owner's duplicates: `$` and its name in lower camel case, escaped with one more
226
+ * `$` when that is one of the SDK's keys: an owner named `Class` groups under `$$class`
227
+ * (`OwnerGroup`).
228
+ */
229
+ function ownerGroup(owner) {
230
+ const group = `$${owner.charAt(0).toLowerCase()}${owner.slice(1)}`;
231
+ return SDK_KEYS.some((key) => key === group) ? `$${group}` : group;
232
+ }
233
+ /** Two candidates the types see as one: the same name, Edge and far Classes. */
234
+ function sameRelation(a, b) {
235
+ return a.edge === b.edge && a.far.length === b.far.length && a.far.every((c, i) => c === b.far[i]);
236
+ }
237
+ const models = new WeakMap();
238
+ /** The Class model of a resolved Domain, built once. */
239
+ export function modelOf(domain) {
240
+ let model = models.get(domain);
241
+ if (model === undefined) {
242
+ model = new Model(domain);
243
+ models.set(domain, model);
244
+ }
245
+ return model;
246
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * What a read lowers to: its canonical v7 document, and the plan the recipe runtime answers it
3
+ * by (WP-S3): the verb, its bound, and for each pattern the Classes its rows may be, how they
4
+ * render and the relations they carry. A read whose condition can match nothing is `empty`: it
5
+ * has no document, and the runtime answers it without sending. When the input folds a condition
6
+ * (an empty list), the read keeps its document as written: the one S12 checks.
7
+ */
8
+ import type { AnyQuery } from '../language/query.js';
9
+ import type { Scope } from './terms.js';
10
+ /** The verbs of a root read; `document` is the escape hatch (D23). */
11
+ export type Verb = 'get' | 'find' | 'first' | 'firstN' | 'firstMore' | 'page' | 'all' | 'exists' | 'count' | 'document';
12
+ /** The verbs of a relation, per parent. */
13
+ export type RelationVerb = 'get' | 'find' | 'first' | 'firstN' | 'all' | 'exists' | 'count';
14
+ export type Rendering = 'value' | 'reference';
15
+ /** How a pattern's rows are answered. */
16
+ export interface Pattern {
17
+ /** The keys of the Classes its rows may be, after narrowing (S3): the layout of each row. */
18
+ readonly classes: readonly string[];
19
+ readonly select: Rendering;
20
+ /** Rows the reader may not read stay, as `{ id, $class, $withheld }`. */
21
+ readonly withheld: boolean;
22
+ readonly branches: readonly BranchPlan[];
23
+ }
24
+ /** A relation a row carries, under its `.with` key. */
25
+ export interface BranchPlan extends Pattern {
26
+ /** The `.with` key the answer goes under. */
27
+ readonly key: string;
28
+ /** The Branch's name in the document. */
29
+ readonly name: string;
30
+ /** The relation as an integrity error names it: its name, or `via(<Edge keys>)`. */
31
+ readonly relation: string;
32
+ readonly verb: RelationVerb;
33
+ /** `first(n)`: n; `all`: max; `count`: upTo. */
34
+ readonly bound?: number;
35
+ /** Its condition matches nothing: it is not sent, and every parent gets the empty answer. */
36
+ readonly empty: boolean;
37
+ /** Each row carries `$edge` (`.withEdge()`). */
38
+ readonly edge: boolean;
39
+ }
40
+ export interface NodeRootPlan extends Pattern {
41
+ readonly kind: 'nodes';
42
+ }
43
+ /** One end of an Edge root: its role on the rows, and the Classes it accepts. */
44
+ export interface EndPlan {
45
+ readonly role: string;
46
+ readonly classes: readonly string[];
47
+ }
48
+ export interface EdgeRootPlan {
49
+ readonly kind: 'edges';
50
+ readonly classes: readonly string[];
51
+ readonly select: Rendering;
52
+ readonly withheld: boolean;
53
+ readonly source: EndPlan;
54
+ readonly target: EndPlan;
55
+ }
56
+ /** The plan of a root read. */
57
+ export interface ReadPlan {
58
+ readonly verb: Verb;
59
+ /** `first(n)` and `first(n, { more })`: n; `page` and `all`: max; `count`: upTo. */
60
+ readonly bound?: number;
61
+ /** Its condition matches nothing: answered without sending. */
62
+ readonly empty: boolean;
63
+ /** Absent when `empty`. */
64
+ readonly document?: AnyQuery;
65
+ /** The document as written, when the input folds it: as no empty list folds it. */
66
+ readonly written?: AnyQuery;
67
+ /** Absent for `document`, whose rows are unknown. */
68
+ readonly root?: NodeRootPlan | EdgeRootPlan;
69
+ /** The id or path `get`, `find` or `exists` was given, as `NOT_FOUND` names it. */
70
+ readonly target?: string;
71
+ }
72
+ /** A read of a root: what a verb on a Class handle, or `d.document`, returns. */
73
+ export declare class RootRead {
74
+ readonly plan: ReadPlan;
75
+ constructor(plan: ReadPlan);
76
+ }
77
+ /** A Branch of a document and its plan, once its parent names it. */
78
+ export interface LoweredBranch {
79
+ readonly plan: BranchPlan;
80
+ /** Absent when the plan is `empty`. */
81
+ readonly branch?: Readonly<Record<string, unknown>>;
82
+ /** The Branch as written, when the input folds it or a Branch under it. */
83
+ readonly written?: Readonly<Record<string, unknown>>;
84
+ }
85
+ /** A read of a relation, per parent: what a `.with` takes. */
86
+ export declare class RelationRead {
87
+ /** The handle it was read from: a `.with` takes only its own handle's relations. */
88
+ readonly scope: Scope;
89
+ readonly lower: (key: string, name: string) => LoweredBranch;
90
+ constructor(
91
+ /** The handle it was read from: a `.with` takes only its own handle's relations. */
92
+ scope: Scope, lower: (key: string, name: string) => LoweredBranch);
93
+ }
94
+ /** Whether a value is a read a recipe runs (a root read). */
95
+ export declare function isRead(value: unknown): value is RootRead;
96
+ /** The plan of a root read. */
97
+ export declare function planOf(read: unknown): ReadPlan;
98
+ /** The canonical document of a root read; an `empty` read has none. */
99
+ export declare function lower(read: unknown): AnyQuery | undefined;
@@ -0,0 +1,37 @@
1
+ /** A read of a root: what a verb on a Class handle, or `d.document`, returns. */
2
+ export class RootRead {
3
+ plan;
4
+ constructor(plan) {
5
+ this.plan = plan;
6
+ Object.freeze(this);
7
+ }
8
+ }
9
+ /** A read of a relation, per parent: what a `.with` takes. */
10
+ export class RelationRead {
11
+ scope;
12
+ lower;
13
+ constructor(
14
+ /** The handle it was read from: a `.with` takes only its own handle's relations. */
15
+ scope, lower) {
16
+ this.scope = scope;
17
+ this.lower = lower;
18
+ Object.freeze(this);
19
+ }
20
+ }
21
+ /** Whether a value is a read a recipe runs (a root read). */
22
+ export function isRead(value) {
23
+ return value instanceof RootRead;
24
+ }
25
+ /** The plan of a root read. */
26
+ export function planOf(read) {
27
+ if (!(read instanceof RootRead)) {
28
+ if (read instanceof RelationRead)
29
+ throw new TypeError('A relation read is answered per parent: read it inside a `.with`.');
30
+ throw new TypeError('Not a read: a read ends with a verb (get, find, first, page, all, exists, count).');
31
+ }
32
+ return read.plan;
33
+ }
34
+ /** The canonical document of a root read; an `empty` read has none. */
35
+ export function lower(read) {
36
+ return planOf(read).document;
37
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The handles' runtime: Node, relation and Edge sets, and the handles their callbacks receive.
3
+ * Each verb lowers its read to canonical v7 JSON and a plan (`plan.ts`). Sets are immutable:
4
+ * every method returns a new set.
5
+ */
6
+ import type { AnyResolvedClass } from '../../../platform/schema/index.js';
7
+ import type { Direction, Model } from './model.js';
8
+ import type { Context } from './terms.js';
9
+ import { RelationRead, RootRead } from './plan.js';
10
+ import { Condition } from './terms.js';
11
+ /**
12
+ * The one Class a Class handle names, as a write takes it: `d.<Class>`, on which no method was
13
+ * called. `undefined` for a value that is no set of roots.
14
+ */
15
+ export declare function handleClass(value: unknown): AnyResolvedClass | undefined;
16
+ /**
17
+ * A guard's range (S7), the roots of a Class handle after `where`, `union` and `orderBy`, as a
18
+ * read: of whether one exists, or, `ordered`, of them in their order. `undefined` for a value that
19
+ * is no set of roots; a set whose rows render (`with`, `pick`, `includeWithheld`) is refused.
20
+ */
21
+ export declare function rangeRead(value: unknown, ordered: boolean): RootRead | undefined;
22
+ /** A Node handle: its Properties, its named to-one relations, and the methods every Node has. */
23
+ export declare function nodeHandle(model: Model, classes: readonly AnyResolvedClass[], context: Context): object;
24
+ /** A condition that is also a relation read: `exists()` is a boolean in `.with`. */
25
+ declare class Exists extends Condition {
26
+ readonly read: RelationRead;
27
+ constructor(condition: Condition, read: RelationRead);
28
+ }
29
+ /** A relation from a Node: the Nodes at the far end of its Edges. */
30
+ export declare class Relation {
31
+ #private;
32
+ private constructor();
33
+ static of(model: Model, name: string, edges: readonly AnyResolvedClass[], direction: Direction, far: readonly AnyResolvedClass[], context: Context): Relation;
34
+ where(conditions: unknown): Relation;
35
+ orderBy(keys: unknown): Relation;
36
+ with(relations: unknown): Relation;
37
+ withEdge(): Relation;
38
+ pick(): Relation;
39
+ includeWithheld(): Relation;
40
+ distinct(): Relation;
41
+ /** Exactly one per parent: two rows, to see a second. */
42
+ get(): RelationRead;
43
+ find(): RelationRead;
44
+ first(n?: unknown): RelationRead;
45
+ all(written: unknown): RelationRead;
46
+ count(written: unknown): RelationRead;
47
+ /** A boolean per parent in a `.with`; a condition in a `where`. */
48
+ exists(): Exists;
49
+ /** The relation reaches this Node. */
50
+ is(target: unknown): Condition;
51
+ some(conditions?: unknown): Condition;
52
+ none(conditions?: unknown): Condition;
53
+ atLeast(n: unknown, conditions?: unknown): Condition;
54
+ atMost(n: unknown, conditions?: unknown): Condition;
55
+ exactly(n: unknown, conditions?: unknown): Condition;
56
+ /** No Edge of the relation fails the conditions: `none` of their negation, on one side. */
57
+ every(conditions: unknown): Condition;
58
+ }
59
+ /** The Nodes of a Class, or of a union of Classes, at the root of a read. */
60
+ export declare class NodeSet {
61
+ #private;
62
+ private constructor();
63
+ static of(model: Model, cls: AnyResolvedClass): NodeSet;
64
+ /** Its Classes, after narrowing. */
65
+ get classes(): readonly AnyResolvedClass[];
66
+ /** No method was called on it but `union`: a Class handle, as `is` and `union` take one. */
67
+ get pristine(): boolean;
68
+ /** The range a guard reads (S7); a set whose rows render is none. */
69
+ static range(set: NodeSet, ordered: boolean): RootRead;
70
+ where(conditions: unknown): NodeSet;
71
+ orderBy(keys: unknown): NodeSet;
72
+ with(relations: unknown): NodeSet;
73
+ pick(): NodeSet;
74
+ includeWithheld(): NodeSet;
75
+ union(other: unknown): NodeSet;
76
+ /** Exactly one: two rows, to see a second. */
77
+ get(id?: unknown): RootRead;
78
+ find(id?: unknown): RootRead;
79
+ first(n?: unknown, written?: unknown): RootRead;
80
+ page(written: unknown): RootRead;
81
+ all(written: unknown): RootRead;
82
+ exists(id?: unknown): RootRead;
83
+ count(written: unknown): RootRead;
84
+ }
85
+ /** The Edges of a Class at the root of a read: its Properties, and both ends by role. */
86
+ export declare class EdgeSet {
87
+ #private;
88
+ private constructor();
89
+ static of(model: Model, edge: AnyResolvedClass): EdgeSet;
90
+ get edge(): AnyResolvedClass;
91
+ get pristine(): boolean;
92
+ /** The range a guard reads (S7); a set whose rows render is none. */
93
+ static range(set: EdgeSet, ordered: boolean): RootRead;
94
+ where(conditions: unknown): EdgeSet;
95
+ orderBy(keys: unknown): EdgeSet;
96
+ pick(): EdgeSet;
97
+ includeWithheld(): EdgeSet;
98
+ get(): RootRead;
99
+ find(): RootRead;
100
+ first(n?: unknown): RootRead;
101
+ page(written: unknown): RootRead;
102
+ all(written: unknown): RootRead;
103
+ exists(): RootRead;
104
+ count(written: unknown): RootRead;
105
+ }
106
+ export {};