@hops-ops/distributed 4.9.0 → 4.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.
@@ -0,0 +1,57 @@
1
+ import { type ReplicaOperationArtifact } from '../replica/index.js';
2
+ import type { GraphqlVariables } from '../types.js';
3
+ export type DistributedBoundaryVariableSource<TValue = unknown> = Readonly<{
4
+ kind: 'route_param';
5
+ name: string;
6
+ }> | Readonly<{
7
+ kind: 'search_param';
8
+ name: string;
9
+ mode?: 'first' | 'all';
10
+ }> | Readonly<{
11
+ kind: 'trusted_session';
12
+ path: readonly string[];
13
+ }> | Readonly<{
14
+ kind: 'constant';
15
+ value: TValue;
16
+ }> | Readonly<{
17
+ kind: 'forwarded_prop';
18
+ path: readonly string[];
19
+ }> | Readonly<{
20
+ kind: 'omit';
21
+ }>;
22
+ export type DistributedBoundaryVariableSources<TVariables extends GraphqlVariables> = Readonly<{
23
+ [K in keyof TVariables]?: DistributedBoundaryVariableSource<TVariables[K]>;
24
+ }>;
25
+ export type DistributedBoundaryVariableContext<TSession = unknown, TProps = Readonly<Record<string, unknown>>> = Readonly<{
26
+ params: Readonly<Record<string, string | undefined>>;
27
+ search: URLSearchParams | Readonly<Record<string, string | readonly string[] | undefined>>;
28
+ session: TSession | null;
29
+ props: TProps;
30
+ }>;
31
+ export type DistributedBoundaryBinding<TVariables extends GraphqlVariables, TSession = unknown, TProps = Readonly<Record<string, unknown>>> = Readonly<{
32
+ version: 1;
33
+ id: string;
34
+ artifactId: string;
35
+ sources: DistributedBoundaryVariableSources<TVariables>;
36
+ resolve(context: DistributedBoundaryVariableContext<TSession, TProps>): TVariables;
37
+ canonicalBytes(context: DistributedBoundaryVariableContext<TSession, TProps>): string;
38
+ }>;
39
+ export type DistributedBoundaryPlan = Readonly<{
40
+ operation: string;
41
+ route: string;
42
+ kind: 'layout' | 'page';
43
+ sourcePath?: string;
44
+ discovery: 'component' | 'route_document' | 'explicit';
45
+ }>;
46
+ export type DistributedBoundaryOperation<TData = unknown, TVariables extends GraphqlVariables = GraphqlVariables, TSession = unknown, TProps = Readonly<Record<string, unknown>>> = Readonly<{
47
+ plan: DistributedBoundaryPlan;
48
+ artifact: ReplicaOperationArtifact<TData, TVariables>;
49
+ binding: DistributedBoundaryBinding<TVariables, TSession, TProps>;
50
+ }>;
51
+ /**
52
+ * Define one closed, inspectable variable binding for every boundary lifecycle.
53
+ * The operation artifact remains the sole owner of coercion and cache identity.
54
+ */
55
+ export declare function defineDistributedBoundaryBinding<TData, TVariables extends GraphqlVariables, TSession = unknown, TProps = Readonly<Record<string, unknown>>>(artifact: ReplicaOperationArtifact<TData, TVariables>, sources: DistributedBoundaryVariableSources<TVariables>): DistributedBoundaryBinding<TVariables, TSession, TProps>;
56
+ export declare function defineDistributedBoundaryOperation<TData, TVariables extends GraphqlVariables, TSession = unknown, TProps = Readonly<Record<string, unknown>>>(plan: DistributedBoundaryPlan, artifact: ReplicaOperationArtifact<TData, TVariables>, binding: DistributedBoundaryBinding<TVariables, TSession, TProps>): DistributedBoundaryOperation<TData, TVariables, TSession, TProps>;
57
+ export declare function resolveDistributedBoundaryVariables<TData, TVariables extends GraphqlVariables, TSession, TProps>(artifact: ReplicaOperationArtifact<TData, TVariables>, sources: DistributedBoundaryVariableSources<TVariables>, context: DistributedBoundaryVariableContext<TSession, TProps>): TVariables;
@@ -0,0 +1,290 @@
1
+ import { canonicalizeOperationVariables } from '../replica/index.js';
2
+ const BINDING_VERSION = 1;
3
+ const GRAPHQL_NAME = /^[_A-Za-z][_0-9A-Za-z]*$/;
4
+ const MAX_BINDING_VARIABLES = 128;
5
+ const MAX_PATH_SEGMENTS = 16;
6
+ const MAX_LITERAL_DEPTH = 32;
7
+ const MAX_LITERAL_VALUES = 4_096;
8
+ const HOSTILE_KEYS = new Set(['__proto__', 'prototype', 'constructor']);
9
+ /**
10
+ * Define one closed, inspectable variable binding for every boundary lifecycle.
11
+ * The operation artifact remains the sole owner of coercion and cache identity.
12
+ */
13
+ export function defineDistributedBoundaryBinding(artifact, sources) {
14
+ const validated = validateSources(artifact, sources);
15
+ const id = `boundary-v${BINDING_VERSION}:${fnv1a64(`${artifact.id}\n${stableJson(validated)}`)}`;
16
+ const resolve = (context) => resolveDistributedBoundaryVariables(artifact, validated, context);
17
+ return Object.freeze({
18
+ version: BINDING_VERSION,
19
+ id,
20
+ artifactId: artifact.id,
21
+ sources: validated,
22
+ resolve,
23
+ canonicalBytes(context) {
24
+ return JSON.stringify(resolve(context));
25
+ }
26
+ });
27
+ }
28
+ export function defineDistributedBoundaryOperation(plan, artifact, binding) {
29
+ if (binding.artifactId !== artifact.id) {
30
+ throw new TypeError('Distributed boundary binding belongs to a different operation artifact');
31
+ }
32
+ if (plan === null ||
33
+ typeof plan !== 'object' ||
34
+ !GRAPHQL_NAME.test(plan.operation) ||
35
+ !plan.route.startsWith('/') ||
36
+ (plan.kind !== 'layout' && plan.kind !== 'page') ||
37
+ !['component', 'route_document', 'explicit'].includes(plan.discovery)) {
38
+ throw new TypeError('Distributed boundary operation plan is invalid');
39
+ }
40
+ return Object.freeze({
41
+ plan: Object.freeze({ ...plan }),
42
+ artifact,
43
+ binding
44
+ });
45
+ }
46
+ export function resolveDistributedBoundaryVariables(artifact, sources, context) {
47
+ if (context === null || typeof context !== 'object') {
48
+ throw new TypeError('Distributed boundary variable context is required');
49
+ }
50
+ const entries = [];
51
+ for (const [variable, source] of Object.entries(sources).sort(([left], [right]) => left.localeCompare(right))) {
52
+ const value = resolveSource(source, context);
53
+ if (value !== OMITTED)
54
+ entries.push([variable, value]);
55
+ }
56
+ return canonicalizeOperationVariables(artifact, Object.fromEntries(entries));
57
+ }
58
+ const OMITTED = Symbol('distributed.boundary.omitted');
59
+ function resolveSource(source, context) {
60
+ switch (source.kind) {
61
+ case 'omit':
62
+ return OMITTED;
63
+ case 'constant':
64
+ return source.value;
65
+ case 'route_param': {
66
+ const value = ownValue(context.params, source.name);
67
+ return value === undefined ? OMITTED : value;
68
+ }
69
+ case 'search_param': {
70
+ const search = context.search;
71
+ if (isSearchParams(search)) {
72
+ if (source.mode === 'all')
73
+ return search.getAll(source.name);
74
+ const value = search.get(source.name);
75
+ return value === null ? OMITTED : value;
76
+ }
77
+ const value = ownValue(search, source.name);
78
+ if (value === undefined)
79
+ return source.mode === 'all' ? [] : OMITTED;
80
+ if (source.mode === 'all')
81
+ return Array.isArray(value) ? [...value] : [value];
82
+ return Array.isArray(value) ? (value[0] ?? OMITTED) : value;
83
+ }
84
+ case 'trusted_session': {
85
+ const value = readPath(context.session, source.path, 'trusted session');
86
+ return value === undefined ? OMITTED : value;
87
+ }
88
+ case 'forwarded_prop': {
89
+ const value = readPath(context.props, source.path, 'forwarded prop');
90
+ return value === undefined ? OMITTED : value;
91
+ }
92
+ }
93
+ }
94
+ function validateSources(artifact, sources) {
95
+ if (sources === null || typeof sources !== 'object' || Array.isArray(sources)) {
96
+ throw new TypeError('Distributed boundary variable sources must be an object');
97
+ }
98
+ const definitions = artifact.variableCodec?.variables;
99
+ if (definitions === null || typeof definitions !== 'object' || Array.isArray(definitions)) {
100
+ throw new TypeError('Distributed boundary artifact has no variable codec');
101
+ }
102
+ const names = Object.keys(sources);
103
+ if (names.length > MAX_BINDING_VARIABLES) {
104
+ throw new TypeError(`Distributed boundary binding exceeds ${MAX_BINDING_VARIABLES} variables`);
105
+ }
106
+ const entries = [];
107
+ for (const name of names.sort()) {
108
+ if (!GRAPHQL_NAME.test(name) || !Object.hasOwn(definitions, name)) {
109
+ throw new TypeError(`Distributed boundary binding names unknown variable ${name}`);
110
+ }
111
+ const source = ownValue(sources, name);
112
+ entries.push([name, validateSource(source, name)]);
113
+ }
114
+ for (const [name, definition] of Object.entries(definitions)) {
115
+ const required = definition !== null &&
116
+ typeof definition === 'object' &&
117
+ 'nullable' in definition &&
118
+ definition.nullable === false;
119
+ if (required && !Object.hasOwn(sources, name)) {
120
+ throw new TypeError(`Distributed boundary binding is missing required variable ${name}; use an explicit binding, parent/boundary query, client-only execution, or a better read root`);
121
+ }
122
+ }
123
+ return Object.freeze(Object.fromEntries(entries));
124
+ }
125
+ function validateSource(value, variable) {
126
+ const source = exactRecord(value, `binding source ${variable}`);
127
+ if (typeof source.kind !== 'string') {
128
+ throw new TypeError(`Distributed boundary source ${variable} has no kind`);
129
+ }
130
+ switch (source.kind) {
131
+ case 'omit':
132
+ exactKeys(source, ['kind'], variable);
133
+ return Object.freeze({ kind: 'omit' });
134
+ case 'route_param':
135
+ exactKeys(source, ['kind', 'name'], variable);
136
+ return Object.freeze({ kind: 'route_param', name: safeName(source.name, variable) });
137
+ case 'search_param': {
138
+ exactKeys(source, ['kind', 'name', 'mode'], variable, ['mode']);
139
+ if (source.mode !== undefined && source.mode !== 'first' && source.mode !== 'all') {
140
+ throw new TypeError(`Distributed boundary source ${variable} has invalid search mode`);
141
+ }
142
+ return Object.freeze({
143
+ kind: 'search_param',
144
+ name: safeName(source.name, variable),
145
+ ...(source.mode === undefined ? {} : { mode: source.mode })
146
+ });
147
+ }
148
+ case 'trusted_session':
149
+ exactKeys(source, ['kind', 'path'], variable);
150
+ return Object.freeze({ kind: 'trusted_session', path: safePath(source.path, variable) });
151
+ case 'forwarded_prop':
152
+ exactKeys(source, ['kind', 'path'], variable);
153
+ return Object.freeze({ kind: 'forwarded_prop', path: safePath(source.path, variable) });
154
+ case 'constant':
155
+ exactKeys(source, ['kind', 'value'], variable);
156
+ return Object.freeze({
157
+ kind: 'constant',
158
+ value: freezeJson(stableValue(source.value))
159
+ });
160
+ default:
161
+ throw new TypeError(`Distributed boundary source ${variable} is unsupported; use an explicit binding, parent/boundary query, client-only execution, or a better read root`);
162
+ }
163
+ }
164
+ function safePath(value, variable) {
165
+ if (!Array.isArray(value) ||
166
+ value.length === 0 ||
167
+ value.length > MAX_PATH_SEGMENTS ||
168
+ value.some((part) => typeof part !== 'string' || !GRAPHQL_NAME.test(part) || HOSTILE_KEYS.has(part))) {
169
+ throw new TypeError(`Distributed boundary source ${variable} has an invalid path`);
170
+ }
171
+ return Object.freeze([...value]);
172
+ }
173
+ function safeName(value, variable) {
174
+ if (typeof value !== 'string' || value.length === 0 || value.length > 512) {
175
+ throw new TypeError(`Distributed boundary source ${variable} has an invalid name`);
176
+ }
177
+ return value;
178
+ }
179
+ function readPath(value, path, label) {
180
+ let current = value;
181
+ for (const segment of path) {
182
+ if (current === null || typeof current !== 'object')
183
+ return undefined;
184
+ const descriptor = Object.getOwnPropertyDescriptor(current, segment);
185
+ if (descriptor === undefined)
186
+ return undefined;
187
+ if (!('value' in descriptor)) {
188
+ throw new TypeError(`Distributed boundary ${label} path contains an accessor`);
189
+ }
190
+ current = descriptor.value;
191
+ }
192
+ return current;
193
+ }
194
+ function ownValue(value, key) {
195
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
196
+ if (descriptor === undefined)
197
+ return undefined;
198
+ if (!('value' in descriptor)) {
199
+ throw new TypeError('Distributed boundary input contains an accessor');
200
+ }
201
+ return descriptor.value;
202
+ }
203
+ function isSearchParams(value) {
204
+ return (value !== null &&
205
+ typeof value === 'object' &&
206
+ typeof value.get === 'function' &&
207
+ typeof value.getAll === 'function');
208
+ }
209
+ function exactRecord(value, label) {
210
+ if (value === null ||
211
+ typeof value !== 'object' ||
212
+ Array.isArray(value) ||
213
+ (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null)) {
214
+ throw new TypeError(`Distributed ${label} must be a plain object`);
215
+ }
216
+ return value;
217
+ }
218
+ function exactKeys(value, allowed, variable, optional = []) {
219
+ const permitted = new Set(allowed);
220
+ for (const key of Object.keys(value)) {
221
+ if (!permitted.has(key)) {
222
+ throw new TypeError(`Distributed boundary source ${variable} contains unknown field ${key}`);
223
+ }
224
+ }
225
+ for (const key of allowed) {
226
+ if (!optional.includes(key) && !Object.hasOwn(value, key)) {
227
+ throw new TypeError(`Distributed boundary source ${variable} is missing field ${key}`);
228
+ }
229
+ }
230
+ }
231
+ function stableJson(value) {
232
+ return JSON.stringify(stableValue(value));
233
+ }
234
+ function stableValue(value) {
235
+ let visited = 0;
236
+ const active = new Set();
237
+ const visit = (current, depth) => {
238
+ visited += 1;
239
+ if (visited > MAX_LITERAL_VALUES || depth > MAX_LITERAL_DEPTH) {
240
+ throw new TypeError('Distributed boundary constant exceeds structural limits');
241
+ }
242
+ if (current === null ||
243
+ typeof current === 'string' ||
244
+ typeof current === 'boolean')
245
+ return current;
246
+ if (typeof current === 'number' && Number.isFinite(current))
247
+ return current;
248
+ if (typeof current !== 'object') {
249
+ throw new TypeError('Distributed boundary constant is not JSON-compatible');
250
+ }
251
+ if (active.has(current))
252
+ throw new TypeError('Distributed boundary constant is cyclic');
253
+ active.add(current);
254
+ try {
255
+ if (Array.isArray(current))
256
+ return current.map((entry) => visit(entry, depth + 1));
257
+ const record = exactRecord(current, 'boundary constant');
258
+ return Object.fromEntries(Object.keys(record).sort().map((key) => {
259
+ if (HOSTILE_KEYS.has(key)) {
260
+ throw new TypeError('Distributed boundary constant contains a hostile object key');
261
+ }
262
+ return [key, visit(ownValue(record, key), depth + 1)];
263
+ }));
264
+ }
265
+ finally {
266
+ active.delete(current);
267
+ }
268
+ };
269
+ return visit(value, 0);
270
+ }
271
+ function fnv1a64(value) {
272
+ let hash = 0xcbf29ce484222325n;
273
+ for (const byte of new TextEncoder().encode(value)) {
274
+ hash ^= BigInt(byte);
275
+ hash = BigInt.asUintN(64, hash * 0x100000001b3n);
276
+ }
277
+ return hash.toString(16).padStart(16, '0');
278
+ }
279
+ function freezeJson(value) {
280
+ if (value === null || typeof value !== 'object')
281
+ return value;
282
+ if (Array.isArray(value)) {
283
+ for (const entry of value)
284
+ freezeJson(entry);
285
+ return Object.freeze(value);
286
+ }
287
+ for (const entry of Object.values(value))
288
+ freezeJson(entry);
289
+ return Object.freeze(value);
290
+ }
@@ -1,5 +1,6 @@
1
1
  import type { ReplicaOperationArtifact } from '../replica/index.js';
