@astrale-os/kernel-core 0.9.0-beta.65 → 0.9.0-beta.67
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/dist/auth/authority/admission/admission.d.ts +0 -1
- package/dist/auth/authority/admission/admission.js +8 -141
- package/dist/auth/authority/admission/references.d.ts +13 -0
- package/dist/auth/authority/admission/references.js +38 -0
- package/dist/auth/authority/admission/term.d.ts +6 -0
- package/dist/auth/authority/admission/term.js +60 -0
- package/dist/auth/authority/admission/wire.d.ts +8 -0
- package/dist/auth/authority/admission/wire.js +33 -0
- package/dist/auth/authority/semantics/interpret.d.ts +6 -0
- package/dist/auth/authority/semantics/interpret.js +187 -14
- package/dist/auth/authority/semantics/snapshot.d.ts +6 -0
- package/dist/graph/graph/index.d.ts +1 -1
- package/dist/graph/graph/index.js +1 -1
- package/dist/graph/graph/model/codec.js +3 -3
- package/dist/graph/graph/model/index.d.ts +1 -1
- package/dist/graph/graph/model/index.js +1 -1
- package/dist/graph/graph/model/model.d.ts +7 -7
- package/dist/graph/graph/model/model.js +6 -6
- package/dist/graph/graph/model/wire.d.ts +0 -20
- package/dist/graph/graph/model/wire.js +2 -2
- package/dist/graph/mutate/authoring/builder.d.ts +2 -2
- package/dist/graph/mutate/authoring/builder.js +2 -2
- package/dist/graph/mutate/index.d.ts +1 -1
- package/dist/graph/mutate/language/codec.js +3 -3
- package/dist/graph/mutate/language/model.d.ts +4 -4
- package/dist/graph/mutate/language/wire.d.ts +11 -0
- package/dist/graph/mutate/result/index.d.ts +4 -3
- package/dist/graph/mutate/result/index.js +8 -6
- package/dist/graph/mutate/result/wire.d.ts +1 -0
- package/dist/graph/mutate/result/wire.js +5 -2
- package/dist/graph/node/identity/id.d.ts +0 -3
- package/dist/graph/node/identity/id.js +0 -4
- package/dist/graph/node/identity/order.js +20 -0
- package/dist/graph/query/authoring/builder.js +29 -2
- package/dist/graph/query/authoring/model.d.ts +20 -1
- package/dist/graph/query/index.d.ts +3 -3
- package/dist/graph/query/index.js +1 -1
- package/dist/graph/query/language/codec.js +18 -3
- package/dist/graph/query/language/fingerprint.js +8 -0
- package/dist/graph/query/language/model.d.ts +22 -4
- package/dist/graph/query/language/wire.d.ts +11 -0
- package/dist/graph/query/language/wire.js +8 -1
- package/dist/graph/query/order/index.d.ts +8 -1
- package/dist/graph/query/order/index.js +20 -0
- package/dist/graph/query/reference/evaluate.js +5 -3
- package/dist/graph/reconcile/condition/model.d.ts +2 -2
- package/dist/graph/reconcile/condition/references.d.ts +0 -1
- package/dist/graph/reconcile/condition/references.js +4 -4
- package/dist/graph/reconcile/correspondence.d.ts +9 -8
- package/dist/graph/reconcile/evidence.d.ts +2 -2
- package/dist/graph/reconcile/mutation/assess.d.ts +2 -1
- package/dist/graph/reconcile/observation.d.ts +4 -3
- package/dist/graph/reconcile/planning/context.d.ts +3 -3
- package/dist/graph/reconcile/planning/model.d.ts +4 -4
- package/dist/schema/callables/{view-for.d.ts → entrypoint.d.ts} +7 -5
- package/dist/schema/callables/entrypoint.js +12 -0
- package/dist/schema/callables/function.d.ts +0 -120
- package/dist/schema/callables/index.d.ts +1 -1
- package/dist/schema/callables/index.js +1 -1
- package/dist/schema/callables/view.d.ts +2 -24
- package/dist/schema/domain/domain.d.ts +2 -121
- package/dist/schema/domain/domain.js +3 -0
- package/dist/schema/identity/identity.d.ts +0 -8
- package/dist/schema/kernel/projection/core.d.ts +7 -0
- package/dist/schema/kernel/projection/core.js +51 -0
- package/dist/schema/kernel/projection/definitions.d.ts +13 -0
- package/dist/schema/kernel/projection/definitions.js +71 -0
- package/dist/schema/kernel/projection/methods.d.ts +5 -0
- package/dist/schema/kernel/projection/methods.js +41 -0
- package/dist/schema/kernel/projection/part.d.ts +34 -0
- package/dist/schema/kernel/projection/part.js +42 -0
- package/dist/schema/kernel/projection/paths.d.ts +6 -0
- package/dist/schema/kernel/projection/{keys.js → paths.js} +11 -12
- package/dist/schema/kernel/projection/project.d.ts +1 -1
- package/dist/schema/kernel/projection/project.js +16 -290
- package/dist/schema/kernel/projection/properties.d.ts +11 -0
- package/dist/schema/kernel/projection/properties.js +36 -0
- package/dist/schema/kernel/projection/relations.d.ts +7 -0
- package/dist/schema/kernel/projection/relations.js +49 -0
- package/dist/schema/kernel/projection/types.d.ts +4 -4
- package/dist/schema/kernel/schema.d.ts +174 -409
- package/dist/schema/kernel/schema.js +3 -2
- package/dist/schema/kernel/syscalls/contracts/blob.d.ts +12 -2
- package/dist/schema/kernel/syscalls/contracts/blob.js +10 -2
- package/dist/schema/kernel/syscalls/contracts/delegate.d.ts +0 -4
- package/dist/schema/kernel/syscalls/contracts/delegate.js +0 -3
- package/dist/schema/kernel/syscalls/contracts/index.d.ts +1 -1
- package/dist/schema/kernel/syscalls/contracts/index.js +1 -1
- package/dist/schema/kernel/syscalls/contracts/install.d.ts +3 -20
- package/dist/schema/kernel/syscalls/contracts/install.js +0 -2
- package/dist/schema/kernel/syscalls/contracts/installation.d.ts +0 -36
- package/dist/schema/kernel/syscalls/contracts/installation.js +3 -3
- package/dist/schema/kernel/syscalls/contracts/mutate.d.ts +13 -0
- package/dist/schema/kernel/syscalls/contracts/mutate.js +2 -1
- package/dist/schema/kernel/syscalls/contracts/query.d.ts +11 -0
- package/dist/schema/kernel/syscalls/contracts/view-resolve.d.ts +3 -14
- package/dist/schema/kernel/syscalls/contracts/view-resolve.js +3 -18
- package/dist/schema/kernel/syscalls/declarations/delegate.d.ts +0 -4
- package/dist/schema/kernel/syscalls/declarations/download.d.ts +5 -0
- package/dist/schema/kernel/syscalls/declarations/index.d.ts +30 -24
- package/dist/schema/kernel/syscalls/declarations/install.d.ts +0 -8
- package/dist/schema/kernel/syscalls/declarations/mutate.d.ts +13 -0
- package/dist/schema/kernel/syscalls/declarations/query.d.ts +11 -0
- package/dist/schema/kernel/syscalls/declarations/view-resolve.d.ts +1 -12
- package/dist/schema/kernel/syscalls/descriptors/identity.d.ts +0 -4
- package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.d.ts +2 -13
- package/dist/schema/kernel/syscalls/descriptors/results/view-resolution.js +4 -119
- package/dist/schema/kernel/syscalls/descriptors/view.d.ts +1 -12
- package/package.json +2 -2
- package/dist/schema/callables/view-for.js +0 -12
- package/dist/schema/kernel/projection/keys.d.ts +0 -3
- package/dist/schema/kernel/syscalls/contracts/legacy/delegate.d.ts +0 -5
- package/dist/schema/kernel/syscalls/contracts/legacy/delegate.js +0 -25
- package/dist/schema/kernel/syscalls/contracts/legacy/install.d.ts +0 -22
- package/dist/schema/kernel/syscalls/contracts/legacy/install.js +0 -31
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Stable aggregate facade over Graph model, admission, indexes, delta, and merge. */
|
|
2
2
|
export { Graph } from './graph.js';
|
|
3
3
|
export { GraphData, GraphDataDecodeError, GraphSpec, GraphSpecDecodeError } from './model/index.js';
|
|
4
|
-
export {
|
|
4
|
+
export { LocalAlias, isLocalAlias } from './model/index.js';
|
|
5
5
|
export { GraphAdmissionError } from './admission/index.js';
|
|
@@ -5,7 +5,7 @@ import { node as constructNode, NodeId } from '../../node/index.js';
|
|
|
5
5
|
import { NodePath } from '../../path/index.js';
|
|
6
6
|
import { normalizeProperties } from '../../properties/index.js';
|
|
7
7
|
import { decodeWire } from '../../wire.js';
|
|
8
|
-
import {
|
|
8
|
+
import { isLocalAlias, LocalAlias } from './model.js';
|
|
9
9
|
import { graphSpecSchema } from './wire.js';
|
|
10
10
|
export class GraphDataDecodeError extends TypeError {
|
|
11
11
|
path;
|
|
@@ -124,10 +124,10 @@ function decodeEndpoint(input, path) {
|
|
|
124
124
|
return Object.freeze({ created: binding(input.created, `${path}/created`) });
|
|
125
125
|
}
|
|
126
126
|
function binding(input, path) {
|
|
127
|
-
if (!
|
|
127
|
+
if (!isLocalAlias(input)) {
|
|
128
128
|
specInvalid(path, 'Expected a local binding name of at most 64 characters');
|
|
129
129
|
}
|
|
130
|
-
return
|
|
130
|
+
return LocalAlias(input);
|
|
131
131
|
}
|
|
132
132
|
function validateGraphSpec(nodes, edges) {
|
|
133
133
|
const ids = new Set();
|
|
@@ -13,5 +13,5 @@ export declare const GraphSpec: {
|
|
|
13
13
|
encode(spec: GraphSpecValue): GraphSpecJson;
|
|
14
14
|
};
|
|
15
15
|
export type { AnonymousNodeSpec, GraphSpecEdge, GraphSpecEndpoint, GraphSpecJson, GraphSpecNode, } from './model.js';
|
|
16
|
-
export {
|
|
16
|
+
export { LocalAlias, isLocalAlias } from './model.js';
|
|
17
17
|
export { GraphSpecDecodeError } from './codec.js';
|
|
@@ -2,5 +2,5 @@ import { decodeGraphData, decodeGraphSpec, encodeGraphData, encodeGraphSpec } fr
|
|
|
2
2
|
export const GraphData = Object.freeze({ decode: decodeGraphData, encode: encodeGraphData });
|
|
3
3
|
export { GraphDataDecodeError } from './codec.js';
|
|
4
4
|
export const GraphSpec = Object.freeze({ decode: decodeGraphSpec, encode: encodeGraphSpec });
|
|
5
|
-
export {
|
|
5
|
+
export { LocalAlias, isLocalAlias } from './model.js';
|
|
6
6
|
export { GraphSpecDecodeError } from './codec.js';
|
|
@@ -2,21 +2,21 @@ import type { EdgeSpec } from '../../edge/index.js';
|
|
|
2
2
|
import type { Node, NodeId, NodeSpec } from '../../node/index.js';
|
|
3
3
|
import type { NodePath } from '../../path/index.js';
|
|
4
4
|
import type { Properties } from '../../properties/index.js';
|
|
5
|
-
declare const
|
|
5
|
+
declare const LOCAL_ALIAS_BRAND: unique symbol;
|
|
6
6
|
/** A graph-local lexical name. It is never Node identity. */
|
|
7
|
-
export type
|
|
8
|
-
readonly [
|
|
7
|
+
export type LocalAlias = string & {
|
|
8
|
+
readonly [LOCAL_ALIAS_BRAND]: true;
|
|
9
9
|
};
|
|
10
|
-
export declare function
|
|
11
|
-
export declare function
|
|
10
|
+
export declare function LocalAlias(input: string): LocalAlias;
|
|
11
|
+
export declare function isLocalAlias(input: unknown): input is LocalAlias;
|
|
12
12
|
export interface AnonymousNodeSpec extends NodeSpec {
|
|
13
|
-
readonly as:
|
|
13
|
+
readonly as: LocalAlias;
|
|
14
14
|
}
|
|
15
15
|
export type GraphSpecNode = Node | AnonymousNodeSpec;
|
|
16
16
|
export type GraphSpecEndpoint = NodeId | {
|
|
17
17
|
readonly path: NodePath;
|
|
18
18
|
} | {
|
|
19
|
-
readonly created:
|
|
19
|
+
readonly created: LocalAlias;
|
|
20
20
|
};
|
|
21
21
|
export type GraphSpecEdge = EdgeSpec<GraphSpecEndpoint>;
|
|
22
22
|
/** Detached structural graph values, including graph-local anonymous Nodes. */
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const
|
|
2
|
-
export function
|
|
3
|
-
if (!
|
|
4
|
-
throw new TypeError(`Invalid local
|
|
1
|
+
const LOCAL_ALIAS_PATTERN = /^[A-Za-z][A-Za-z0-9_]{0,63}$/u;
|
|
2
|
+
export function LocalAlias(input) {
|
|
3
|
+
if (!isLocalAlias(input)) {
|
|
4
|
+
throw new TypeError(`Invalid local alias ${JSON.stringify(input)}.`);
|
|
5
5
|
}
|
|
6
6
|
return input;
|
|
7
7
|
}
|
|
8
|
-
export function
|
|
9
|
-
return typeof input === 'string' &&
|
|
8
|
+
export function isLocalAlias(input) {
|
|
9
|
+
return typeof input === 'string' && LOCAL_ALIAS_PATTERN.test(input);
|
|
10
10
|
}
|
|
@@ -5,11 +5,6 @@ export declare const graphNodeSchema: import("zod").ZodObject<{
|
|
|
5
5
|
class: import("zod").ZodString;
|
|
6
6
|
props: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
7
7
|
}, import("zod/v4/core").$strict>;
|
|
8
|
-
export declare const anonymousGraphNodeSchema: import("zod").ZodObject<{
|
|
9
|
-
as: import("zod").ZodString;
|
|
10
|
-
class: import("zod").ZodString;
|
|
11
|
-
props: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
12
|
-
}, import("zod/v4/core").$strict>;
|
|
13
8
|
export declare const edgeKeySchema: import("zod").ZodObject<{
|
|
14
9
|
source: import("zod").ZodString;
|
|
15
10
|
target: import("zod").ZodString;
|
|
@@ -22,21 +17,6 @@ export declare const graphEdgeSchema: import("zod").ZodObject<{
|
|
|
22
17
|
slug: import("zod").ZodOptional<ZodType<EdgeSlug, unknown, import("zod/v4/core").$ZodTypeInternals<EdgeSlug, unknown>>>;
|
|
23
18
|
props: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
24
19
|
}, import("zod/v4/core").$strict>;
|
|
25
|
-
export declare const graphSpecEdgeSchema: import("zod").ZodObject<{
|
|
26
|
-
source: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodObject<{
|
|
27
|
-
path: import("zod").ZodString;
|
|
28
|
-
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
29
|
-
created: import("zod").ZodString;
|
|
30
|
-
}, import("zod/v4/core").$strict>]>;
|
|
31
|
-
target: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodObject<{
|
|
32
|
-
path: import("zod").ZodString;
|
|
33
|
-
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
34
|
-
created: import("zod").ZodString;
|
|
35
|
-
}, import("zod/v4/core").$strict>]>;
|
|
36
|
-
class: import("zod").ZodString;
|
|
37
|
-
slug: import("zod").ZodOptional<ZodType<EdgeSlug, unknown, import("zod/v4/core").$ZodTypeInternals<EdgeSlug, unknown>>>;
|
|
38
|
-
props: import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodUnknown>;
|
|
39
|
-
}, import("zod/v4/core").$strict>;
|
|
40
20
|
export declare const graphSpecSchema: import("zod").ZodObject<{
|
|
41
21
|
nodes: import("zod").ZodArray<import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
42
22
|
id: import("zod").ZodString;
|
|
@@ -9,7 +9,7 @@ const edgeSlug = string()
|
|
|
9
9
|
.max(edgeSlugSchema.maxLength)
|
|
10
10
|
.check(fullMatch(edgeSlugSchema.fullMatch));
|
|
11
11
|
export const graphNodeSchema = strictObject({ id: text, class: text, props });
|
|
12
|
-
|
|
12
|
+
const anonymousGraphNodeSchema = strictObject({ as: binding, class: text, props });
|
|
13
13
|
export const edgeKeySchema = strictObject({ source: text, target: text, class: text });
|
|
14
14
|
export const graphEdgeSchema = edgeKeySchema.extend({ slug: edgeSlug.optional(), props });
|
|
15
15
|
const graphSpecEndpointSchema = union([
|
|
@@ -17,7 +17,7 @@ const graphSpecEndpointSchema = union([
|
|
|
17
17
|
strictObject({ path: text }),
|
|
18
18
|
strictObject({ created: binding }),
|
|
19
19
|
]);
|
|
20
|
-
|
|
20
|
+
const graphSpecEdgeSchema = strictObject({
|
|
21
21
|
source: graphSpecEndpointSchema,
|
|
22
22
|
target: graphSpecEndpointSchema,
|
|
23
23
|
class: text,
|
|
@@ -6,7 +6,7 @@ import type { DeltaInput } from '../../properties/index.js';
|
|
|
6
6
|
import type { QueryEdgeAST, QueryNodeAST } from '../../query/index.js';
|
|
7
7
|
import type { MutationAST } from '../language/index.js';
|
|
8
8
|
import type { MutationInputEdgeSelector, MutationInputEndpoint, MutationPropertyConditionsInput, MutationPropsInput } from './model.js';
|
|
9
|
-
import {
|
|
9
|
+
import { LocalAlias } from '../../graph/index.js';
|
|
10
10
|
export type MutationQueryPreconditionInput = {
|
|
11
11
|
readonly query: QueryNodeAST;
|
|
12
12
|
readonly equals: {
|
|
@@ -39,7 +39,7 @@ export interface MutationBuilder {
|
|
|
39
39
|
readonly class: ClassKey;
|
|
40
40
|
readonly props?: MutationPropsInput;
|
|
41
41
|
}): {
|
|
42
|
-
readonly created:
|
|
42
|
+
readonly created: LocalAlias;
|
|
43
43
|
};
|
|
44
44
|
updateNode(input: {
|
|
45
45
|
readonly node: NodeTarget;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LocalAlias } from '../../graph/index.js';
|
|
2
2
|
import { createMutationAST } from './create.js';
|
|
3
3
|
/** Run one synchronous author and admit its complete operation set. */
|
|
4
4
|
export function buildMutationAST(author) {
|
|
@@ -38,7 +38,7 @@ export function buildMutationAST(author) {
|
|
|
38
38
|
expect: expectation,
|
|
39
39
|
createNode(input) {
|
|
40
40
|
requireOpen();
|
|
41
|
-
const created =
|
|
41
|
+
const created = LocalAlias(input.as);
|
|
42
42
|
operations.push({
|
|
43
43
|
op: 'node.create',
|
|
44
44
|
as: created,
|
|
@@ -2,7 +2,7 @@ import type { GraphSpec } from '../graph/index.js';
|
|
|
2
2
|
import type { MutationBuilder, MutationInput } from './authoring/index.js';
|
|
3
3
|
import type { MutationAST as MutationASTValue, MutationStructuralLimits } from './language/index.js';
|
|
4
4
|
export type { MutationBuilder, MutationInput, MutationInputEdgeSelector, MutationInputEndpoint, MutationInputOperation, MutationInputPrecondition, MutationPropertyConditionsInput, MutationPropsInput, MutationQueryPreconditionInput, } from './authoring/index.js';
|
|
5
|
-
export type { EdgeCreateOperation, EdgeDeleteOperation, EdgeUpdateOperation,
|
|
5
|
+
export type { EdgeCreateOperation, EdgeDeleteOperation, EdgeUpdateOperation, LocalAlias, MutationEdgeSelector, MutationEndpoint, MutationOperation, MutationPrecondition, MutationPropertyConditions, MutationProps, MutationQueryPrecondition, MutationStructuralLimits, NodeCreateOperation, NodeDeleteOperation, NodeUpdateOperation, QueryExpectedSelection, } from './language/index.js';
|
|
6
6
|
export { MutationASTDecodeError } from './language/index.js';
|
|
7
7
|
export type MutationAST = MutationASTValue;
|
|
8
8
|
export declare const MutationAST: {
|
|
@@ -3,7 +3,7 @@ import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
|
3
3
|
import * as portable from '@astrale-os/kernel-dsl/value';
|
|
4
4
|
import { EdgeSlug, encodeEdgeKey } from '../../edge/index.js';
|
|
5
5
|
import { compareEdgeKeys } from '../../edge/index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isLocalAlias, LocalAlias as LocalAliasValue } from '../../graph/index.js';
|
|
7
7
|
import { NodeId } from '../../node/index.js';
|
|
8
8
|
import { compareNodeIds } from '../../node/index.js';
|
|
9
9
|
import { NodePath } from '../../path/index.js';
|
|
@@ -341,9 +341,9 @@ function compare(left, right) {
|
|
|
341
341
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
342
342
|
}
|
|
343
343
|
function localBinding(value, path) {
|
|
344
|
-
if (!
|
|
344
|
+
if (!isLocalAlias(value))
|
|
345
345
|
invalid(path, 'Expected a local binding name of at most 64 characters');
|
|
346
|
-
return
|
|
346
|
+
return LocalAliasValue(value);
|
|
347
347
|
}
|
|
348
348
|
function propertyKey(value, path) {
|
|
349
349
|
if (typeof value !== 'string' || !PropertyKey.is(value)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PropertyKey } from '@astrale-os/kernel-dsl/v1';
|
|
2
2
|
import type { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
3
3
|
import type { EdgeSlug } from '../../edge/index.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { LocalAlias } from '../../graph/index.js';
|
|
5
5
|
import type { NodePath } from '../../path/index.js';
|
|
6
6
|
import type { Delta as PropertiesDelta, Properties } from '../../properties/index.js';
|
|
7
7
|
import type { QueryEdgeAST, QueryNodeAST } from '../../query/index.js';
|
|
@@ -14,10 +14,10 @@ export type MutationStructuralLimits = Readonly<{
|
|
|
14
14
|
queryExpectedIdentities: 4096;
|
|
15
15
|
}>;
|
|
16
16
|
export declare const MUTATION_AST_LIMITS: MutationStructuralLimits;
|
|
17
|
-
export type {
|
|
17
|
+
export type { LocalAlias } from '../../graph/index.js';
|
|
18
18
|
export type MutationProps = Properties;
|
|
19
19
|
export type MutationEndpoint = NodePath | {
|
|
20
|
-
readonly created:
|
|
20
|
+
readonly created: LocalAlias;
|
|
21
21
|
};
|
|
22
22
|
export interface MutationEdgeSelector {
|
|
23
23
|
readonly source: NodePath;
|
|
@@ -55,7 +55,7 @@ export type MutationPrecondition = {
|
|
|
55
55
|
} | MutationQueryPrecondition;
|
|
56
56
|
export interface NodeCreateOperation {
|
|
57
57
|
readonly op: 'node.create';
|
|
58
|
-
readonly as:
|
|
58
|
+
readonly as: LocalAlias;
|
|
59
59
|
readonly class: ClassKey;
|
|
60
60
|
readonly props: MutationProps;
|
|
61
61
|
}
|
|
@@ -87,6 +87,17 @@ export declare const mutationAstSchema: import("zod").ZodObject<{
|
|
|
87
87
|
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
88
88
|
kind: import("zod").ZodLiteral<"property.present">;
|
|
89
89
|
property: import("zod").ZodString;
|
|
90
|
+
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
91
|
+
kind: import("zod").ZodLiteral<"property.range">;
|
|
92
|
+
property: import("zod").ZodString;
|
|
93
|
+
lower: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
94
|
+
value: import("zod").ZodUnion<readonly [import("zod").ZodNumber, import("zod").ZodString]>;
|
|
95
|
+
inclusive: import("zod").ZodBoolean;
|
|
96
|
+
}, import("zod/v4/core").$strict>>;
|
|
97
|
+
upper: import("zod").ZodOptional<import("zod").ZodObject<{
|
|
98
|
+
value: import("zod").ZodUnion<readonly [import("zod").ZodNumber, import("zod").ZodString]>;
|
|
99
|
+
inclusive: import("zod").ZodBoolean;
|
|
100
|
+
}, import("zod/v4/core").$strict>>;
|
|
90
101
|
}, import("zod/v4/core").$strict>, import("zod").ZodObject<{
|
|
91
102
|
kind: import("zod").ZodLiteral<"identity.equal">;
|
|
92
103
|
identity: import("zod").ZodUnion<readonly [import("zod").ZodString, import("zod").ZodObject<{
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { NodeId } from '../../node/index.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { LocalAlias } from '../language/index.js';
|
|
3
3
|
export type MutationResult = {
|
|
4
|
-
readonly createdNodes: Readonly<Record<
|
|
4
|
+
readonly createdNodes: Readonly<Record<LocalAlias, NodeId>>;
|
|
5
|
+
readonly replayed?: true;
|
|
5
6
|
};
|
|
6
7
|
export declare const MutationResult: {
|
|
7
8
|
decode(input: unknown): MutationResult;
|
|
@@ -12,5 +13,5 @@ export { MutationResultDecodeError } from './error.js';
|
|
|
12
13
|
export { mutationResultSchema } from './wire.js';
|
|
13
14
|
/** Re-admit one mutation result before it crosses a trust or transport boundary. */
|
|
14
15
|
export declare function encodeMutationResult(input: MutationResult): MutationResult;
|
|
15
|
-
/** Decode unknown JSON into immutable admitted
|
|
16
|
+
/** Decode unknown JSON into immutable admitted LocalAlias-to-NodeId results. */
|
|
16
17
|
export declare function decodeMutationResult(input: unknown): MutationResult;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as portable from '@astrale-os/kernel-dsl/value';
|
|
2
|
-
import {
|
|
2
|
+
import { isLocalAlias, LocalAlias as LocalAliasValue } from '#graph/graph';
|
|
3
3
|
import { NodeId as nodeId } from '../../node/index.js';
|
|
4
4
|
import { decodeWire } from '../../wire.js';
|
|
5
5
|
import { MutationResultDecodeError } from './error.js';
|
|
@@ -8,7 +8,7 @@ export const MutationResult = Object.freeze({
|
|
|
8
8
|
decode: decodeMutationResult,
|
|
9
9
|
encode: encodeMutationResult,
|
|
10
10
|
createdNode(result, binding) {
|
|
11
|
-
return result.createdNodes[
|
|
11
|
+
return result.createdNodes[LocalAliasValue(binding)];
|
|
12
12
|
},
|
|
13
13
|
});
|
|
14
14
|
export { MutationResultDecodeError } from './error.js';
|
|
@@ -17,10 +17,11 @@ export { mutationResultSchema } from './wire.js';
|
|
|
17
17
|
export function encodeMutationResult(input) {
|
|
18
18
|
return decodeMutationResult(input);
|
|
19
19
|
}
|
|
20
|
-
/** Decode unknown JSON into immutable admitted
|
|
20
|
+
/** Decode unknown JSON into immutable admitted LocalAlias-to-NodeId results. */
|
|
21
21
|
export function decodeMutationResult(input) {
|
|
22
22
|
try {
|
|
23
|
-
const
|
|
23
|
+
const admitted = decodeWire(mutationResultSchema, portable.accept(input), invalid);
|
|
24
|
+
const encoded = admitted.createdNodes;
|
|
24
25
|
const createdNodes = {};
|
|
25
26
|
for (const binding of Object.keys(encoded).sort()) {
|
|
26
27
|
const path = `/createdNodes/${escapePointer(binding)}`;
|
|
@@ -35,6 +36,7 @@ export function decodeMutationResult(input) {
|
|
|
35
36
|
}
|
|
36
37
|
return Object.freeze({
|
|
37
38
|
createdNodes: Object.freeze(createdNodes),
|
|
39
|
+
...(admitted.replayed === true ? { replayed: true } : {}),
|
|
38
40
|
});
|
|
39
41
|
}
|
|
40
42
|
catch (error) {
|
|
@@ -46,8 +48,8 @@ export function decodeMutationResult(input) {
|
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
function requireBinding(value, path) {
|
|
49
|
-
if (!
|
|
50
|
-
invalid(path, 'Invalid
|
|
51
|
+
if (!isLocalAlias(value))
|
|
52
|
+
invalid(path, 'Invalid LocalAlias');
|
|
51
53
|
}
|
|
52
54
|
function escapePointer(value) {
|
|
53
55
|
return value.replaceAll('~', '~0').replaceAll('/', '~1');
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { record, strictObject, string } from 'zod';
|
|
1
|
+
import { literal, record, strictObject, string } from 'zod';
|
|
2
2
|
const text = string().min(1);
|
|
3
3
|
const binding = string().min(1).max(64);
|
|
4
|
-
export const mutationResultSchema = strictObject({
|
|
4
|
+
export const mutationResultSchema = strictObject({
|
|
5
|
+
createdNodes: record(binding, text),
|
|
6
|
+
replayed: literal(true).optional(),
|
|
7
|
+
});
|
|
@@ -11,7 +11,4 @@ export declare class NodeIdError extends TypeError {
|
|
|
11
11
|
/** Admit opaque 1-255 character ASCII NodeId text without repair or format-specific semantics. */
|
|
12
12
|
export declare function NodeId(input: string): NodeId;
|
|
13
13
|
export declare function isNodeId(input: unknown): input is NodeId;
|
|
14
|
-
export declare const nodeIdSchema: import("zod").ZodPipe<import("zod").ZodString & import("zod").ZodType<NodeId, string, import("zod/v4/core").$ZodTypeInternals<NodeId, string>>, import("zod").ZodTransform<NodeId, string & {
|
|
15
|
-
readonly [NODE_ID_BRAND]: true;
|
|
16
|
-
}>>;
|
|
17
14
|
export {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { string } from 'zod';
|
|
2
1
|
const NODE_ID_MAX_LENGTH = 255;
|
|
3
2
|
const NODE_ID_INVALID_CHARACTER = /[^A-Za-z0-9._-]/u;
|
|
4
3
|
const NODE_ID_ERROR_MESSAGE = 'NodeId must be 1-255 ASCII characters drawn from [A-Za-z0-9._-].';
|
|
@@ -23,6 +22,3 @@ export function isNodeId(input) {
|
|
|
23
22
|
input.length <= NODE_ID_MAX_LENGTH &&
|
|
24
23
|
!NODE_ID_INVALID_CHARACTER.test(input));
|
|
25
24
|
}
|
|
26
|
-
export const nodeIdSchema = string()
|
|
27
|
-
.refine(isNodeId, NODE_ID_ERROR_MESSAGE)
|
|
28
|
-
.transform((value) => value);
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
const encoder = new TextEncoder();
|
|
2
2
|
/** Compare canonical Node identity by unsigned lexicographic UTF-8 byte order. */
|
|
3
3
|
export function compareNodeIds(left, right) {
|
|
4
|
+
// UTF-8 preserves code point order, and identical UTF-16 prefixes encode identically. Below the
|
|
5
|
+
// surrogate block, the first differing code unit therefore decides the UTF-8 byte order.
|
|
6
|
+
const length = Math.min(left.length, right.length);
|
|
7
|
+
let index = 0;
|
|
8
|
+
while (index < length && left.charCodeAt(index) === right.charCodeAt(index))
|
|
9
|
+
index++;
|
|
10
|
+
if (index < length) {
|
|
11
|
+
const a = left.charCodeAt(index);
|
|
12
|
+
const b = right.charCodeAt(index);
|
|
13
|
+
if (a < 0xd800 && b < 0xd800)
|
|
14
|
+
return a < b ? -1 : 1;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const next = (left.length > right.length ? left : right).charCodeAt(index);
|
|
18
|
+
if (Number.isNaN(next) || next < 0xdc00 || next > 0xdfff)
|
|
19
|
+
return Math.sign(left.length - right.length);
|
|
20
|
+
}
|
|
21
|
+
return compareUtf8(left, right);
|
|
22
|
+
}
|
|
23
|
+
function compareUtf8(left, right) {
|
|
4
24
|
const a = encoder.encode(left);
|
|
5
25
|
const b = encoder.encode(right);
|
|
6
26
|
const length = Math.min(a.length, b.length);
|
|
@@ -40,6 +40,33 @@ export function Property(input) {
|
|
|
40
40
|
isPresent() {
|
|
41
41
|
return Object.freeze({ kind: 'property.present', property: key });
|
|
42
42
|
},
|
|
43
|
+
greater: (value) => range(key, bound(value, false, 'lower'), undefined),
|
|
44
|
+
greaterOrEqual: (value) => range(key, bound(value, true, 'lower'), undefined),
|
|
45
|
+
less: (value) => range(key, undefined, bound(value, false, 'upper')),
|
|
46
|
+
lessOrEqual: (value) => range(key, undefined, bound(value, true, 'upper')),
|
|
47
|
+
between(lower, upper, bounds = {}) {
|
|
48
|
+
if (typeof lower !== typeof upper) {
|
|
49
|
+
invalid('/predicate/upper/value', 'Range bounds must have one kind');
|
|
50
|
+
}
|
|
51
|
+
return range(key, bound(lower, bounds.lower !== 'exclusive', 'lower'), bound(upper, bounds.upper !== 'exclusive', 'upper'));
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function bound(value, inclusive, side) {
|
|
56
|
+
if (typeof value !== 'number' && typeof value !== 'string') {
|
|
57
|
+
invalid(`/predicate/${side}/value`, 'Range bound must be a number or a text');
|
|
58
|
+
}
|
|
59
|
+
return Object.freeze({
|
|
60
|
+
value: canonicalValue(value, `/predicate/${side}/value`),
|
|
61
|
+
inclusive,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function range(property, lower, upper) {
|
|
65
|
+
return Object.freeze({
|
|
66
|
+
kind: 'property.range',
|
|
67
|
+
property,
|
|
68
|
+
...(lower === undefined ? {} : { lower }),
|
|
69
|
+
...(upper === undefined ? {} : { upper }),
|
|
43
70
|
});
|
|
44
71
|
}
|
|
45
72
|
/** Primary persistent Query V6 authoring entry point. */
|
|
@@ -190,12 +217,12 @@ function appendFilter(state, input, defaultBinding) {
|
|
|
190
217
|
...(state.edge === undefined ? {} : { edge: state.edge }),
|
|
191
218
|
});
|
|
192
219
|
}
|
|
193
|
-
function canonicalValue(input) {
|
|
220
|
+
function canonicalValue(input, path = '/predicate/value') {
|
|
194
221
|
try {
|
|
195
222
|
return freezeValue(portable.json.decode(portable.json.encode(input)));
|
|
196
223
|
}
|
|
197
224
|
catch (cause) {
|
|
198
|
-
invalid(
|
|
225
|
+
invalid(path, 'Invalid portable Property value', cause);
|
|
199
226
|
}
|
|
200
227
|
}
|
|
201
228
|
function freezeValue(input) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as dslApi from '@astrale-os/kernel-dsl/v1';
|
|
2
2
|
import type * as portable from '@astrale-os/kernel-dsl/value';
|
|
3
3
|
import type { NodeTarget } from '../../path/index.js';
|
|
4
|
-
import type { EdgeBinding, NodeBinding, QueryBinding, QueryDirection, QueryEdgeIdentityPredicate, QueryEdgeProjection, QueryNodeIdentityPredicate, QueryNodeProjection, QueryPropertyOrder, QueryPropertyPredicate, QueryPropertyEqualPredicate, QueryPropertyPresentPredicate } from '../language/index.js';
|
|
4
|
+
import type { EdgeBinding, NodeBinding, QueryBinding, QueryDirection, QueryEdgeIdentityPredicate, QueryEdgeProjection, QueryNodeIdentityPredicate, QueryNodeProjection, QueryPropertyOrder, QueryPropertyPredicate, QueryPropertyEqualPredicate, QueryPropertyPresentPredicate, QueryPropertyRangeOf } from '../language/index.js';
|
|
5
5
|
type NonEmpty<Value> = readonly [Value, ...Value[]];
|
|
6
6
|
export type QueryClassInput<Kind extends 'node' | 'edge' = 'node' | 'edge'> = dslApi.ClassRef | dslApi.ClassKey | Readonly<{
|
|
7
7
|
readonly ref: dslApi.ClassRef;
|
|
@@ -55,9 +55,28 @@ export type QueryCurrentNodeFilterInput = (Omit<QueryClassFilterInput, 'binding'
|
|
|
55
55
|
}) | Extract<QueryIdentityFilterInput, {
|
|
56
56
|
readonly binding: EdgeBinding;
|
|
57
57
|
}>;
|
|
58
|
+
/** Whether each end of `between` includes its bound; both are inclusive by default. */
|
|
59
|
+
export interface QueryRangeBoundsInput {
|
|
60
|
+
readonly lower?: 'inclusive' | 'exclusive';
|
|
61
|
+
readonly upper?: 'inclusive' | 'exclusive';
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Property predicate leaves. The range forms are one canonical `property.range` predicate: a
|
|
65
|
+
* number range compares numerically, a text range in code-point order.
|
|
66
|
+
*/
|
|
58
67
|
export interface QueryPropertyPredicateBuilder {
|
|
59
68
|
equals(value: portable.Value): QueryPropertyEqualPredicate;
|
|
60
69
|
isPresent(): QueryPropertyPresentPredicate;
|
|
70
|
+
greater(value: number): QueryPropertyRangeOf<number>;
|
|
71
|
+
greater(value: string): QueryPropertyRangeOf<string>;
|
|
72
|
+
greaterOrEqual(value: number): QueryPropertyRangeOf<number>;
|
|
73
|
+
greaterOrEqual(value: string): QueryPropertyRangeOf<string>;
|
|
74
|
+
less(value: number): QueryPropertyRangeOf<number>;
|
|
75
|
+
less(value: string): QueryPropertyRangeOf<string>;
|
|
76
|
+
lessOrEqual(value: number): QueryPropertyRangeOf<number>;
|
|
77
|
+
lessOrEqual(value: string): QueryPropertyRangeOf<string>;
|
|
78
|
+
between(lower: number, upper: number, bounds?: QueryRangeBoundsInput): QueryPropertyRangeOf<number>;
|
|
79
|
+
between(lower: string, upper: string, bounds?: QueryRangeBoundsInput): QueryPropertyRangeOf<string>;
|
|
61
80
|
}
|
|
62
81
|
export interface QueryExpandInput {
|
|
63
82
|
readonly from: NodeBinding;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/** Stable flat facade over Query language, authoring, result, and reference semantics. */
|
|
2
2
|
export { Property, Query } from './authoring/index.js';
|
|
3
|
-
export type { EdgeQueryBuilder, ExpandedQueryBuilder, NodeQueryBuilder, QueryCurrentNodeExpandInput, QueryCurrentNodeFilterInput, QueryClassInput, QueryEdgeClassInput, QueryEdgeInput, QueryClassFilterInput, QueryEdgeSourceInput, QueryEdgeGraphSelectInput, QueryEdgeSelectInput, QueryExpandInput, QueryFilterInput, QueryIdentityFilterInput, QueryNodeClassInput, QueryNodeGraphSelectInput, QueryNodeInput, QueryNodeSelectInput, QueryNodeSourceInput, QueryPropertyFilterInput, QueryPropertyPredicateBuilder, QuerySelectInput, QuerySourceInput, } from './authoring/index.js';
|
|
3
|
+
export type { EdgeQueryBuilder, ExpandedQueryBuilder, NodeQueryBuilder, QueryCurrentNodeExpandInput, QueryCurrentNodeFilterInput, QueryClassInput, QueryEdgeClassInput, QueryEdgeInput, QueryClassFilterInput, QueryEdgeSourceInput, QueryEdgeGraphSelectInput, QueryEdgeSelectInput, QueryExpandInput, QueryFilterInput, QueryIdentityFilterInput, QueryNodeClassInput, QueryNodeGraphSelectInput, QueryNodeInput, QueryNodeSelectInput, QueryNodeSourceInput, QueryPropertyFilterInput, QueryPropertyPredicateBuilder, QueryRangeBoundsInput, QuerySelectInput, QuerySourceInput, } from './authoring/index.js';
|
|
4
4
|
export { QueryAST, QueryASTDecodeError } from './language/index.js';
|
|
5
|
-
export type { EdgeBinding, NodeBinding, QueryBinding, QueryClassFilter, QueryClassPredicate, QueryClassSourceTerm, QueryClassSatisfiesPredicate, QueryClassEqualPredicate, QueryDirection, QueryEdgeSource, QueryEdgeSourceTerm, QueryEdgeSelect, QueryEdgeAST, QueryEdgeIdentityPredicate, QueryEdgeProjection, QueryExpand, QueryFingerprint, QueryIdentityFilter, QueryIdentityPredicate, QueryGraphSelect, QueryNodeAST, QueryNodeIdentityPredicate, QueryNodeProjection, QueryNodeSelect, QueryNodeSource, QueryNodeSourceTerm, QueryNodeTerminalSelect, QueryEdgeTerminalSelect, QueryOrderDirection, QueryPathSourceTerm, QueryPredicate, QueryProjectionShape, QueryPropertyEqualPredicate, QueryPropertyFilter, QueryPropertyOrder, QueryPropertyPredicate, QueryPropertyPresentPredicate, QuerySelect, QuerySingleSourceClassOf, QuerySource, QuerySourceClassesOf, QuerySourceTerm, QueryStep, QueryStructuralLimits, QueryUnrankedPlacement, } from './language/index.js';
|
|
5
|
+
export type { EdgeBinding, NodeBinding, QueryBinding, QueryClassFilter, QueryClassPredicate, QueryClassSourceTerm, QueryClassSatisfiesPredicate, QueryClassEqualPredicate, QueryDirection, QueryEdgeSource, QueryEdgeSourceTerm, QueryEdgeSelect, QueryEdgeAST, QueryEdgeIdentityPredicate, QueryEdgeProjection, QueryExpand, QueryFingerprint, QueryIdentityFilter, QueryIdentityPredicate, QueryGraphSelect, QueryNodeAST, QueryNodeIdentityPredicate, QueryNodeProjection, QueryNodeSelect, QueryNodeSource, QueryNodeSourceTerm, QueryNodeTerminalSelect, QueryEdgeTerminalSelect, QueryOrderDirection, QueryPathSourceTerm, QueryPredicate, QueryProjectionShape, QueryPropertyEqualPredicate, QueryPropertyFilter, QueryPropertyOrder, QueryPropertyPredicate, QueryPropertyPresentPredicate, QueryPropertyRangeOf, QueryPropertyRangePredicate, QueryRangeBound, QueryRangeValue, QuerySelect, QuerySingleSourceClassOf, QuerySource, QuerySourceClassesOf, QuerySourceTerm, QueryStep, QueryStructuralLimits, QueryUnrankedPlacement, } from './language/index.js';
|
|
6
6
|
export { QueryResult, QueryResultDecodeError } from './result/index.js';
|
|
7
7
|
export type { QueryEdgeComponentFor, QueryEdgeGraphResult, QueryEdgeItemFor, QueryEdgeResult, QueryGraphResult, QueryNodeComponentFor, QueryNodeGraphResult, QueryNodeItemFor, QueryNodeReference, QueryNodeResult, QueryResultFor, QueryResultForSelect, QuerySelection, QuerySelectionFor, } from './result/index.js';
|
|
8
|
-
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, } from './order/index.js';
|
|
8
|
+
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, queryRangeContains, } from './order/index.js';
|
|
9
9
|
export type { QueryRank, QueryRankIdentity, QueryRankOrder, QueryRankValue } from './order/index.js';
|
|
10
10
|
export { QueryReference, QueryReferenceError } from './reference/index.js';
|
|
11
11
|
export type { QueryReferenceContext, QueryReferenceClassClosure, QueryReferenceEvaluation, QueryReferenceFrontier, QueryReferenceIdentity, QueryReferenceOptions, QueryReferencePathWitness, QueryReferenceProperty, QueryReferenceTrace, } from './reference/index.js';
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
export { Property, Query } from './authoring/index.js';
|
|
3
3
|
export { QueryAST, QueryASTDecodeError } from './language/index.js';
|
|
4
4
|
export { QueryResult, QueryResultDecodeError } from './result/index.js';
|
|
5
|
-
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, } from './order/index.js';
|
|
5
|
+
export { compareQueryIdentity, compareQueryRank, compareQueryText, compareQueryValue, queryRangeContains, } from './order/index.js';
|
|
6
6
|
export { QueryReference, QueryReferenceError } from './reference/index.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { patterns, PropertyKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
2
2
|
import { ClassKey } from '@astrale-os/kernel-dsl/v1/addressing';
|
|
3
3
|
import * as portable from '@astrale-os/kernel-dsl/value';
|
|
4
|
-
import {
|
|
4
|
+
import { LocalAlias } from '../../graph/index.js';
|
|
5
5
|
import { NodeId } from '../../node/index.js';
|
|
6
6
|
import { NodePath } from '../../path/index.js';
|
|
7
7
|
import { decodeWire } from '../../wire.js';
|
|
@@ -194,6 +194,21 @@ function decodePredicate(input, path, binding) {
|
|
|
194
194
|
if (input.kind === 'property.present') {
|
|
195
195
|
return Object.freeze({ kind: 'property.present', property });
|
|
196
196
|
}
|
|
197
|
+
if (input.kind === 'property.range') {
|
|
198
|
+
const lower = input.lower === undefined ? undefined : Object.freeze({ ...input.lower });
|
|
199
|
+
const upper = input.upper === undefined ? undefined : Object.freeze({ ...input.upper });
|
|
200
|
+
if (lower === undefined && upper === undefined)
|
|
201
|
+
invalid(path, 'Range requires a bound');
|
|
202
|
+
if (lower !== undefined && upper !== undefined && typeof lower.value !== typeof upper.value) {
|
|
203
|
+
invalid(`${path}/upper/value`, 'Range bounds must have one kind');
|
|
204
|
+
}
|
|
205
|
+
return Object.freeze({
|
|
206
|
+
kind: 'property.range',
|
|
207
|
+
property,
|
|
208
|
+
...(lower === undefined ? {} : { lower }),
|
|
209
|
+
...(upper === undefined ? {} : { upper }),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
197
212
|
return Object.freeze({
|
|
198
213
|
kind: 'property.equal',
|
|
199
214
|
property,
|
|
@@ -237,7 +252,7 @@ function decodeClass(input, path) {
|
|
|
237
252
|
function introduce(input, kind, path, symbols) {
|
|
238
253
|
let name;
|
|
239
254
|
try {
|
|
240
|
-
name =
|
|
255
|
+
name = LocalAlias(input);
|
|
241
256
|
}
|
|
242
257
|
catch (cause) {
|
|
243
258
|
invalid(path, 'Invalid binding name', cause);
|
|
@@ -250,7 +265,7 @@ function introduce(input, kind, path, symbols) {
|
|
|
250
265
|
function reference(input, expected, path, symbols) {
|
|
251
266
|
let name;
|
|
252
267
|
try {
|
|
253
|
-
name =
|
|
268
|
+
name = LocalAlias(input);
|
|
254
269
|
}
|
|
255
270
|
catch (cause) {
|
|
256
271
|
invalid(path, 'Invalid binding name', cause);
|
|
@@ -122,6 +122,14 @@ function predicateValue(predicate) {
|
|
|
122
122
|
if (predicate.kind === 'property.present') {
|
|
123
123
|
return { kind: predicate.kind, property: predicate.property };
|
|
124
124
|
}
|
|
125
|
+
if (predicate.kind === 'property.range') {
|
|
126
|
+
return {
|
|
127
|
+
kind: predicate.kind,
|
|
128
|
+
property: predicate.property,
|
|
129
|
+
...(predicate.lower === undefined ? {} : { lower: { ...predicate.lower } }),
|
|
130
|
+
...(predicate.upper === undefined ? {} : { upper: { ...predicate.upper } }),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
125
133
|
if (predicate.kind === 'identity.equal') {
|
|
126
134
|
return {
|
|
127
135
|
kind: predicate.kind,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ClassRef, PropertyKey } from '@astrale-os/kernel-dsl/v1';
|
|
2
2
|
import type * as portable from '@astrale-os/kernel-dsl/value';
|
|
3
3
|
import type { EdgeKey } from '../../edge/index.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { LocalAlias } from '../../graph/index.js';
|
|
5
5
|
import type { NodeId } from '../../node/index.js';
|
|
6
6
|
import type { NodePath } from '../../path/index.js';
|
|
7
7
|
export declare const QUERY_AST_FORMAT: 'astrale.graph.query';
|
|
@@ -20,10 +20,10 @@ export type QueryUnrankedPlacement = 'first' | 'last';
|
|
|
20
20
|
export type QueryFingerprint = `sha256:${string}`;
|
|
21
21
|
declare const NODE_BINDING: unique symbol;
|
|
22
22
|
declare const EDGE_BINDING: unique symbol;
|
|
23
|
-
export type NodeBinding =
|
|
23
|
+
export type NodeBinding = LocalAlias & {
|
|
24
24
|
readonly [NODE_BINDING]: true;
|
|
25
25
|
};
|
|
26
|
-
export type EdgeBinding =
|
|
26
|
+
export type EdgeBinding = LocalAlias & {
|
|
27
27
|
readonly [EDGE_BINDING]: true;
|
|
28
28
|
};
|
|
29
29
|
export type QueryBinding = NodeBinding | EdgeBinding;
|
|
@@ -76,7 +76,25 @@ export interface QueryPropertyPresentPredicate {
|
|
|
76
76
|
readonly kind: 'property.present';
|
|
77
77
|
readonly property: PropertyKey;
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
/** A range bound value: a finite number or a text, compared in Core order. */
|
|
80
|
+
export type QueryRangeValue = number | string;
|
|
81
|
+
/** One end of a range; an exclusive bound excludes a value equal to it. */
|
|
82
|
+
export interface QueryRangeBound<Value extends QueryRangeValue = QueryRangeValue> {
|
|
83
|
+
readonly value: Value;
|
|
84
|
+
readonly inclusive: boolean;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* A stored value of the bounds' kind within at least one and at most two bounds: numeric order for
|
|
88
|
+
* numbers, code-point order for texts. Both bounds have one kind. Any other value never passes.
|
|
89
|
+
*/
|
|
90
|
+
export type QueryPropertyRangePredicate = QueryPropertyRangeOf<number> | QueryPropertyRangeOf<string>;
|
|
91
|
+
export interface QueryPropertyRangeOf<Value extends QueryRangeValue> {
|
|
92
|
+
readonly kind: 'property.range';
|
|
93
|
+
readonly property: PropertyKey;
|
|
94
|
+
readonly lower?: QueryRangeBound<Value>;
|
|
95
|
+
readonly upper?: QueryRangeBound<Value>;
|
|
96
|
+
}
|
|
97
|
+
export type QueryPropertyPredicate = QueryPropertyEqualPredicate | QueryPropertyPresentPredicate | QueryPropertyRangePredicate;
|
|
80
98
|
export interface QueryNodeIdentityPredicate {
|
|
81
99
|
readonly kind: 'identity.equal';
|
|
82
100
|
readonly identity: NodeId;
|