@metreeca/keep-sparql 0.10.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 (71) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +106 -0
  3. package/dist/_/_decode.d.ts +20 -0
  4. package/dist/_/_decode.d.ts.map +1 -0
  5. package/dist/_/_decode.js +55 -0
  6. package/dist/_/_decode.js.map +1 -0
  7. package/dist/_/_encode.d.ts +112 -0
  8. package/dist/_/_encode.d.ts.map +1 -0
  9. package/dist/_/_encode.js +262 -0
  10. package/dist/_/_encode.js.map +1 -0
  11. package/dist/_/_flake.d.ts +16 -0
  12. package/dist/_/_flake.d.ts.map +1 -0
  13. package/dist/_/_flake.js +65 -0
  14. package/dist/_/_flake.js.map +1 -0
  15. package/dist/_/_union.d.ts +28 -0
  16. package/dist/_/_union.d.ts.map +1 -0
  17. package/dist/_/_union.js +51 -0
  18. package/dist/_/_union.js.map +1 -0
  19. package/dist/detect/decode.d.ts +25 -0
  20. package/dist/detect/decode.d.ts.map +1 -0
  21. package/dist/detect/decode.js +34 -0
  22. package/dist/detect/decode.js.map +1 -0
  23. package/dist/detect/encode.d.ts +25 -0
  24. package/dist/detect/encode.d.ts.map +1 -0
  25. package/dist/detect/encode.js +30 -0
  26. package/dist/detect/encode.js.map +1 -0
  27. package/dist/detect/index.d.ts +17 -0
  28. package/dist/detect/index.d.ts.map +1 -0
  29. package/dist/detect/index.js +55 -0
  30. package/dist/detect/index.js.map +1 -0
  31. package/dist/index.d.ts +95 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +70 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/lookup/decode.d.ts +33 -0
  36. package/dist/lookup/decode.d.ts.map +1 -0
  37. package/dist/lookup/decode.js +193 -0
  38. package/dist/lookup/decode.js.map +1 -0
  39. package/dist/lookup/encode.d.ts +46 -0
  40. package/dist/lookup/encode.d.ts.map +1 -0
  41. package/dist/lookup/encode.js +111 -0
  42. package/dist/lookup/encode.js.map +1 -0
  43. package/dist/lookup/index.d.ts +21 -0
  44. package/dist/lookup/index.d.ts.map +1 -0
  45. package/dist/lookup/index.js +72 -0
  46. package/dist/lookup/index.js.map +1 -0
  47. package/dist/modify/decode.d.ts +22 -0
  48. package/dist/modify/decode.d.ts.map +1 -0
  49. package/dist/modify/decode.js +26 -0
  50. package/dist/modify/decode.js.map +1 -0
  51. package/dist/modify/encode.d.ts +21 -0
  52. package/dist/modify/encode.d.ts.map +1 -0
  53. package/dist/modify/encode.js +184 -0
  54. package/dist/modify/encode.js.map +1 -0
  55. package/dist/modify/index.d.ts +22 -0
  56. package/dist/modify/index.d.ts.map +1 -0
  57. package/dist/modify/index.js +44 -0
  58. package/dist/modify/index.js.map +1 -0
  59. package/dist/select/decode.d.ts +16 -0
  60. package/dist/select/decode.d.ts.map +1 -0
  61. package/dist/select/decode.js +229 -0
  62. package/dist/select/decode.js.map +1 -0
  63. package/dist/select/encode.d.ts +16 -0
  64. package/dist/select/encode.d.ts.map +1 -0
  65. package/dist/select/encode.js +434 -0
  66. package/dist/select/encode.js.map +1 -0
  67. package/dist/select/index.d.ts +16 -0
  68. package/dist/select/index.d.ts.map +1 -0
  69. package/dist/select/index.js +38 -0
  70. package/dist/select/index.js.map +1 -0
  71. package/package.json +68 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/lookup/encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { Broker, Deferred, Lookup } from "@metreeca/keep/batching";
