@hops-ops/distributed 0.0.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/README.md +454 -0
- package/dist/auth-headers.d.ts +8 -0
- package/dist/auth-headers.js +35 -0
- package/dist/diagnostics.d.ts +2 -0
- package/dist/diagnostics.js +1 -0
- package/dist/document.d.ts +8 -0
- package/dist/document.js +6 -0
- package/dist/identity.d.ts +23 -0
- package/dist/identity.js +73 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +6 -0
- package/dist/internal/cache-engine/create.d.ts +5 -0
- package/dist/internal/cache-engine/create.js +7 -0
- package/dist/internal/cache-engine/engine.d.ts +32 -0
- package/dist/internal/cache-engine/engine.js +1287 -0
- package/dist/internal/cache-engine/errors.d.ts +5 -0
- package/dist/internal/cache-engine/errors.js +10 -0
- package/dist/internal/cache-engine/helpers.d.ts +55 -0
- package/dist/internal/cache-engine/helpers.js +545 -0
- package/dist/internal/cache-engine/index.d.ts +3 -0
- package/dist/internal/cache-engine/index.js +2 -0
- package/dist/internal/cache-engine/types.d.ts +300 -0
- package/dist/internal/cache-engine/types.js +1 -0
- package/dist/internal/cache-engine.d.ts +3 -0
- package/dist/internal/cache-engine.js +2 -0
- package/dist/lib/assert-name.d.ts +2 -0
- package/dist/lib/assert-name.js +6 -0
- package/dist/lib/compare-code-units.d.ts +2 -0
- package/dist/lib/compare-code-units.js +4 -0
- package/dist/lib/deep-equal.d.ts +2 -0
- package/dist/lib/deep-equal.js +24 -0
- package/dist/lib/freeze-record.d.ts +2 -0
- package/dist/lib/freeze-record.js +13 -0
- package/dist/lib/index.d.ts +6 -0
- package/dist/lib/index.js +6 -0
- package/dist/lib/is-plain-record.d.ts +2 -0
- package/dist/lib/is-plain-record.js +8 -0
- package/dist/lib/report.d.ts +7 -0
- package/dist/lib/report.js +26 -0
- package/dist/protocol.d.ts +179 -0
- package/dist/protocol.js +558 -0
- package/dist/react/context.d.ts +20 -0
- package/dist/react/context.js +24 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +3 -0
- package/dist/react/query.d.ts +20 -0
- package/dist/react/query.js +99 -0
- package/dist/replica/command-id.d.ts +2 -0
- package/dist/replica/command-id.js +19 -0
- package/dist/replica/command-runtime/constants.d.ts +5 -0
- package/dist/replica/command-runtime/constants.js +5 -0
- package/dist/replica/command-runtime/create.d.ts +2 -0
- package/dist/replica/command-runtime/create.js +644 -0
- package/dist/replica/command-runtime/errors.d.ts +16 -0
- package/dist/replica/command-runtime/errors.js +41 -0
- package/dist/replica/command-runtime/index.d.ts +5 -0
- package/dist/replica/command-runtime/index.js +4 -0
- package/dist/replica/command-runtime/lib/binding.d.ts +4 -0
- package/dist/replica/command-runtime/lib/binding.js +64 -0
- package/dist/replica/command-runtime/lib/effects.d.ts +11 -0
- package/dist/replica/command-runtime/lib/effects.js +89 -0
- package/dist/replica/command-runtime/lib/index.d.ts +9 -0
- package/dist/replica/command-runtime/lib/index.js +9 -0
- package/dist/replica/command-runtime/lib/inventory.d.ts +10 -0
- package/dist/replica/command-runtime/lib/inventory.js +141 -0
- package/dist/replica/command-runtime/lib/output.d.ts +13 -0
- package/dist/replica/command-runtime/lib/output.js +190 -0
- package/dist/replica/command-runtime/lib/projection.d.ts +20 -0
- package/dist/replica/command-runtime/lib/projection.js +255 -0
- package/dist/replica/command-runtime/lib/status.d.ts +7 -0
- package/dist/replica/command-runtime/lib/status.js +127 -0
- package/dist/replica/command-runtime/lib/transport.d.ts +16 -0
- package/dist/replica/command-runtime/lib/transport.js +112 -0
- package/dist/replica/command-runtime/lib/util.d.ts +16 -0
- package/dist/replica/command-runtime/lib/util.js +127 -0
- package/dist/replica/command-runtime/lifecycle.d.ts +11 -0
- package/dist/replica/command-runtime/lifecycle.js +13 -0
- package/dist/replica/command-runtime/symbols.d.ts +30 -0
- package/dist/replica/command-runtime/symbols.js +30 -0
- package/dist/replica/command-runtime/types.d.ts +222 -0
- package/dist/replica/command-runtime/types.js +1 -0
- package/dist/replica/command-runtime.d.ts +3 -0
- package/dist/replica/command-runtime.js +2 -0
- package/dist/replica/commands/clone.d.ts +12 -0
- package/dist/replica/commands/clone.js +187 -0
- package/dist/replica/commands/constants.d.ts +6 -0
- package/dist/replica/commands/constants.js +6 -0
- package/dist/replica/commands/errors.d.ts +7 -0
- package/dist/replica/commands/errors.js +22 -0
- package/dist/replica/commands/implementation.d.ts +8 -0
- package/dist/replica/commands/implementation.js +8 -0
- package/dist/replica/commands/index.d.ts +5 -0
- package/dist/replica/commands/index.js +4 -0
- package/dist/replica/commands/prepare.d.ts +27 -0
- package/dist/replica/commands/prepare.js +77 -0
- package/dist/replica/commands/presets.d.ts +12 -0
- package/dist/replica/commands/presets.js +84 -0
- package/dist/replica/commands/receipt.d.ts +3 -0
- package/dist/replica/commands/receipt.js +36 -0
- package/dist/replica/commands/resolve.d.ts +11 -0
- package/dist/replica/commands/resolve.js +165 -0
- package/dist/replica/commands/types.d.ts +278 -0
- package/dist/replica/commands/types.js +2 -0
- package/dist/replica/commands/util.d.ts +21 -0
- package/dist/replica/commands/util.js +96 -0
- package/dist/replica/commands/validate.d.ts +18 -0
- package/dist/replica/commands/validate.js +477 -0
- package/dist/replica/commands.d.ts +3 -0
- package/dist/replica/commands.js +2 -0
- package/dist/replica/diagnostics/event-log.d.ts +4 -0
- package/dist/replica/diagnostics/event-log.js +463 -0
- package/dist/replica/diagnostics/implementation.d.ts +4 -0
- package/dist/replica/diagnostics/implementation.js +4 -0
- package/dist/replica/diagnostics/index.d.ts +2 -0
- package/dist/replica/diagnostics/index.js +1 -0
- package/dist/replica/diagnostics/inspect.d.ts +6 -0
- package/dist/replica/diagnostics/inspect.js +170 -0
- package/dist/replica/diagnostics/types.d.ts +295 -0
- package/dist/replica/diagnostics/types.js +2 -0
- package/dist/replica/diagnostics.d.ts +3 -0
- package/dist/replica/diagnostics.js +2 -0
- package/dist/replica/distributed-replica/clocks.d.ts +23 -0
- package/dist/replica/distributed-replica/clocks.js +156 -0
- package/dist/replica/distributed-replica/constants.d.ts +12 -0
- package/dist/replica/distributed-replica/constants.js +10 -0
- package/dist/replica/distributed-replica/helpers.d.ts +48 -0
- package/dist/replica/distributed-replica/helpers.js +445 -0
- package/dist/replica/distributed-replica/hydration.d.ts +19 -0
- package/dist/replica/distributed-replica/hydration.js +380 -0
- package/dist/replica/distributed-replica/impl-diagnostics.d.ts +22 -0
- package/dist/replica/distributed-replica/impl-diagnostics.js +189 -0
- package/dist/replica/distributed-replica/impl-fetch-live.d.ts +39 -0
- package/dist/replica/distributed-replica/impl-fetch-live.js +395 -0
- package/dist/replica/distributed-replica/impl-hydration-orchestrate.d.ts +56 -0
- package/dist/replica/distributed-replica/impl-hydration-orchestrate.js +299 -0
- package/dist/replica/distributed-replica/impl-optimistic.d.ts +31 -0
- package/dist/replica/distributed-replica/impl-optimistic.js +172 -0
- package/dist/replica/distributed-replica/impl-protocol.d.ts +53 -0
- package/dist/replica/distributed-replica/impl-protocol.js +108 -0
- package/dist/replica/distributed-replica/impl.d.ts +44 -0
- package/dist/replica/distributed-replica/impl.js +1776 -0
- package/dist/replica/distributed-replica/index.d.ts +2 -0
- package/dist/replica/distributed-replica/index.js +4 -0
- package/dist/replica/distributed-replica/optimistic.d.ts +30 -0
- package/dist/replica/distributed-replica/optimistic.js +221 -0
- package/dist/replica/distributed-replica/types.d.ts +147 -0
- package/dist/replica/distributed-replica/types.js +1 -0
- package/dist/replica/distributed-replica/watch.d.ts +19 -0
- package/dist/replica/distributed-replica/watch.js +95 -0
- package/dist/replica/distributed-replica.d.ts +2 -0
- package/dist/replica/distributed-replica.js +2 -0
- package/dist/replica/graphql-transport.d.ts +24 -0
- package/dist/replica/graphql-transport.js +122 -0
- package/dist/replica/identity/clone.d.ts +6 -0
- package/dist/replica/identity/clone.js +54 -0
- package/dist/replica/identity/codec.d.ts +48 -0
- package/dist/replica/identity/codec.js +789 -0
- package/dist/replica/identity/constants.d.ts +3 -0
- package/dist/replica/identity/constants.js +18 -0
- package/dist/replica/identity/implementation.d.ts +5 -0
- package/dist/replica/identity/implementation.js +5 -0
- package/dist/replica/identity/index.d.ts +3 -0
- package/dist/replica/identity/index.js +3 -0
- package/dist/replica/identity/keys.d.ts +29 -0
- package/dist/replica/identity/keys.js +173 -0
- package/dist/replica/identity.d.ts +2 -0
- package/dist/replica/identity.js +2 -0
- package/dist/replica/index-maintenance/engine.d.ts +84 -0
- package/dist/replica/index-maintenance/engine.js +677 -0
- package/dist/replica/index-maintenance/implementation.d.ts +4 -0
- package/dist/replica/index-maintenance/implementation.js +4 -0
- package/dist/replica/index-maintenance/index.d.ts +2 -0
- package/dist/replica/index-maintenance/index.js +1 -0
- package/dist/replica/index-maintenance/registry.d.ts +2 -0
- package/dist/replica/index-maintenance/registry.js +49 -0
- package/dist/replica/index-maintenance/types.d.ts +58 -0
- package/dist/replica/index-maintenance/types.js +1 -0
- package/dist/replica/index-maintenance.d.ts +3 -0
- package/dist/replica/index-maintenance.js +2 -0
- package/dist/replica/index.d.ts +17 -0
- package/dist/replica/index.js +9 -0
- package/dist/replica/materialize.d.ts +10 -0
- package/dist/replica/materialize.js +163 -0
- package/dist/replica/normalize.d.ts +27 -0
- package/dist/replica/normalize.js +298 -0
- package/dist/replica/operation-binding.d.ts +14 -0
- package/dist/replica/operation-binding.js +76 -0
- package/dist/replica/persistence/idb.d.ts +20 -0
- package/dist/replica/persistence/idb.js +193 -0
- package/dist/replica/persistence/implementation.d.ts +4 -0
- package/dist/replica/persistence/implementation.js +4 -0
- package/dist/replica/persistence/index.d.ts +2 -0
- package/dist/replica/persistence/index.js +1 -0
- package/dist/replica/persistence/state.d.ts +104 -0
- package/dist/replica/persistence/state.js +734 -0
- package/dist/replica/persistence/types.d.ts +54 -0
- package/dist/replica/persistence/types.js +1 -0
- package/dist/replica/persistence.d.ts +3 -0
- package/dist/replica/persistence.js +2 -0
- package/dist/replica/query-plan/constants.d.ts +13 -0
- package/dist/replica/query-plan/constants.js +7 -0
- package/dist/replica/query-plan/filter.d.ts +39 -0
- package/dist/replica/query-plan/filter.js +544 -0
- package/dist/replica/query-plan/index.d.ts +4 -0
- package/dist/replica/query-plan/index.js +3 -0
- package/dist/replica/query-plan/order.d.ts +11 -0
- package/dist/replica/query-plan/order.js +158 -0
- package/dist/replica/query-plan/pagination.d.ts +6 -0
- package/dist/replica/query-plan/pagination.js +90 -0
- package/dist/replica/query-plan/resolve.d.ts +14 -0
- package/dist/replica/query-plan/resolve.js +163 -0
- package/dist/replica/query-plan/types.d.ts +89 -0
- package/dist/replica/query-plan/types.js +1 -0
- package/dist/replica/query-plan/util.d.ts +13 -0
- package/dist/replica/query-plan/util.js +62 -0
- package/dist/replica/query-plan.d.ts +3 -0
- package/dist/replica/query-plan.js +2 -0
- package/dist/replica/revalidation.d.ts +9 -0
- package/dist/replica/revalidation.js +86 -0
- package/dist/replica/selection.d.ts +20 -0
- package/dist/replica/selection.js +109 -0
- package/dist/replica/types.d.ts +657 -0
- package/dist/replica/types.js +1 -0
- package/dist/request.d.ts +17 -0
- package/dist/request.js +123 -0
- package/dist/sveltekit/auth.d.ts +18 -0
- package/dist/sveltekit/auth.js +9 -0
- package/dist/sveltekit/context.d.ts +28 -0
- package/dist/sveltekit/context.js +58 -0
- package/dist/sveltekit/index.d.ts +4 -0
- package/dist/sveltekit/index.js +4 -0
- package/dist/sveltekit/replica.d.ts +145 -0
- package/dist/sveltekit/replica.js +491 -0
- package/dist/sveltekit/server-replica.d.ts +52 -0
- package/dist/sveltekit/server-replica.js +176 -0
- package/dist/sveltekit/vite.d.ts +103 -0
- package/dist/sveltekit/vite.js +878 -0
- package/dist/types.d.ts +33 -0
- package/dist/types.js +1 -0
- package/dist/websocket.d.ts +41 -0
- package/dist/websocket.js +187 -0
- package/package.json +95 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const GRAPHQL_NAME = /^[_A-Za-z][_0-9A-Za-z]*$/;
|
|
2
|
+
export const MAX_VARIABLE_CODEC_DEPTH = 64;
|
|
3
|
+
export const FILTER_OPERATORS = new Set([
|
|
4
|
+
'_eq',
|
|
5
|
+
'_neq',
|
|
6
|
+
'_gt',
|
|
7
|
+
'_gte',
|
|
8
|
+
'_lt',
|
|
9
|
+
'_lte',
|
|
10
|
+
'_in',
|
|
11
|
+
'_nin',
|
|
12
|
+
'_is_null',
|
|
13
|
+
'_like',
|
|
14
|
+
'_ilike',
|
|
15
|
+
'_contains',
|
|
16
|
+
'_contained_in',
|
|
17
|
+
'_has_key'
|
|
18
|
+
]);
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { replicaRecordKey, replicaIndexKey, resolveArguments, resolveReplicaArgumentValue, coverageFromArtifact } from './keys.js';
|
|
2
|
+
export { canonicalizeOperationVariables } from './codec.js';
|
|
3
|
+
export { canonicalVariables, cloneJsonObject, cloneJsonValue, canonicalCacheValue } from './clone.js';
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { replicaRecordKey, replicaIndexKey, resolveArguments, resolveReplicaArgumentValue, coverageFromArtifact } from './keys.js';
|
|
2
|
+
export { canonicalizeOperationVariables } from './codec.js';
|
|
3
|
+
export { canonicalVariables, cloneJsonObject, cloneJsonValue, canonicalCacheValue } from './clone.js';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { GraphqlVariables } from '../../types.js';
|
|
2
|
+
import type { ReplicaArgumentValue, ReplicaArgumentsArtifact, ReplicaCoverageArtifact, ReplicaIdentity, ReplicaIndexCoverage, ReplicaModelArtifact, ReplicaValue } from '../types.js';
|
|
3
|
+
export declare function replicaRecordKey(model: ReplicaModelArtifact, identity: ReplicaIdentity): string;
|
|
4
|
+
export declare function replicaIndexKey(input: {
|
|
5
|
+
readonly parent?: string;
|
|
6
|
+
readonly field: string;
|
|
7
|
+
readonly arguments?: Readonly<Record<string, ReplicaValue>>;
|
|
8
|
+
}): string;
|
|
9
|
+
export declare function resolveArguments(artifact: ReplicaArgumentsArtifact | undefined, variables: GraphqlVariables, coverage?: ReplicaCoverageArtifact): Readonly<Record<string, ReplicaValue>>;
|
|
10
|
+
export declare function resolveReplicaArgumentValue(source: ReplicaArgumentValue, variables: GraphqlVariables, position?: 'argument' | 'object' | 'list'): ReplicaValue | undefined;
|
|
11
|
+
export declare function coverageFromArtifact(artifact: ReplicaCoverageArtifact | undefined, argumentsValue: Readonly<Record<string, ReplicaValue>>, returned: number): ReplicaIndexCoverage;
|
|
12
|
+
export type OffsetCoverageArtifact = Extract<ReplicaCoverageArtifact, {
|
|
13
|
+
readonly kind: 'offset';
|
|
14
|
+
}>;
|
|
15
|
+
export declare function effectiveOffsetArguments(argumentsValue: Readonly<Record<string, ReplicaValue>>, artifact: OffsetCoverageArtifact): Readonly<Record<string, ReplicaValue>>;
|
|
16
|
+
export declare function effectiveOffsetWindow(argumentsValue: Readonly<Record<string, ReplicaValue>>, artifact: OffsetCoverageArtifact): {
|
|
17
|
+
readonly offset: number;
|
|
18
|
+
readonly limit?: number;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Distributed's SQL compiler treats an omitted, explicit-null, or negative
|
|
22
|
+
* nullable Int as absent before applying the server default. Other values
|
|
23
|
+
* cannot appear in a successful GraphQL response and remain fail-fast here.
|
|
24
|
+
*/
|
|
25
|
+
export declare function serverNonNegativeIntegerArgument(argumentsValue: Readonly<Record<string, ReplicaValue>>, argument: string | undefined): number | undefined;
|
|
26
|
+
export declare function coverageBound(value: number | undefined, field: string): number | undefined;
|
|
27
|
+
export declare function cacheArgument<K extends 'after' | 'before'>(argumentsValue: Readonly<Record<string, ReplicaValue>>, argument: string | undefined, key: K): Partial<Record<K, ReplicaValue>>;
|
|
28
|
+
export declare function numericCoverageArgument<K extends 'first' | 'last'>(argumentsValue: Readonly<Record<string, ReplicaValue>>, argument: string | undefined, key: K): Partial<Record<K, number>>;
|
|
29
|
+
export declare function numericArgument(argumentsValue: Readonly<Record<string, ReplicaValue>>, argument: string | undefined): number | undefined;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { cacheIndexKey } from '../../internal/cache-engine.js';
|
|
2
|
+
import { assertName } from '../../lib/assert-name.js';
|
|
3
|
+
import { freezeRecord } from '../../lib/freeze-record.js';
|
|
4
|
+
import { canonicalCacheValue, cloneJsonValue } from './clone.js';
|
|
5
|
+
export function replicaRecordKey(model, identity) {
|
|
6
|
+
assertName(model.id, 'model id');
|
|
7
|
+
if (!Array.isArray(model.identityFields) || model.identityFields.length === 0) {
|
|
8
|
+
throw new TypeError(`model ${model.id} must declare at least one identity field`);
|
|
9
|
+
}
|
|
10
|
+
const parts = Array.isArray(identity) ? identity : [identity];
|
|
11
|
+
if (parts.length !== model.identityFields.length) {
|
|
12
|
+
throw new TypeError(`model ${model.id} identity expected ${model.identityFields.length} part(s), received ${parts.length}`);
|
|
13
|
+
}
|
|
14
|
+
return `record:${encodeURIComponent(model.id)}:${canonicalCacheValue(parts.map((part) => cloneJsonValue(part)))}`;
|
|
15
|
+
}
|
|
16
|
+
export function replicaIndexKey(input) {
|
|
17
|
+
return cacheIndexKey({
|
|
18
|
+
...(input.parent === undefined ? {} : { parent: input.parent }),
|
|
19
|
+
field: input.field,
|
|
20
|
+
arguments: input.arguments ?? {}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function resolveArguments(artifact, variables, coverage) {
|
|
24
|
+
const entries = [];
|
|
25
|
+
for (const [argument, source] of Object.entries(artifact ?? {})) {
|
|
26
|
+
assertName(argument, 'GraphQL argument');
|
|
27
|
+
const value = resolveReplicaArgumentValue(source, variables);
|
|
28
|
+
if (value !== undefined)
|
|
29
|
+
entries.push([argument, value]);
|
|
30
|
+
}
|
|
31
|
+
const resolved = freezeRecord(entries);
|
|
32
|
+
return coverage?.kind === 'offset'
|
|
33
|
+
? effectiveOffsetArguments(resolved, coverage)
|
|
34
|
+
: resolved;
|
|
35
|
+
}
|
|
36
|
+
export function resolveReplicaArgumentValue(source, variables, position = 'argument') {
|
|
37
|
+
if (source.kind === 'literal')
|
|
38
|
+
return cloneJsonValue(source.value);
|
|
39
|
+
if (source.kind === 'variable') {
|
|
40
|
+
assertName(source.name, 'GraphQL variable');
|
|
41
|
+
if (!Object.prototype.hasOwnProperty.call(variables, source.name) ||
|
|
42
|
+
variables[source.name] === undefined) {
|
|
43
|
+
return position === 'list' ? null : undefined;
|
|
44
|
+
}
|
|
45
|
+
return cloneJsonValue(variables[source.name]);
|
|
46
|
+
}
|
|
47
|
+
if (source.kind === 'list') {
|
|
48
|
+
if (!Array.isArray(source.items)) {
|
|
49
|
+
throw new TypeError('GraphQL list argument source must contain an items array');
|
|
50
|
+
}
|
|
51
|
+
return Object.freeze(source.items.map((item) => resolveReplicaArgumentValue(item, variables, 'list') ?? null));
|
|
52
|
+
}
|
|
53
|
+
if (source.kind === 'object') {
|
|
54
|
+
if (source.fields === null ||
|
|
55
|
+
typeof source.fields !== 'object' ||
|
|
56
|
+
Array.isArray(source.fields)) {
|
|
57
|
+
throw new TypeError('GraphQL object argument source must contain a fields object');
|
|
58
|
+
}
|
|
59
|
+
const entries = [];
|
|
60
|
+
for (const [field, value] of Object.entries(source.fields)) {
|
|
61
|
+
assertName(field, 'GraphQL input field');
|
|
62
|
+
const resolved = resolveReplicaArgumentValue(value, variables, 'object');
|
|
63
|
+
if (resolved !== undefined)
|
|
64
|
+
entries.push([field, resolved]);
|
|
65
|
+
}
|
|
66
|
+
return freezeRecord(entries);
|
|
67
|
+
}
|
|
68
|
+
throw new TypeError('unsupported argument source');
|
|
69
|
+
}
|
|
70
|
+
export function coverageFromArtifact(artifact, argumentsValue, returned) {
|
|
71
|
+
if (artifact === undefined || artifact.kind === 'complete') {
|
|
72
|
+
return Object.freeze({ kind: 'complete' });
|
|
73
|
+
}
|
|
74
|
+
if (artifact.kind === 'offset') {
|
|
75
|
+
const window = effectiveOffsetWindow(argumentsValue, artifact);
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
kind: 'offset',
|
|
78
|
+
offset: window.offset,
|
|
79
|
+
...(window.limit === undefined ? {} : { limit: window.limit }),
|
|
80
|
+
returned
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return Object.freeze({
|
|
84
|
+
kind: 'cursor',
|
|
85
|
+
...cacheArgument(argumentsValue, artifact.afterArgument, 'after'),
|
|
86
|
+
...cacheArgument(argumentsValue, artifact.beforeArgument, 'before'),
|
|
87
|
+
...numericCoverageArgument(argumentsValue, artifact.firstArgument, 'first'),
|
|
88
|
+
...numericCoverageArgument(argumentsValue, artifact.lastArgument, 'last')
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
export function effectiveOffsetArguments(argumentsValue, artifact) {
|
|
92
|
+
const window = effectiveOffsetWindow(argumentsValue, artifact);
|
|
93
|
+
const entries = new Map(Object.entries(argumentsValue));
|
|
94
|
+
if (artifact.offsetArgument !== undefined) {
|
|
95
|
+
assertName(artifact.offsetArgument, 'offset pagination argument');
|
|
96
|
+
entries.set(artifact.offsetArgument, window.offset);
|
|
97
|
+
}
|
|
98
|
+
if (artifact.limitArgument !== undefined) {
|
|
99
|
+
assertName(artifact.limitArgument, 'limit pagination argument');
|
|
100
|
+
if (window.limit === undefined)
|
|
101
|
+
entries.delete(artifact.limitArgument);
|
|
102
|
+
else
|
|
103
|
+
entries.set(artifact.limitArgument, window.limit);
|
|
104
|
+
}
|
|
105
|
+
return freezeRecord([...entries.entries()]);
|
|
106
|
+
}
|
|
107
|
+
export function effectiveOffsetWindow(argumentsValue, artifact) {
|
|
108
|
+
const configuredDefault = coverageBound(artifact.defaultLimit, 'defaultLimit');
|
|
109
|
+
const configuredMax = coverageBound(artifact.maxLimit, 'maxLimit');
|
|
110
|
+
if (configuredDefault !== undefined &&
|
|
111
|
+
configuredMax !== undefined &&
|
|
112
|
+
configuredDefault > configuredMax) {
|
|
113
|
+
throw new TypeError('offset coverage defaultLimit must not exceed maxLimit');
|
|
114
|
+
}
|
|
115
|
+
const offset = serverNonNegativeIntegerArgument(argumentsValue, artifact.offsetArgument) ?? 0;
|
|
116
|
+
const requested = serverNonNegativeIntegerArgument(argumentsValue, artifact.limitArgument);
|
|
117
|
+
const selected = requested ?? configuredDefault;
|
|
118
|
+
const limit = selected === undefined || configuredMax === undefined
|
|
119
|
+
? selected
|
|
120
|
+
: Math.min(selected, configuredMax);
|
|
121
|
+
return {
|
|
122
|
+
offset,
|
|
123
|
+
...(limit === undefined ? {} : { limit })
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Distributed's SQL compiler treats an omitted, explicit-null, or negative
|
|
128
|
+
* nullable Int as absent before applying the server default. Other values
|
|
129
|
+
* cannot appear in a successful GraphQL response and remain fail-fast here.
|
|
130
|
+
*/
|
|
131
|
+
export function serverNonNegativeIntegerArgument(argumentsValue, argument) {
|
|
132
|
+
if (argument === undefined ||
|
|
133
|
+
!Object.prototype.hasOwnProperty.call(argumentsValue, argument)) {
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
const value = argumentsValue[argument];
|
|
137
|
+
if (value === null)
|
|
138
|
+
return undefined;
|
|
139
|
+
if (!Number.isSafeInteger(value)) {
|
|
140
|
+
throw new TypeError(`pagination argument ${argument} must be an integer or null`);
|
|
141
|
+
}
|
|
142
|
+
if (value < 0)
|
|
143
|
+
return undefined;
|
|
144
|
+
return value === 0 ? 0 : value;
|
|
145
|
+
}
|
|
146
|
+
export function coverageBound(value, field) {
|
|
147
|
+
if (value === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
150
|
+
throw new TypeError(`offset coverage ${field} must be a non-negative safe integer`);
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
export function cacheArgument(argumentsValue, argument, key) {
|
|
155
|
+
if (argument === undefined || !Object.prototype.hasOwnProperty.call(argumentsValue, argument)) {
|
|
156
|
+
return {};
|
|
157
|
+
}
|
|
158
|
+
return { [key]: argumentsValue[argument] };
|
|
159
|
+
}
|
|
160
|
+
export function numericCoverageArgument(argumentsValue, argument, key) {
|
|
161
|
+
const value = numericArgument(argumentsValue, argument);
|
|
162
|
+
return value === undefined ? {} : { [key]: value };
|
|
163
|
+
}
|
|
164
|
+
export function numericArgument(argumentsValue, argument) {
|
|
165
|
+
if (argument === undefined || !Object.prototype.hasOwnProperty.call(argumentsValue, argument)) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
const value = argumentsValue[argument];
|
|
169
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
170
|
+
throw new TypeError(`pagination argument ${argument} must be a non-negative integer`);
|
|
171
|
+
}
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Replica identity/keys and variable codec; implementation in ./identity/. */
|
|
2
|
+
export { canonicalCacheValue, canonicalVariables, canonicalizeOperationVariables, cloneJsonObject, cloneJsonValue, coverageFromArtifact, replicaIndexKey, replicaRecordKey, resolveArguments, resolveReplicaArgumentValue } from './identity/index.js';
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Replica identity/keys and variable codec; implementation in ./identity/. */
|
|
2
|
+
export { canonicalCacheValue, canonicalVariables, canonicalizeOperationVariables, cloneJsonObject, cloneJsonValue, coverageFromArtifact, replicaIndexKey, replicaRecordKey, resolveArguments, resolveReplicaArgumentValue } from './identity/index.js';
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { GraphqlVariables } from '../../types.js';
|
|
2
|
+
import type { DistributedTrustedPreset } from '../../protocol.js';
|
|
3
|
+
import type { ReplicaFilterArtifact, ReplicaCoverageArtifact, ReplicaIndexRecordChange, ReplicaIndexRelationshipChange, ReplicaIndexSemanticChange, ReplicaObjectBranch, ReplicaOperationArtifact, ReplicaOrderArtifact, ReplicaPaginationArtifact, ReplicaRelationshipArtifact, ReplicaRootSelection, ReplicaSurfaceTrustedPresetDescriptor, ReplicaValue } from '../types.js';
|
|
4
|
+
import type { ReplicaIndexMaintenanceDecision, ReplicaIndexMaintenanceIndex, ReplicaIndexMaintenanceReason, ReplicaIndexMaintenanceReasonCode, ReplicaIndexMaintenanceRecord, ReplicaIndexSemanticLayer } from './types.js';
|
|
5
|
+
export type PlanKind = 'entity' | 'relationship' | 'snapshot';
|
|
6
|
+
export type RegisteredPlan = {
|
|
7
|
+
readonly registration: string;
|
|
8
|
+
readonly kind: PlanKind;
|
|
9
|
+
readonly exactIndexKey?: string;
|
|
10
|
+
readonly parentModel?: string;
|
|
11
|
+
readonly targetModel?: string;
|
|
12
|
+
readonly field: string;
|
|
13
|
+
readonly arguments: Readonly<Record<string, ReplicaValue>>;
|
|
14
|
+
readonly dependencies: readonly string[];
|
|
15
|
+
readonly cardinality: 'one' | 'many';
|
|
16
|
+
readonly filter?: ReplicaFilterArtifact;
|
|
17
|
+
readonly order?: ReplicaOrderArtifact;
|
|
18
|
+
readonly pagination?: ReplicaPaginationArtifact;
|
|
19
|
+
readonly coverage?: ReplicaCoverageArtifact;
|
|
20
|
+
readonly relationship?: ReplicaRelationshipArtifact;
|
|
21
|
+
readonly variables: GraphqlVariables;
|
|
22
|
+
readonly trustedPresets: readonly ReplicaSurfaceTrustedPresetDescriptor[];
|
|
23
|
+
readonly path: readonly (string | number)[];
|
|
24
|
+
readonly signature: string;
|
|
25
|
+
};
|
|
26
|
+
export type MutableRecord = {
|
|
27
|
+
readonly key: string;
|
|
28
|
+
readonly model: string;
|
|
29
|
+
fields: Record<string, ReplicaValue>;
|
|
30
|
+
};
|
|
31
|
+
export type AppliedChanges = {
|
|
32
|
+
readonly baseRecords: ReadonlyMap<string, MutableRecord>;
|
|
33
|
+
readonly records: Map<string, MutableRecord>;
|
|
34
|
+
readonly recordChanges: readonly ReplicaIndexRecordChange[];
|
|
35
|
+
readonly relationshipChanges: readonly ReplicaIndexRelationshipChange[];
|
|
36
|
+
readonly invalidatedDependencies: ReadonlySet<string>;
|
|
37
|
+
readonly allDependencies: ReadonlySet<string>;
|
|
38
|
+
};
|
|
39
|
+
export declare function formatReplicaIndexStaleReason(reasonValue: ReplicaIndexMaintenanceReason): string;
|
|
40
|
+
export declare function compilePlans(registration: string, artifact: ReplicaOperationArtifact<unknown, GraphqlVariables>, variables: GraphqlVariables): readonly RegisteredPlan[];
|
|
41
|
+
export declare function compileSelectionPlans(output: RegisteredPlan[], registration: string, selection: ReplicaRootSelection['selection'], parentModel: string | undefined, variables: GraphqlVariables, trustedPresets: readonly ReplicaSurfaceTrustedPresetDescriptor[], path: readonly (string | number)[]): void;
|
|
42
|
+
export declare function compileBranchPlan(output: RegisteredPlan[], registration: string, branch: ReplicaObjectBranch, parentModel: string | undefined, variables: GraphqlVariables, trustedPresets: readonly ReplicaSurfaceTrustedPresetDescriptor[], path: readonly (string | number)[]): void;
|
|
43
|
+
export declare function plan(value: Omit<RegisteredPlan, 'signature'>): RegisteredPlan;
|
|
44
|
+
export declare function selectionModel(selection: ReplicaRootSelection['selection']): string | undefined;
|
|
45
|
+
export declare function instantiatePlans(plans: readonly RegisteredPlan[], indexes: ReadonlyMap<string, ReplicaIndexMaintenanceIndex>): Map<string, RegisteredPlan[]>;
|
|
46
|
+
export declare function appendPlan(output: Map<string, RegisteredPlan[]>, key: string, value: RegisteredPlan): void;
|
|
47
|
+
export declare function applyLayers(base: readonly ReplicaIndexMaintenanceRecord[], layers: readonly ReplicaIndexSemanticLayer[]): AppliedChanges;
|
|
48
|
+
export declare function validateIndexes(input: readonly ReplicaIndexMaintenanceIndex[]): Map<string, ReplicaIndexMaintenanceIndex>;
|
|
49
|
+
export declare function planAffected(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, changes: AppliedChanges): boolean;
|
|
50
|
+
export declare function evaluatePlan(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, changes: AppliedChanges, trustedPresets: readonly DistributedTrustedPreset[]): ReplicaIndexMaintenanceDecision;
|
|
51
|
+
export declare function maintainEntityIndex(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, changes: AppliedChanges, trustedPresets: readonly DistributedTrustedPreset[]): ReplicaIndexMaintenanceDecision;
|
|
52
|
+
export declare function certifyOffsetCoverage(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, confirmedRecords: number, changeKind: 'insert' | 'delete' | 'reorder' | 'stable_update'): ReplicaIndexMaintenanceReason | undefined;
|
|
53
|
+
export declare function parentRecordChangeAffectsRelationship(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, change: ReplicaIndexRecordChange): boolean;
|
|
54
|
+
export declare function relationshipMembership(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, target: MutableRecord | undefined, records: ReadonlyMap<string, MutableRecord>): {
|
|
55
|
+
readonly related: boolean;
|
|
56
|
+
} | {
|
|
57
|
+
readonly reason: ReplicaIndexMaintenanceReason;
|
|
58
|
+
};
|
|
59
|
+
export declare function evaluateMembership(planValue: RegisteredPlan, record: MutableRecord, trustedPresets: readonly DistributedTrustedPreset[]): {
|
|
60
|
+
readonly matches: boolean;
|
|
61
|
+
} | {
|
|
62
|
+
readonly reason: ReplicaIndexMaintenanceReason;
|
|
63
|
+
};
|
|
64
|
+
export declare function sortRecords(keys: readonly string[], order: ReplicaOrderArtifact, records: ReadonlyMap<string, MutableRecord>, variables: GraphqlVariables, path: readonly (string | number)[]): {
|
|
65
|
+
readonly records: readonly string[];
|
|
66
|
+
} | {
|
|
67
|
+
readonly reason: ReplicaIndexMaintenanceReason;
|
|
68
|
+
};
|
|
69
|
+
export declare function relationshipChangeMatches(planValue: RegisteredPlan, index: ReplicaIndexMaintenanceIndex, change: ReplicaIndexRelationshipChange): boolean;
|
|
70
|
+
export declare function isRelationshipChange(change: ReplicaIndexSemanticChange): change is ReplicaIndexRelationshipChange;
|
|
71
|
+
export declare function validateDependencies(value: readonly string[]): readonly string[];
|
|
72
|
+
export declare function intersects(left: readonly string[], right: ReadonlySet<string>): boolean;
|
|
73
|
+
export declare function recordKeyMatchesModel(key: string, model: string): boolean;
|
|
74
|
+
export declare function firstDuplicate(values: readonly string[]): string | undefined;
|
|
75
|
+
export declare function write(indexKey: string, records: readonly string[]): ReplicaIndexMaintenanceDecision;
|
|
76
|
+
export declare function stale(indexKey: string, reasonValue: ReplicaIndexMaintenanceReason): ReplicaIndexMaintenanceDecision;
|
|
77
|
+
export declare function unchanged(indexKey: string): ReplicaIndexMaintenanceDecision;
|
|
78
|
+
export declare function reason(code: ReplicaIndexMaintenanceReasonCode, path: readonly (string | number)[], message: string): ReplicaIndexMaintenanceReason;
|
|
79
|
+
export declare function sameStringList(left: readonly string[], right: readonly string[]): boolean;
|
|
80
|
+
export declare function sameValue(left: unknown, right: unknown): boolean;
|
|
81
|
+
export declare function cloneRecord(value: Readonly<Record<string, ReplicaValue>>): Readonly<Record<string, ReplicaValue>>;
|
|
82
|
+
export declare function cloneValue(value: ReplicaValue): ReplicaValue;
|
|
83
|
+
export declare function canonicalValue(value: unknown): string;
|
|
84
|
+
export declare function validateName(value: string, description: string): void;
|