2
2
  import type { GraphqlVariables } from '../types.js';
3
+ import type { DistributedSvelteKitBoundaryInstance, SveltekitBoundaryRetention } from './boundary-lifecycle.js';
3
4
  import type { DistributedSvelteKitClient, SveltekitBoundOperation } from './replica.js';
4
5
  /**
5
6
  * Install one client in the current Svelte component tree.
@@ -19,6 +20,8 @@ export declare function provideDistributedSvelteKitClient<TCommands>(client: Dis
19
20
  export declare function useDistributedSvelteKitClient<TCommands = Readonly<Record<never, never>>>(): DistributedSvelteKitClient<TCommands>;
20
21
  /** Resolve the nearest generated command surface without a global proxy. */
21
22
  export declare function useDistributedSvelteKitCommands<TCommands>(): TCommands;
23
+ /** Retain the generated selections owned by the nearest page/layout instance. */
24
+ export declare function retainDistributedSvelteKitBoundary<TSession, TProps>(instance: DistributedSvelteKitBoundaryInstance, context: import('./boundary-variables.js').DistributedBoundaryVariableContext<TSession, TProps>): SveltekitBoundaryRetention;
22
25
  /**
23
26
  * Define one SSR-safe generated operation wrapper.
24
27
  *
@@ -1,4 +1,5 @@
1
1
  import { getContext, setContext } from 'svelte';
2
+ import { defineDistributedBoundaryBinding, defineDistributedBoundaryOperation } from './boundary-variables.js';
2
3
  const DISTRIBUTED_CLIENT_CONTEXT = Symbol('@hops-ops/distributed/sveltekit/client');
3
4
  /**
4
5
  * Install one client in the current Svelte component tree.
@@ -34,6 +35,10 @@ export function useDistributedSvelteKitClient() {
34
35
  export function useDistributedSvelteKitCommands() {
35
36
  return useDistributedSvelteKitClient().commands;
36
37
  }
38
+ /** Retain the generated selections owned by the nearest page/layout instance. */
39
+ export function retainDistributedSvelteKitBoundary(instance, context) {
40
+ return useDistributedSvelteKitClient().retainBoundary(instance, context);
41
+ }
37
42
  /**
38
43
  * Define one SSR-safe generated operation wrapper.
39
44
  *
@@ -58,6 +63,9 @@ export function defineDistributedSvelteKitOperation(artifact) {
58
63
  return useDistributedSvelteKitClient()
59
64
  .operation(artifact)
60
65
  .prefetch(variables);
66
+ },
67
+ boundary(plan, sources) {
68
+ return defineDistributedBoundaryOperation(plan, artifact, defineDistributedBoundaryBinding(artifact, sources));
61
69
  }
62
70
  });
63
71
  }
@@ -1,6 +1,8 @@
1
1
  export { authFromPageData, type PageGraphqlData } from './auth.js';
2
2
  export { distributedReloadLifecycle, registerDistributedReloadClient, validateDistributedReloadLocation, validateDistributedReloadState, type DistributedReloadLifecycle, type DistributedReloadOptions, type DistributedReloadStateDeclaration } from './lifecycle.js';
3
3
  export { parseDistributedGenerationEnvelope, type DistributedGenerationEnvelope } from '../generation.js';
4
- export { defineDistributedSvelteKitOperation, provideDistributedSvelteKitClient, useDistributedSvelteKitClient, useDistributedSvelteKitCommands } from './context.js';
5
- export { bindSveltekitOperation, createPageDataSessionSource, createDistributedSvelteKit, sessionSourceFromPageData, type CreateDistributedSvelteKitOptions, type DistributedSvelteKitClient, type SveltekitBoundOperation, type SveltekitCommandRuntimeFactory, type SveltekitCommandRuntimeFactoryOptions, type SveltekitCommandRuntimeLike, type SveltekitDistributedPageData, type SveltekitPageDataSessionSource, type SveltekitPageDataSource, type SveltekitQuerySnapshot, type SveltekitQueryStore, type SveltekitReplicaAuthority, type SveltekitReplicaHydration, type SveltekitSessionSource, type UseSveltekitOperationOptions } from './replica.js';
6
- export { createDistributedSvelteKitServer, matchDistributedRoute, registerDistributedRoute, type CreateDistributedSvelteKitServerOptions, type DistributedRouteOperation, type DistributedRoutePlan, type DistributedRouteVariables, type DistributedSvelteKitServer, type SveltekitServerLoadEventLike } from './server-replica.js';
4
+ export { defineDistributedBoundaryBinding, defineDistributedBoundaryOperation, resolveDistributedBoundaryVariables, type DistributedBoundaryBinding, type DistributedBoundaryOperation, type DistributedBoundaryPlan, type DistributedBoundaryVariableContext, type DistributedBoundaryVariableSource, type DistributedBoundaryVariableSources } from './boundary-variables.js';
5
+ export { DistributedSvelteKitBoundaryController, type DistributedSvelteKitBoundaryInstance, type DistributedSvelteKitBoundaryLocation, type DistributedSvelteKitLocationContext, type SveltekitBoundaryLifecycleDiagnostic, type SveltekitBoundaryRetention } from './boundary-lifecycle.js';
6
+ export { defineDistributedSvelteKitOperation, provideDistributedSvelteKitClient, retainDistributedSvelteKitBoundary, useDistributedSvelteKitClient, useDistributedSvelteKitCommands } from './context.js';
7
+ export { bindSveltekitOperation, createPageDataSessionSource, createDistributedSvelteKit, sessionSourceFromPageData, type CreateDistributedSvelteKitOptions, type DistributedSvelteKitClient, type SveltekitBoundOperation, type SveltekitBoundBoundaryOperation, type SveltekitCommandRuntimeFactory, type SveltekitCommandRuntimeFactoryOptions, type SveltekitCommandRuntimeLike, type SveltekitDistributedPageData, type SveltekitPageDataSessionSource, type SveltekitPageDataSource, type SveltekitQuerySnapshot, type SveltekitQueryStore, type SveltekitReplicaAuthority, type SveltekitReplicaHydration, type SveltekitSessionSource, type UseSveltekitOperationOptions } from './replica.js';
8
+ export { createDistributedSvelteKitServer, type CreateDistributedSvelteKitServerOptions, type DistributedSvelteKitServer, type SveltekitServerLoadEventLike } from './server-replica.js';
@@ -1,6 +1,8 @@
1
1
  export { authFromPageData } from './auth.js';
2
2
  export { distributedReloadLifecycle, registerDistributedReloadClient, validateDistributedReloadLocation, validateDistributedReloadState } from './lifecycle.js';
3
3
  export { parseDistributedGenerationEnvelope } from '../generation.js';
4
- export { defineDistributedSvelteKitOperation, provideDistributedSvelteKitClient, useDistributedSvelteKitClient, useDistributedSvelteKitCommands } from './context.js';
4
+ export { defineDistributedBoundaryBinding, defineDistributedBoundaryOperation, resolveDistributedBoundaryVariables } from './boundary-variables.js';
5
+ export { DistributedSvelteKitBoundaryController } from './boundary-lifecycle.js';
6
+ export { defineDistributedSvelteKitOperation, provideDistributedSvelteKitClient, retainDistributedSvelteKitBoundary, useDistributedSvelteKitClient, useDistributedSvelteKitCommands } from './context.js';
5
7
  export { bindSveltekitOperation, createPageDataSessionSource, createDistributedSvelteKit, sessionSourceFromPageData } from './replica.js';
6
- export { createDistributedSvelteKitServer, matchDistributedRoute, registerDistributedRoute } from './server-replica.js';
8
+ export { createDistributedSvelteKitServer } from './server-replica.js';
@@ -0,0 +1,104 @@
1
+ import type { DistributedBoundaryVariableSource } from '../boundary-variables.js';
2
+ export type DistributedIslandInventory = Readonly<{
3
+ version: number;
4
+ schemaFingerprint: string;
5
+ protocolFingerprint: string;
6
+ surface: unknown;
7
+ islands: readonly DistributedIslandPlanInput[];
8
+ }>;
9
+ export type DistributedIslandPlanInput = Readonly<{
10
+ version: number;
11
+ id: string;
12
+ operation: string;
13
+ operationHash: string;
14
+ modulePath: string;
15
+ exportName: string;
16
+ source: Readonly<{
17
+ path: string;
18
+ line: number;
19
+ column: number;
20
+ }>;
21
+ directives: Readonly<{
22
+ load: boolean;
23
+ live: boolean;
24
+ }>;
25
+ liveCoverage: Readonly<{
26
+ requested: boolean;
27
+ finite: boolean;
28
+ kind: string;
29
+ maxItems?: number;
30
+ }>;
31
+ variableSchema: Readonly<{
32
+ reference: string;
33
+ codecVersion: number;
34
+ variables: readonly Readonly<{
35
+ name: string;
36
+ graphqlType: string;
37
+ }>[];
38
+ }>;
39
+ }>;
40
+ export type DistributedSvelteKitBoundaryOccurrence = Readonly<{
41
+ islandId: string;
42
+ operation: string;
43
+ modulePath: string;
44
+ exportName: string;
45
+ component: string;
46
+ graphqlSource: string;
47
+ reason: 'route_document' | 'static_component_import' | 'explicit';
48
+ conservative: boolean;
49
+ directives: Readonly<{
50
+ load: boolean;
51
+ live: boolean;
52
+ }>;
53
+ liveCoverage: DistributedIslandPlanInput['liveCoverage'];
54
+ binding: Readonly<{
55
+ version: 1;
56
+ id: string;
57
+ discovery: 'route_param' | 'empty' | 'explicit';
58
+ sources: Readonly<Record<string, DistributedBoundaryVariableSource>>;
59
+ }>;
60
+ }>;
61
+ export type DistributedSvelteKitBoundary = Readonly<{
62
+ id: string;
63
+ route: string;
64
+ kind: 'layout' | 'page';
65
+ source: string;
66
+ islands: readonly DistributedSvelteKitBoundaryOccurrence[];
67
+ }>;
68
+ export type DistributedSvelteKitBoundaryPlan = Readonly<{
69
+ version: number;
70
+ module: string;
71
+ schemaFingerprint: string;
72
+ protocolFingerprint: string;
73
+ boundaries: readonly DistributedSvelteKitBoundary[];
74
+ unplaced: readonly Readonly<{
75
+ islandId: string;
76
+ operation: string;
77
+ graphqlSource: string;
78
+ }>[];
79
+ }>;
80
+ export type DistributedSvelteKitBoundaryAnalysisClient = Readonly<{
81
+ module: string;
82
+ inventory: DistributedIslandInventory;
83
+ explicitBoundaries?: readonly DistributedSvelteKitBoundaryRegistration[];
84
+ }>;
85
+ export type DistributedSvelteKitBoundaryRegistration = Readonly<{
86
+ operation: string;
87
+ route: string;
88
+ kind: 'layout' | 'page';
89
+ variables?: Readonly<Record<string, DistributedBoundaryVariableSource>>;
90
+ }>;
91
+ export type DistributedSvelteKitBoundaryAnalysisOptions = Readonly<{
92
+ cwd: string;
93
+ routesDir?: string;
94
+ libDir?: string;
95
+ aliases?: Readonly<Record<string, string>>;
96
+ clients: readonly DistributedSvelteKitBoundaryAnalysisClient[];
97
+ }>;
98
+ /** Validate a persisted adapter plan before check/dev treats it as coherent. */
99
+ export declare function validateDistributedSvelteKitBoundaryPlan(value: unknown, module?: string): DistributedSvelteKitBoundaryPlan;
100
+ /**
101
+ * Analyze Svelte component reachability without evaluating application code.
102
+ * The returned plan is deterministic and contains project-relative paths only.
103
+ */
104
+ export declare function analyzeDistributedSvelteKitBoundaries(options: DistributedSvelteKitBoundaryAnalysisOptions): Promise<readonly DistributedSvelteKitBoundaryPlan[]>;