@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.
- package/LICENSE +201 -0
- package/README.md +106 -0
- package/dist/_/_decode.d.ts +20 -0
- package/dist/_/_decode.d.ts.map +1 -0
- package/dist/_/_decode.js +55 -0
- package/dist/_/_decode.js.map +1 -0
- package/dist/_/_encode.d.ts +112 -0
- package/dist/_/_encode.d.ts.map +1 -0
- package/dist/_/_encode.js +262 -0
- package/dist/_/_encode.js.map +1 -0
- package/dist/_/_flake.d.ts +16 -0
- package/dist/_/_flake.d.ts.map +1 -0
- package/dist/_/_flake.js +65 -0
- package/dist/_/_flake.js.map +1 -0
- package/dist/_/_union.d.ts +28 -0
- package/dist/_/_union.d.ts.map +1 -0
- package/dist/_/_union.js +51 -0
- package/dist/_/_union.js.map +1 -0
- package/dist/detect/decode.d.ts +25 -0
- package/dist/detect/decode.d.ts.map +1 -0
- package/dist/detect/decode.js +34 -0
- package/dist/detect/decode.js.map +1 -0
- package/dist/detect/encode.d.ts +25 -0
- package/dist/detect/encode.d.ts.map +1 -0
- package/dist/detect/encode.js +30 -0
- package/dist/detect/encode.js.map +1 -0
- package/dist/detect/index.d.ts +17 -0
- package/dist/detect/index.d.ts.map +1 -0
- package/dist/detect/index.js +55 -0
- package/dist/detect/index.js.map +1 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/lookup/decode.d.ts +33 -0
- package/dist/lookup/decode.d.ts.map +1 -0
- package/dist/lookup/decode.js +193 -0
- package/dist/lookup/decode.js.map +1 -0
- package/dist/lookup/encode.d.ts +46 -0
- package/dist/lookup/encode.d.ts.map +1 -0
- package/dist/lookup/encode.js +111 -0
- package/dist/lookup/encode.js.map +1 -0
- package/dist/lookup/index.d.ts +21 -0
- package/dist/lookup/index.d.ts.map +1 -0
- package/dist/lookup/index.js +72 -0
- package/dist/lookup/index.js.map +1 -0
- package/dist/modify/decode.d.ts +22 -0
- package/dist/modify/decode.d.ts.map +1 -0
- package/dist/modify/decode.js +26 -0
- package/dist/modify/decode.js.map +1 -0
- package/dist/modify/encode.d.ts +21 -0
- package/dist/modify/encode.d.ts.map +1 -0
- package/dist/modify/encode.js +184 -0
- package/dist/modify/encode.js.map +1 -0
- package/dist/modify/index.d.ts +22 -0
- package/dist/modify/index.d.ts.map +1 -0
- package/dist/modify/index.js +44 -0
- package/dist/modify/index.js.map +1 -0
- package/dist/select/decode.d.ts +16 -0
- package/dist/select/decode.d.ts.map +1 -0
- package/dist/select/decode.js +229 -0
- package/dist/select/decode.js.map +1 -0
- package/dist/select/encode.d.ts +16 -0
- package/dist/select/encode.d.ts.map +1 -0
- package/dist/select/encode.js +434 -0
- package/dist/select/encode.js.map +1 -0
- package/dist/select/index.d.ts +16 -0
- package/dist/select/index.d.ts.map +1 -0
- package/dist/select/index.js +38 -0
- package/dist/select/index.js.map +1 -0
- 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"}
|