2
+ import { type RepositoryClient } from "@metreeca/wire-sparql";
3
+ /**
4
+ * Per-batch body for the lookup handler.
5
+ *
6
+ * Three phases run in sequence: **plan** every request via
7
+ * {@link _flake_!createFlake | createFlake}; **fetch** by
8
+ * folding plans into one batched SELECT through {@link encode}; **deliver** by
9
+ * {@link decode | decoding} each request against the returned tuples and settling the
10
+ * deferred. Variable allocation across the batched
11
+ * SELECT is shared via a single {@link createScope | Scope} passed into {@link encode}, so
12
+ * the decoder recovers each request's per-slot columns by resolving the same branch nodes.
13
+ *
14
+ * Items whose flake carries no top-level descent branch are filtered out of the fetch
15
+ * phase (their arms would be empty), and the fetch is skipped entirely when no item
16
+ * contributes anything. They still flow through the deliver phase, where {@link decode}
17
+ * yields `id` / `type` entries inline from the focus and shape and routes set-valued
18
+ * slots through the collections pass.
19
+ */
20
+ export declare function lookup(batch: readonly Deferred<Lookup>[], client: RepositoryClient, broker: Broker): Promise<void>;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lookup/index.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,uBAAuB,CAAC;AAKtF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,MAAM,CAC3B,KAAK,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,gBAAgB,EACxB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright © 2025-2026 Metreeca srl
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Resources-pass driver.
18
+ *
19
+ * Owns one SELECT round per drain iteration covering every queued
20
+ * {@link Lookup}. The cycle is:
21
+ *
22
+ * **plan** → **encode** → `client.select` → **decode**
23
+ *
24
+ * - {@link _flake_!createFlake | createFlake} builds the per-request lookup plan
25
+ * ({@link Flake} IR) from `(shape, model)`;
26
+ * - {@link encode} folds every plan into one batched SELECT whose WHERE is a union of
27
+ * arms, coordinated with the decoder through the shared {@link Scope};
28
+ * - `client.select` runs the unified query;
29
+ * - {@link decode} walks each request's plan alongside the returned tuples, decoding
30
+ * single-valued slots inline and forwarding set-valued slots to the collections
31
+ * pass through {@link select}.
32
+ *
33
+ * Multi-valued slots are forwarded to the collections pass through the supplied
34
+ * {@link Broker}, the only cross-pass communication channel admitted by this module.
35
+ * Decoding chains the deferred's resolution through the returned promise so the handler
36
+ * can return promptly and let the drain advance to the collections pass within the same
37
+ * iteration.
38
+ *
39
+ * @module
40
+ */
41
+ import { eager } from "@metreeca/blue/value";
42
+ import { createScope } from "@metreeca/core/scope";
43
+ import { createFlake, isModelBranch } from "@metreeca/keep-flake";
44
+ import { variable as toVariable } from "@metreeca/wire-sparql";
45
+ import { decode } from "./decode.js";
46
+ import { encode } from "./encode.js";
47
+ /**
48
+ * Per-batch body for the lookup handler.
49
+ *
50
+ * Three phases run in sequence: **plan** every request via
51
+ * {@link _flake_!createFlake | createFlake}; **fetch** by
52
+ * folding plans into one batched SELECT through {@link encode}; **deliver** by
53
+ * {@link decode | decoding} each request against the returned tuples and settling the
54
+ * deferred. Variable allocation across the batched
55
+ * SELECT is shared via a single {@link createScope | Scope} passed into {@link encode}, so
56
+ * the decoder recovers each request's per-slot columns by resolving the same branch nodes.
57
+ *
58
+ * Items whose flake carries no top-level descent branch are filtered out of the fetch
59
+ * phase (their arms would be empty), and the fetch is skipped entirely when no item
60
+ * contributes anything. They still flow through the deliver phase, where {@link decode}
61
+ * yields `id` / `type` entries inline from the focus and shape and routes set-valued
62
+ * slots through the collections pass.
63
+ */
64
+ export async function lookup(batch, client, broker) {
65
+ const scope = createScope(toVariable);
66
+ const items = batch.map(lookup => ({ ...lookup, flake: createFlake(eager(lookup.request.shape), lookup.request.model) }));
67
+ // drop items whose union arm would be empty (only id/type or collection slots) from the fetch;
68
+ // they still flow through delivery, where decode yields id/type inline and routes collections
69
+ const effective = items.filter(({ flake }) => Object.values(flake.entries ?? {}).flat().some(isModelBranch));
70
+ decode(scope, items, broker, effective.length === 0 ? [] : await client.select(encode(scope, effective)));
71
+ }
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lookup/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAc,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE9E,OAAO,EAAyB,QAAQ,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC3B,KAAkC,EAClC,MAAwB,EACxB,MAAc;IAGd,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAChC,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CACtF,CAAC;IAEF,+FAA+F;IAC/F,8FAA8F;IAE9F,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAC5C,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAC7D,CAAC;IAEF,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,MAAM,CAC7E,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CACxB,CAAC,CAAC;AAEJ,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Modify-pass result decoder.
3
+ *
4
+ * Settles each queued {@link Modify} once the batched update has been applied: every request's
5
+ * deferred resolves to its own `entry`, the mutation having already been folded into the single
6
+ * update the encoder emitted. A SPARQL Update projects no bindings, so there is nothing to read
7
+ * back; the decoder exists to keep the drive cycle uniform with the query passes.
8
+ *
9
+ * @module
10
+ */
11
+ import type { Scope } from "@metreeca/core/scope";
12
+ import type { Deferred, Modify } from "@metreeca/keep/batching";
13
+ import type { Variable } from "@metreeca/wire-sparql";
14
+ /**
15
+ * Resolves each applied modify request to its entry.
16
+ *
17
+ * @param scope The shared variable scope, unused: the update projects no bindings
18
+ * @param batch The queued modify requests to settle, each carrying the `request` whose `entry` is returned
19
+ * @param value The update result, unused: a SPARQL Update yields no solution
20
+ */
21
+ export declare function decode(scope: Scope<Variable>, batch: readonly Deferred<Modify>[], value: void): void;
22
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/modify/decode.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD;;;;;;GAMG;AACH,wBAAgB,MAAM,CACrB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,EACtB,KAAK,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,EAAE,EAClC,KAAK,EAAE,IAAI,GACT,IAAI,CAMN"}
@@ -0,0 +1,26 @@
1
+ /*
2
+ * Copyright © 2025-2026 Metreeca srl
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ /**
17
+ * Resolves each applied modify request to its entry.
18
+ *
19
+ * @param scope The shared variable scope, unused: the update projects no bindings
20
+ * @param batch The queued modify requests to settle, each carrying the `request` whose `entry` is returned
21
+ * @param value The update result, unused: a SPARQL Update yields no solution
22
+ */
23
+ export function decode(scope, batch, value) {
24
+ batch.forEach(({ request, resolve }) => resolve(request.entry));
25
+ }
26
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/modify/decode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CACrB,KAAsB,EACtB,KAAkC,EAClC,KAAW;IAGX,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CACtC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CACtB,CAAC;AAEH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { Scope } from "@metreeca/core/scope";
2
+ import { type Flake } from "@metreeca/keep-flake";
3
+ import type { Deferred, Modify } from "@metreeca/keep/batching";
4
+ import { type SPARQL, type Variable } from "@metreeca/wire-sparql";
5
+ /**
6
+ * Emits a single batched SPARQL Update covering every supplied request.
7
+ *
8
+ * Each request is dispatched by the presence of its `state`: a present `state` produces a
9
+ * cleanup-and-insert statement, an omitted `state` a cascade delete. The per-request statements are
10
+ * joined into one update applied in submission order.
11
+ *
12
+ * @param scope The variable allocator shared across every request's cleanup walk, keyed on
13
+ * {@link Branch} identity
14
+ * @param batch The batched root entries paired with their {@link Flake | mutation plans}
15
+ *
16
+ * @returns The unified SPARQL Update query
17
+ */
18
+ export declare function encode(scope: Scope<Variable>, batch: readonly (Deferred<Modify> & {
19
+ readonly flake: Flake;
20
+ })[]): SPARQL;
21
+ //# sourceMappingURL=encode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.d.ts","sourceRoot":"","sources":["../../src/modify/encode.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAe,KAAK,KAAK,EAAmB,MAAM,sBAAsB,CAAC;AAChF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAIhE,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAkBnE;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CACrB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,EACtB,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,CAAC,EAAE,GAC9D,MAAM,CAkQR"}
@@ -0,0 +1,184 @@
1
+ /*
2
+ * Copyright © 2025-2026 Metreeca srl
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { getShapeVariants, getStateVariant } from "@metreeca/blue/union";
17
+ import { isObject, opt } from "@metreeca/core";
18
+ import { some } from "@metreeca/core/arrays";
19
+ import { getFlakeVariant } from "@metreeca/keep-flake";
20
+ import { isVacuous } from "@metreeca/qest/template";
21
+ import { named, rdf } from "@metreeca/trio";
22
+ import { deleet, fragment, insert as create, nil, optional, pattern, reference, union, update, values, variable, where } from "@metreeca/wire-sparql/builder";
23
+ import { forward, reverse, valuesToTerms } from "../_/_encode.js";
24
+ /**
25
+ * Emits a single batched SPARQL Update covering every supplied request.
26
+ *
27
+ * Each request is dispatched by the presence of its `state`: a present `state` produces a
28
+ * cleanup-and-insert statement, an omitted `state` a cascade delete. The per-request statements are
29
+ * joined into one update applied in submission order.
30
+ *
31
+ * @param scope The variable allocator shared across every request's cleanup walk, keyed on
32
+ * {@link Branch} identity
33
+ * @param batch The batched root entries paired with their {@link Flake | mutation plans}
34
+ *
35
+ * @returns The unified SPARQL Update query
36
+ */
37
+ export function encode(scope, batch) {
38
+ return update(...batch.map(({ request: { entry, state }, flake }) => state === undefined
39
+ ? remove(entry, flake)
40
+ : insert(entry, flake, state)));
41
+ function insert(entry, flake, state) {
42
+ return update(deleet(triples(named(entry), flake), where(matches(named(entry), flake))), create(data(entry, flake, state)));
43
+ function triples(entry, flake) {
44
+ return fragment(...flake.range.variants.flatMap(shape => shape.kind !== "resource" ? [] : [fragment(isTyped(shape) ? pattern([entry, named(rdf.type), scope.resolve(shape)]) : nil(), ...getFlakeVariant(flake, shape).flatMap(branch => {
45
+ const property = branch.entry;
46
+ if (property.kind === "property" && isOwn(property.range.shape)) {
47
+ const v = scope.resolve(branch);
48
+ return [
49
+ forward([entry, property, v]),
50
+ reverse([entry, property, v]),
51
+ triples(v, branch) // only embedded resources recurse; references are written separately
52
+ ];
53
+ }
54
+ else {
55
+ return [];
56
+ }
57
+ }))]));
58
+ }
59
+ function matches(entry, flake) {
60
+ return fragment(...flake.range.variants.flatMap(shape => shape.kind !== "resource" ? [] : [fragment(isTyped(shape) ? optional(pattern([entry, named(rdf.type), scope.resolve(shape)])) : nil(), ...getFlakeVariant(flake, shape).flatMap(branch => {
61
+ const property = branch.entry;
62
+ if (property.kind === "property" && isOwn(property.range.shape)) {
63
+ const v = scope.resolve(branch);
64
+ const edges = fragment(forward([entry, property, v]), reverse([entry, property, v]));
65
+ return [
66
+ ...(getShapeVariants(property.range.shape).some(variant => variant.kind === "resource")
67
+ ? [optional(edges, matches(v, branch))] // only embedded resources recurse
68
+ : []),
69
+ ...(isLeaf(property.range.shape)
70
+ ? [optional(edges)]
71
+ : [])
72
+ ];
73
+ }
74
+ else {
75
+ return [];
76
+ }
77
+ }))]));
78
+ }
79
+ function data(entry, flake, state) {
80
+ const shape = getStateVariant(state, flake.range.variants);
81
+ return shape === undefined || shape.kind !== "resource" ? nil() : record(named(entry), shape, state);
82
+ function record(entry, shape, state) {
83
+ // denormalise the class lineage as `rdf:type` triples — own `class` plus inherited `classes` —
84
+ // so an exact-match query on any supertype reaches the instance (class-lineage retrieval)
85
+ return fragment(shape.class !== undefined ? pattern([entry, named(rdf.type), named(shape.class)]) : nil(), ...(shape.classes ?? []).map(clazz => pattern([entry, named(rdf.type), named(clazz)])), ...Object.entries(shape.entries).flatMap(([label, property]) => {
86
+ const values = state[label];
87
+ if (property.kind === "property" && values !== undefined) {
88
+ const variants = getShapeVariants(property.range.shape);
89
+ return some(values)
90
+ .filter(value => !isVacuous(value))
91
+ .flatMap(value => opt(getStateVariant(value, variants), variant => triples(property, value, variant), []));
92
+ }
93
+ else {
94
+ return [];
95
+ }
96
+ }));
97
+ function triples(property, values, shape) {
98
+ switch (shape.kind) {
99
+ case "boolean":
100
+ case "number":
101
+ case "string":
102
+ case "dictionary":
103
+ return valuesToTerms(values, shape).map(term => forward([entry, property, term]));
104
+ case "reference":
105
+ if (shape.foreign === true) {
106
+ return [];
107
+ }
108
+ else {
109
+ return valuesToTerms(values, shape).filter(node => node.kind === "named").flatMap(node => [
110
+ forward([entry, property, node]),
111
+ reverse([entry, property, node])
112
+ ]);
113
+ }
114
+ case "resource":
115
+ if (!isObject(values)) {
116
+ return [];
117
+ }
118
+ else {
119
+ return valuesToTerms(values, shape).filter(node => node.kind === "named").flatMap(node => [
120
+ forward([entry, property, node]),
121
+ reverse([entry, property, node]),
122
+ record(node, shape, values)
123
+ ]);
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ function remove(entry, flake) {
131
+ const branches = Object.values(flake.entries ?? {}).flat();
132
+ const root = scope.resolve();
133
+ // wildcard patterns matching every triple incident on `?root` (outgoing then incoming),
134
+ // resolved once so the same variables bind in both the DELETE template and the WHERE match
135
+ const wildcard = [
136
+ pattern([root, scope.resolve(), scope.resolve()]),
137
+ pattern([scope.resolve(), scope.resolve(), root])
138
+ ];
139
+ return deleet(fragment(...wildcard), where(union(values([variable(root)], [[reference(entry)]]), ...matches(named(entry), [], branches)), union(...wildcard)));
140
+ function matches(anchor, prefix, level) {
141
+ return level.flatMap(branch => {
142
+ if (branch.entry.kind === "property" && isCascading(branch.entry.range.shape)) {
143
+ const property = branch.entry;
144
+ const here = fragment(...prefix, forward([anchor, property, root]), reverse([anchor, property, root]));
145
+ const perVariant = getShapeVariants(property.range.shape)
146
+ .map(variant => getFlakeVariant(branch, variant))
147
+ .filter(bs => bs.length > 0);
148
+ if (perVariant.length === 0) {
149
+ return [here];
150
+ }
151
+ else {
152
+ const next = scope.resolve();
153
+ const step = [
154
+ ...prefix,
155
+ forward([anchor, property, next]),
156
+ reverse([anchor, property, next])
157
+ ];
158
+ return [here, ...perVariant.flatMap(bs => matches(next, step, bs))];
159
+ }
160
+ }
161
+ else {
162
+ return [];
163
+ }
164
+ });
165
+ }
166
+ }
167
+ function isTyped(shape) {
168
+ return shape.kind === "union" ? shape.variants.some(isTyped)
169
+ : shape.kind === "resource" && Object.values(shape.entries).some(p => p.kind === "type");
170
+ }
171
+ function isLeaf(shape) {
172
+ return shape.kind === "union" ? shape.variants.some(isLeaf)
173
+ : shape.kind !== "resource" && (shape.kind !== "reference" || shape.foreign !== true);
174
+ }
175
+ function isOwn(shape) {
176
+ return shape.kind === "union" ? shape.variants.some(isOwn)
177
+ : shape.kind !== "reference" || shape.foreign !== true;
178
+ }
179
+ function isCascading(shape) {
180
+ return shape.kind === "union" ? shape.variants.some(isCascading)
181
+ : shape.kind === "reference" && shape.captive === true || shape.kind === "resource";
182
+ }
183
+ }
184
+ //# sourceMappingURL=encode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode.js","sourceRoot":"","sources":["../../src/modify/encode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { Deferred, Modify } from "@metreeca/keep/batching";
2
+ import { type RepositoryClient } from "@metreeca/wire-sparql";
3
+ /**
4
+ * Applies a batch of {@link Modify} requests against a repository as a single update.
5
+ *
6
+ * Each request is encoded by the presence of its `state`: a present `state` inserts (creates or
7
+ * updates) the entry, an omitted `state` removes it. Every request's operations are folded into one
8
+ * SPARQL update joined in submission order, so the backend applies them sequentially
9
+ * ({@link https://www.w3.org/TR/sparql11-update/#updateLanguage SPARQL 1.1 Update §3}) and, where
10
+ * supported, atomically (§3.2). The batch arrives pre-validated by the batching layer, which rejects
11
+ * any request whose `state` carries an `id` other than its `entry` (§4.1) before it reaches here, so
12
+ * every request is applied unconditionally; each batched {@link Deferred} resolves to its entry once
13
+ * the update completes, while a backend failure propagates for the batching layer to settle as a
14
+ * rejection across the batch.
15
+ *
16
+ * @param batch The modify requests to apply
17
+ * @param client The repository the mutations are applied against
18
+ *
19
+ * @returns A promise settling once the batched update has been applied
20
+ */
21
+ export declare function modify(batch: readonly Deferred<Modify>[], client: RepositoryClient): Promise<void>;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/modify/index.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,uBAAuB,CAAC;AAItF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,MAAM,CAC3B,KAAK,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,gBAAgB,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf"}
@@ -0,0 +1,44 @@
1
+ /*
2
+ * Copyright © 2025-2026 Metreeca srl
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { createScope } from "@metreeca/core/scope";
17
+ import { createFlake } from "@metreeca/keep-flake";
18
+ import { variable as toVariable } from "@metreeca/wire-sparql";
19
+ import { decode } from "./decode.js";
20
+ import { encode } from "./encode.js";
21
+ /**
22
+ * Applies a batch of {@link Modify} requests against a repository as a single update.
23
+ *
24
+ * Each request is encoded by the presence of its `state`: a present `state` inserts (creates or
25
+ * updates) the entry, an omitted `state` removes it. Every request's operations are folded into one
26
+ * SPARQL update joined in submission order, so the backend applies them sequentially
27
+ * ({@link https://www.w3.org/TR/sparql11-update/#updateLanguage SPARQL 1.1 Update §3}) and, where
28
+ * supported, atomically (§3.2). The batch arrives pre-validated by the batching layer, which rejects
29
+ * any request whose `state` carries an `id` other than its `entry` (§4.1) before it reaches here, so
30
+ * every request is applied unconditionally; each batched {@link Deferred} resolves to its entry once
31
+ * the update completes, while a backend failure propagates for the batching layer to settle as a
32
+ * rejection across the batch.
33
+ *
34
+ * @param batch The modify requests to apply
35
+ * @param client The repository the mutations are applied against
36
+ *
37
+ * @returns A promise settling once the batched update has been applied
38
+ */
39
+ export async function modify(batch, client) {
40
+ const scope = createScope(toVariable);
41
+ const items = batch.map(modify => ({ ...modify, flake: createFlake(modify.request.shape) }));
42
+ decode(scope, items, await client.update(encode(scope, items)));
43
+ }
44
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modify/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAyB,QAAQ,IAAI,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAC3B,KAAkC,EAClC,MAAwB;IAGxB,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAChC,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CACzD,CAAC;IAEF,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC,MAAM,CACvC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CACpB,CAAC,CAAC;AAEJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { Scope } from "@metreeca/core/scope";
2
+ import { type Flake } from "@metreeca/keep-flake";
3
+ import type { Broker, Deferred, Select } from "@metreeca/keep/batching";
4
+ import type { Tuple, Variable } from "@metreeca/wire-sparql";
5
+ /**
6
+ * Settles each batched select request against the SELECT solution.
7
+ *
8
+ * @param scope The variable scope shared with the encoder, recovering per-request tuple slots
9
+ * @param batch The queued select requests to settle, each paired with its {@link Flake | query plan} and deferred
10
+ * @param broker The cross-pass channel expanding localised properties through the resources pass
11
+ * @param tuples The solution tuples returned by the batched SELECT round
12
+ */
13
+ export declare function decode(scope: Scope<Variable>, batch: readonly (Deferred<Select> & {
14
+ readonly flake: Flake;
15
+ })[], broker: Broker, tuples: readonly Tuple[]): void;
16
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/select/decode.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAEN,KAAK,KAAK,EAOV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAIxE,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAK7D;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACrB,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,EACtB,KAAK,EAAE,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CAAE,CAAC,EAAE,EACjE,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,KAAK,EAAE,GACtB,IAAI,CAgTN"}