@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.
Files changed (242) hide show
  1. package/README.md +454 -0
  2. package/dist/auth-headers.d.ts +8 -0
  3. package/dist/auth-headers.js +35 -0
  4. package/dist/diagnostics.d.ts +2 -0
  5. package/dist/diagnostics.js +1 -0
  6. package/dist/document.d.ts +8 -0
  7. package/dist/document.js +6 -0
  8. package/dist/identity.d.ts +23 -0
  9. package/dist/identity.js +73 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.js +6 -0
  12. package/dist/internal/cache-engine/create.d.ts +5 -0
  13. package/dist/internal/cache-engine/create.js +7 -0
  14. package/dist/internal/cache-engine/engine.d.ts +32 -0
  15. package/dist/internal/cache-engine/engine.js +1287 -0
  16. package/dist/internal/cache-engine/errors.d.ts +5 -0
  17. package/dist/internal/cache-engine/errors.js +10 -0
  18. package/dist/internal/cache-engine/helpers.d.ts +55 -0
  19. package/dist/internal/cache-engine/helpers.js +545 -0
  20. package/dist/internal/cache-engine/index.d.ts +3 -0
  21. package/dist/internal/cache-engine/index.js +2 -0
  22. package/dist/internal/cache-engine/types.d.ts +300 -0
  23. package/dist/internal/cache-engine/types.js +1 -0
  24. package/dist/internal/cache-engine.d.ts +3 -0
  25. package/dist/internal/cache-engine.js +2 -0
  26. package/dist/lib/assert-name.d.ts +2 -0
  27. package/dist/lib/assert-name.js +6 -0
  28. package/dist/lib/compare-code-units.d.ts +2 -0
  29. package/dist/lib/compare-code-units.js +4 -0
  30. package/dist/lib/deep-equal.d.ts +2 -0
  31. package/dist/lib/deep-equal.js +24 -0
  32. package/dist/lib/freeze-record.d.ts +2 -0
  33. package/dist/lib/freeze-record.js +13 -0
  34. package/dist/lib/index.d.ts +6 -0
  35. package/dist/lib/index.js +6 -0
  36. package/dist/lib/is-plain-record.d.ts +2 -0
  37. package/dist/lib/is-plain-record.js +8 -0
  38. package/dist/lib/report.d.ts +7 -0
  39. package/dist/lib/report.js +26 -0
  40. package/dist/protocol.d.ts +179 -0
  41. package/dist/protocol.js +558 -0
  42. package/dist/react/context.d.ts +20 -0
  43. package/dist/react/context.js +24 -0
  44. package/dist/react/index.d.ts +2 -0
  45. package/dist/react/index.js +3 -0
  46. package/dist/react/query.d.ts +20 -0
  47. package/dist/react/query.js +99 -0
  48. package/dist/replica/command-id.d.ts +2 -0
  49. package/dist/replica/command-id.js +19 -0
  50. package/dist/replica/command-runtime/constants.d.ts +5 -0
  51. package/dist/replica/command-runtime/constants.js +5 -0
  52. package/dist/replica/command-runtime/create.d.ts +2 -0
  53. package/dist/replica/command-runtime/create.js +644 -0
  54. package/dist/replica/command-runtime/errors.d.ts +16 -0
  55. package/dist/replica/command-runtime/errors.js +41 -0
  56. package/dist/replica/command-runtime/index.d.ts +5 -0
  57. package/dist/replica/command-runtime/index.js +4 -0
  58. package/dist/replica/command-runtime/lib/binding.d.ts +4 -0
  59. package/dist/replica/command-runtime/lib/binding.js +64 -0
  60. package/dist/replica/command-runtime/lib/effects.d.ts +11 -0
  61. package/dist/replica/command-runtime/lib/effects.js +89 -0
  62. package/dist/replica/command-runtime/lib/index.d.ts +9 -0
  63. package/dist/replica/command-runtime/lib/index.js +9 -0
  64. package/dist/replica/command-runtime/lib/inventory.d.ts +10 -0
  65. package/dist/replica/command-runtime/lib/inventory.js +141 -0
  66. package/dist/replica/command-runtime/lib/output.d.ts +13 -0
  67. package/dist/replica/command-runtime/lib/output.js +190 -0
  68. package/dist/replica/command-runtime/lib/projection.d.ts +20 -0
  69. package/dist/replica/command-runtime/lib/projection.js +255 -0
  70. package/dist/replica/command-runtime/lib/status.d.ts +7 -0
  71. package/dist/replica/command-runtime/lib/status.js +127 -0
  72. package/dist/replica/command-runtime/lib/transport.d.ts +16 -0
  73. package/dist/replica/command-runtime/lib/transport.js +112 -0
  74. package/dist/replica/command-runtime/lib/util.d.ts +16 -0
  75. package/dist/replica/command-runtime/lib/util.js +127 -0
  76. package/dist/replica/command-runtime/lifecycle.d.ts +11 -0
  77. package/dist/replica/command-runtime/lifecycle.js +13 -0
  78. package/dist/replica/command-runtime/symbols.d.ts +30 -0
  79. package/dist/replica/command-runtime/symbols.js +30 -0
  80. package/dist/replica/command-runtime/types.d.ts +222 -0
  81. package/dist/replica/command-runtime/types.js +1 -0
  82. package/dist/replica/command-runtime.d.ts +3 -0
  83. package/dist/replica/command-runtime.js +2 -0
  84. package/dist/replica/commands/clone.d.ts +12 -0
  85. package/dist/replica/commands/clone.js +187 -0
  86. package/dist/replica/commands/constants.d.ts +6 -0
  87. package/dist/replica/commands/constants.js +6 -0
  88. package/dist/replica/commands/errors.d.ts +7 -0
  89. package/dist/replica/commands/errors.js +22 -0
  90. package/dist/replica/commands/implementation.d.ts +8 -0
  91. package/dist/replica/commands/implementation.js +8 -0
  92. package/dist/replica/commands/index.d.ts +5 -0
  93. package/dist/replica/commands/index.js +4 -0
  94. package/dist/replica/commands/prepare.d.ts +27 -0
  95. package/dist/replica/commands/prepare.js +77 -0
  96. package/dist/replica/commands/presets.d.ts +12 -0
  97. package/dist/replica/commands/presets.js +84 -0
  98. package/dist/replica/commands/receipt.d.ts +3 -0
  99. package/dist/replica/commands/receipt.js +36 -0
  100. package/dist/replica/commands/resolve.d.ts +11 -0
  101. package/dist/replica/commands/resolve.js +165 -0
  102. package/dist/replica/commands/types.d.ts +278 -0
  103. package/dist/replica/commands/types.js +2 -0
  104. package/dist/replica/commands/util.d.ts +21 -0
  105. package/dist/replica/commands/util.js +96 -0
  106. package/dist/replica/commands/validate.d.ts +18 -0
  107. package/dist/replica/commands/validate.js +477 -0
  108. package/dist/replica/commands.d.ts +3 -0
  109. package/dist/replica/commands.js +2 -0
  110. package/dist/replica/diagnostics/event-log.d.ts +4 -0
  111. package/dist/replica/diagnostics/event-log.js +463 -0
  112. package/dist/replica/diagnostics/implementation.d.ts +4 -0
  113. package/dist/replica/diagnostics/implementation.js +4 -0
  114. package/dist/replica/diagnostics/index.d.ts +2 -0
  115. package/dist/replica/diagnostics/index.js +1 -0
  116. package/dist/replica/diagnostics/inspect.d.ts +6 -0
  117. package/dist/replica/diagnostics/inspect.js +170 -0
  118. package/dist/replica/diagnostics/types.d.ts +295 -0
  119. package/dist/replica/diagnostics/types.js +2 -0
  120. package/dist/replica/diagnostics.d.ts +3 -0
  121. package/dist/replica/diagnostics.js +2 -0
  122. package/dist/replica/distributed-replica/clocks.d.ts +23 -0
  123. package/dist/replica/distributed-replica/clocks.js +156 -0
  124. package/dist/replica/distributed-replica/constants.d.ts +12 -0
  125. package/dist/replica/distributed-replica/constants.js +10 -0
  126. package/dist/replica/distributed-replica/helpers.d.ts +48 -0
  127. package/dist/replica/distributed-replica/helpers.js +445 -0
  128. package/dist/replica/distributed-replica/hydration.d.ts +19 -0
  129. package/dist/replica/distributed-replica/hydration.js +380 -0
  130. package/dist/replica/distributed-replica/impl-diagnostics.d.ts +22 -0
  131. package/dist/replica/distributed-replica/impl-diagnostics.js +189 -0
  132. package/dist/replica/distributed-replica/impl-fetch-live.d.ts +39 -0
  133. package/dist/replica/distributed-replica/impl-fetch-live.js +395 -0
  134. package/dist/replica/distributed-replica/impl-hydration-orchestrate.d.ts +56 -0
  135. package/dist/replica/distributed-replica/impl-hydration-orchestrate.js +299 -0
  136. package/dist/replica/distributed-replica/impl-optimistic.d.ts +31 -0
  137. package/dist/replica/distributed-replica/impl-optimistic.js +172 -0
  138. package/dist/replica/distributed-replica/impl-protocol.d.ts +53 -0
  139. package/dist/replica/distributed-replica/impl-protocol.js +108 -0
  140. package/dist/replica/distributed-replica/impl.d.ts +44 -0
  141. package/dist/replica/distributed-replica/impl.js +1776 -0
  142. package/dist/replica/distributed-replica/index.d.ts +2 -0
  143. package/dist/replica/distributed-replica/index.js +4 -0
  144. package/dist/replica/distributed-replica/optimistic.d.ts +30 -0
  145. package/dist/replica/distributed-replica/optimistic.js +221 -0
  146. package/dist/replica/distributed-replica/types.d.ts +147 -0
  147. package/dist/replica/distributed-replica/types.js +1 -0
  148. package/dist/replica/distributed-replica/watch.d.ts +19 -0
  149. package/dist/replica/distributed-replica/watch.js +95 -0
  150. package/dist/replica/distributed-replica.d.ts +2 -0
  151. package/dist/replica/distributed-replica.js +2 -0
  152. package/dist/replica/graphql-transport.d.ts +24 -0
  153. package/dist/replica/graphql-transport.js +122 -0
  154. package/dist/replica/identity/clone.d.ts +6 -0
  155. package/dist/replica/identity/clone.js +54 -0
  156. package/dist/replica/identity/codec.d.ts +48 -0
  157. package/dist/replica/identity/codec.js +789 -0
  158. package/dist/replica/identity/constants.d.ts +3 -0
  159. package/dist/replica/identity/constants.js +18 -0
  160. package/dist/replica/identity/implementation.d.ts +5 -0
  161. package/dist/replica/identity/implementation.js +5 -0
  162. package/dist/replica/identity/index.d.ts +3 -0
  163. package/dist/replica/identity/index.js +3 -0
  164. package/dist/replica/identity/keys.d.ts +29 -0
  165. package/dist/replica/identity/keys.js +173 -0
  166. package/dist/replica/identity.d.ts +2 -0
  167. package/dist/replica/identity.js +2 -0
  168. package/dist/replica/index-maintenance/engine.d.ts +84 -0
  169. package/dist/replica/index-maintenance/engine.js +677 -0
  170. package/dist/replica/index-maintenance/implementation.d.ts +4 -0
  171. package/dist/replica/index-maintenance/implementation.js +4 -0
  172. package/dist/replica/index-maintenance/index.d.ts +2 -0
  173. package/dist/replica/index-maintenance/index.js +1 -0
  174. package/dist/replica/index-maintenance/registry.d.ts +2 -0
  175. package/dist/replica/index-maintenance/registry.js +49 -0
  176. package/dist/replica/index-maintenance/types.d.ts +58 -0
  177. package/dist/replica/index-maintenance/types.js +1 -0
  178. package/dist/replica/index-maintenance.d.ts +3 -0
  179. package/dist/replica/index-maintenance.js +2 -0
  180. package/dist/replica/index.d.ts +17 -0
  181. package/dist/replica/index.js +9 -0
  182. package/dist/replica/materialize.d.ts +10 -0
  183. package/dist/replica/materialize.js +163 -0
  184. package/dist/replica/normalize.d.ts +27 -0
  185. package/dist/replica/normalize.js +298 -0
  186. package/dist/replica/operation-binding.d.ts +14 -0
  187. package/dist/replica/operation-binding.js +76 -0
  188. package/dist/replica/persistence/idb.d.ts +20 -0
  189. package/dist/replica/persistence/idb.js +193 -0
  190. package/dist/replica/persistence/implementation.d.ts +4 -0
  191. package/dist/replica/persistence/implementation.js +4 -0
  192. package/dist/replica/persistence/index.d.ts +2 -0
  193. package/dist/replica/persistence/index.js +1 -0
  194. package/dist/replica/persistence/state.d.ts +104 -0
  195. package/dist/replica/persistence/state.js +734 -0
  196. package/dist/replica/persistence/types.d.ts +54 -0
  197. package/dist/replica/persistence/types.js +1 -0
  198. package/dist/replica/persistence.d.ts +3 -0
  199. package/dist/replica/persistence.js +2 -0
  200. package/dist/replica/query-plan/constants.d.ts +13 -0
  201. package/dist/replica/query-plan/constants.js +7 -0
  202. package/dist/replica/query-plan/filter.d.ts +39 -0
  203. package/dist/replica/query-plan/filter.js +544 -0
  204. package/dist/replica/query-plan/index.d.ts +4 -0
  205. package/dist/replica/query-plan/index.js +3 -0
  206. package/dist/replica/query-plan/order.d.ts +11 -0
  207. package/dist/replica/query-plan/order.js +158 -0
  208. package/dist/replica/query-plan/pagination.d.ts +6 -0
  209. package/dist/replica/query-plan/pagination.js +90 -0
  210. package/dist/replica/query-plan/resolve.d.ts +14 -0
  211. package/dist/replica/query-plan/resolve.js +163 -0
  212. package/dist/replica/query-plan/types.d.ts +89 -0
  213. package/dist/replica/query-plan/types.js +1 -0
  214. package/dist/replica/query-plan/util.d.ts +13 -0
  215. package/dist/replica/query-plan/util.js +62 -0
  216. package/dist/replica/query-plan.d.ts +3 -0
  217. package/dist/replica/query-plan.js +2 -0
  218. package/dist/replica/revalidation.d.ts +9 -0
  219. package/dist/replica/revalidation.js +86 -0
  220. package/dist/replica/selection.d.ts +20 -0
  221. package/dist/replica/selection.js +109 -0
  222. package/dist/replica/types.d.ts +657 -0
  223. package/dist/replica/types.js +1 -0
  224. package/dist/request.d.ts +17 -0
  225. package/dist/request.js +123 -0
  226. package/dist/sveltekit/auth.d.ts +18 -0
  227. package/dist/sveltekit/auth.js +9 -0
  228. package/dist/sveltekit/context.d.ts +28 -0
  229. package/dist/sveltekit/context.js +58 -0
  230. package/dist/sveltekit/index.d.ts +4 -0
  231. package/dist/sveltekit/index.js +4 -0
  232. package/dist/sveltekit/replica.d.ts +145 -0
  233. package/dist/sveltekit/replica.js +491 -0
  234. package/dist/sveltekit/server-replica.d.ts +52 -0
  235. package/dist/sveltekit/server-replica.js +176 -0
  236. package/dist/sveltekit/vite.d.ts +103 -0
  237. package/dist/sveltekit/vite.js +878 -0
  238. package/dist/types.d.ts +33 -0
  239. package/dist/types.js +1 -0
  240. package/dist/websocket.d.ts +41 -0
  241. package/dist/websocket.js +187 -0
  242. package/package.json +95 -0
@@ -0,0 +1,21 @@
1
+ import type { ReplicaCommandContractErrorCode, ReplicaCommandScalarCodec } from './types.js';
2
+ export declare function createUlid(): string;
3
+ export declare function validateUuidV7(value: unknown, path: string, code: ReplicaCommandContractErrorCode): string;
4
+ export declare function validateUlid(value: unknown, path: string): string;
5
+ export declare function sameProjectionMultiset(expected: readonly {
6
+ projection: string;
7
+ model: string;
8
+ }[], actual: readonly {
9
+ projection: string;
10
+ model: string;
11
+ }[]): boolean;
12
+ export declare function samePath(left: readonly string[], right: readonly string[]): boolean;
13
+ export declare function isSupportedCodec(value: string): value is ReplicaCommandScalarCodec;
14
+ export declare function defineEnumerable<T>(target: Record<string, T>, key: string, value: T): void;
15
+ export declare function nonempty(value: unknown, path: string): asserts value is string;
16
+ export declare function requiredString(value: unknown, path: string): string;
17
+ export declare function hash(value: unknown, path: string): void;
18
+ export declare function artifactInvalid(path: string): never;
19
+ export declare function inputInvalid(path: string): never;
20
+ export declare function receiptMismatch(path: string): never;
21
+ export declare function trustedPresetMismatch(path: string): never;
@@ -0,0 +1,96 @@
1
+ import { SHA256, ULID, ULID_ALPHABET, UUID_V7 } from './constants.js';
2
+ import { ReplicaCommandContractError } from './errors.js';
3
+ import { isDistributedTrustedPresetCodec } from '../../protocol.js';
4
+ export function createUlid() {
5
+ const crypto = globalThis.crypto;
6
+ if (!crypto || typeof crypto.getRandomValues !== 'function') {
7
+ throw new ReplicaCommandContractError('REPLICA_COMMAND_INPUT_INVALID', 'inputDefaults.ulid');
8
+ }
9
+ let timestamp = Date.now();
10
+ let time = '';
11
+ for (let index = 0; index < 10; index += 1) {
12
+ time = ULID_ALPHABET[timestamp % 32] + time;
13
+ timestamp = Math.floor(timestamp / 32);
14
+ }
15
+ const bytes = crypto.getRandomValues(new Uint8Array(10));
16
+ let random = 0n;
17
+ for (const byte of bytes)
18
+ random = (random << 8n) | BigInt(byte);
19
+ let suffix = '';
20
+ for (let index = 0; index < 16; index += 1) {
21
+ suffix = ULID_ALPHABET[Number(random & 31n)] + suffix;
22
+ random >>= 5n;
23
+ }
24
+ return `${time}${suffix}`;
25
+ }
26
+ export function validateUuidV7(value, path, code) {
27
+ if (typeof value !== 'string' || !UUID_V7.test(value)) {
28
+ throw new ReplicaCommandContractError(code, path);
29
+ }
30
+ return value.toLowerCase();
31
+ }
32
+ export function validateUlid(value, path) {
33
+ if (typeof value !== 'string' || !ULID.test(value.toUpperCase())) {
34
+ inputInvalid(path);
35
+ }
36
+ return value.toUpperCase();
37
+ }
38
+ export function sameProjectionMultiset(expected, actual) {
39
+ if (expected.length !== actual.length)
40
+ return false;
41
+ const counts = new Map();
42
+ for (const item of expected) {
43
+ const key = JSON.stringify([item.projection, item.model]);
44
+ counts.set(key, (counts.get(key) ?? 0) + 1);
45
+ }
46
+ for (const item of actual) {
47
+ const key = JSON.stringify([item.projection, item.model]);
48
+ const count = counts.get(key);
49
+ if (count === undefined)
50
+ return false;
51
+ if (count === 1)
52
+ counts.delete(key);
53
+ else
54
+ counts.set(key, count - 1);
55
+ }
56
+ return counts.size === 0;
57
+ }
58
+ export function samePath(left, right) {
59
+ return (left.length === right.length &&
60
+ left.every((segment, index) => segment === right[index]));
61
+ }
62
+ export function isSupportedCodec(value) {
63
+ return isDistributedTrustedPresetCodec(value);
64
+ }
65
+ export function defineEnumerable(target, key, value) {
66
+ Object.defineProperty(target, key, {
67
+ value,
68
+ enumerable: true,
69
+ configurable: true,
70
+ writable: true
71
+ });
72
+ }
73
+ export function nonempty(value, path) {
74
+ if (typeof value !== 'string' || value.trim() === '')
75
+ artifactInvalid(path);
76
+ }
77
+ export function requiredString(value, path) {
78
+ nonempty(value, path);
79
+ return value;
80
+ }
81
+ export function hash(value, path) {
82
+ if (typeof value !== 'string' || !SHA256.test(value))
83
+ artifactInvalid(path);
84
+ }
85
+ export function artifactInvalid(path) {
86
+ throw new ReplicaCommandContractError('REPLICA_COMMAND_ARTIFACT_INVALID', path);
87
+ }
88
+ export function inputInvalid(path) {
89
+ throw new ReplicaCommandContractError('REPLICA_COMMAND_INPUT_INVALID', path);
90
+ }
91
+ export function receiptMismatch(path) {
92
+ throw new ReplicaCommandContractError('REPLICA_COMMAND_RECEIPT_MISMATCH', path);
93
+ }
94
+ export function trustedPresetMismatch(path) {
95
+ throw new ReplicaCommandContractError('REPLICA_COMMAND_TRUSTED_PRESET_MISMATCH', path);
96
+ }
@@ -0,0 +1,18 @@
1
+ import type { ReplicaClientSurface } from '../types.js';
2
+ import type { ReplicaCommandArtifact, ReplicaCommandEffect, ReplicaCommandEffectExpression, ReplicaCommandEffectField, ReplicaCommandEffectKey, ReplicaCommandEffectRelationship, ReplicaCommandInputDefaults, ReplicaCommandShape, ReplicaCommandTypeDefinition, ReplicaTrustedPresetDescriptor, TrustedPresetReference } from './types.js';
3
+ export declare function validateArtifact<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>, allowTrustedPresets: boolean): readonly ReplicaTrustedPresetDescriptor[];
4
+ export declare function validateClientSurface(surface: ReplicaClientSurface, path: string): void;
5
+ export declare function validateTrustedPresetReferences<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>, descriptors: readonly ReplicaTrustedPresetDescriptor[], allowTrustedPresets: boolean): void;
6
+ export declare function collectTrustedPresetReferences<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>): readonly TrustedPresetReference[];
7
+ export declare function validateShape(shape: ReplicaCommandShape, path: string, depth: number, active: Set<ReplicaCommandTypeDefinition>): void;
8
+ export declare function validateDefinition(definition: ReplicaCommandTypeDefinition, path: string, depth: number, active: Set<ReplicaCommandTypeDefinition>): void;
9
+ export declare function validateDefaults(shape: ReplicaCommandShape, defaults: ReplicaCommandInputDefaults | undefined): void;
10
+ export declare function validateConfirmations<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>): void;
11
+ export declare function validateDirectProjection<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>): void;
12
+ export declare function validateRevalidation<TInput, TOutput>(artifact: ReplicaCommandArtifact<TInput, TOutput>): void;
13
+ export declare function validateEffectArtifact(effect: ReplicaCommandEffect, input: ReplicaCommandShape, path: string): void;
14
+ export declare function validateKeyArtifact(key: ReplicaCommandEffectKey, input: ReplicaCommandShape, path: string): void;
15
+ export declare function validateFieldsArtifact(fields: readonly ReplicaCommandEffectField[], input: ReplicaCommandShape, path: string): void;
16
+ export declare function validateExpressionArtifact(expression: ReplicaCommandEffectExpression, input: ReplicaCommandShape, path: string): void;
17
+ export declare function validateRelationshipArtifact(relationship: ReplicaCommandEffectRelationship, path: string): void;
18
+ export declare function validateArtifactJson(value: unknown, path: string, active: Set<object>, depth: number): void;
@@ -0,0 +1,477 @@
1
+ import { isPlainRecord } from '../../lib/is-plain-record.js';
2
+ import { GRAPHQL_NAME, MAX_TYPE_DEPTH } from './constants.js';
3
+ import { artifactInvalid, hash, isSupportedCodec, nonempty, requiredString } from './util.js';
4
+ import { parseReplicaTrustedPresetDescriptors, trustedPresetName } from './presets.js';
5
+ import { fieldAtPath } from './resolve.js';
6
+ export function validateArtifact(artifact, allowTrustedPresets) {
7
+ if (artifact.version !== 1)
8
+ artifactInvalid('artifact.version');
9
+ nonempty(artifact.name, 'artifact.name');
10
+ if (!GRAPHQL_NAME.test(artifact.mutationField)) {
11
+ artifactInvalid('artifact.mutationField');
12
+ }
13
+ nonempty(artifact.document, 'artifact.document');
14
+ hash(artifact.operationHash, 'artifact.operationHash');
15
+ if (artifact.protocol.version !== 1)
16
+ artifactInvalid('artifact.protocol.version');
17
+ hash(artifact.protocol.schemaHash, 'artifact.protocol.schemaHash');
18
+ hash(artifact.protocol.protocolHash, 'artifact.protocol.protocolHash');
19
+ validateClientSurface(artifact.protocol.surface, 'artifact.protocol.surface');
20
+ if (artifact.protocol.operation !== artifact.operationHash) {
21
+ artifactInvalid('artifact.protocol.operation');
22
+ }
23
+ const surfaceTrustedPresets = parseReplicaTrustedPresetDescriptors(artifact.protocol.trustedPresets, 'artifact.protocol.trustedPresets');
24
+ const trustedPresets = parseReplicaTrustedPresetDescriptors(artifact.trustedPresets ?? [], 'artifact.trustedPresets');
25
+ const surfaceByName = new Map(surfaceTrustedPresets.map((descriptor) => [
26
+ descriptor.name,
27
+ descriptor.codec
28
+ ]));
29
+ for (let index = 0; index < trustedPresets.length; index += 1) {
30
+ const descriptor = trustedPresets[index];
31
+ if (surfaceByName.get(descriptor.name) !== descriptor.codec) {
32
+ artifactInvalid(`artifact.trustedPresets[${index}]`);
33
+ }
34
+ }
35
+ validateShape(artifact.input, 'artifact.input', 0, new Set());
36
+ validateShape(artifact.output, 'artifact.output', 0, new Set());
37
+ if (artifact.output.kind === 'none')
38
+ artifactInvalid('artifact.output.kind');
39
+ validateDefaults(artifact.input, artifact.inputDefaults);
40
+ if (artifact.consistency !== 'accepted' &&
41
+ artifact.consistency !== 'fact' &&
42
+ artifact.consistency !== 'projected') {
43
+ artifactInvalid('artifact.consistency');
44
+ }
45
+ if (artifact.effects.version !== 1)
46
+ artifactInvalid('artifact.effects.version');
47
+ if (artifact.effects.fallback !== 'revalidate') {
48
+ artifactInvalid('artifact.effects.fallback');
49
+ }
50
+ if (!Array.isArray(artifact.effects.operations)) {
51
+ artifactInvalid('artifact.effects.operations');
52
+ }
53
+ for (let index = 0; index < artifact.effects.operations.length; index += 1) {
54
+ validateEffectArtifact(artifact.effects.operations[index], artifact.input, `artifact.effects.operations[${index}]`);
55
+ }
56
+ validateConfirmations(artifact);
57
+ validateDirectProjection(artifact);
58
+ validateRevalidation(artifact);
59
+ validateTrustedPresetReferences(artifact, trustedPresets, allowTrustedPresets);
60
+ return trustedPresets;
61
+ }
62
+ export function validateClientSurface(surface, path) {
63
+ if (surface === null || typeof surface !== 'object')
64
+ artifactInvalid(path);
65
+ requiredString(surface.name, `${path}.name`);
66
+ if (surface.kind === 'role')
67
+ return;
68
+ if (surface.kind !== 'application' ||
69
+ !Array.isArray(surface.roles) ||
70
+ surface.roles.length === 0) {
71
+ artifactInvalid(path);
72
+ }
73
+ const roles = new Set();
74
+ for (let index = 0; index < surface.roles.length; index += 1) {
75
+ const role = requiredString(surface.roles[index], `${path}.roles[${index}]`);
76
+ if (roles.has(role))
77
+ artifactInvalid(`${path}.roles[${index}]`);
78
+ roles.add(role);
79
+ }
80
+ }
81
+ export function validateTrustedPresetReferences(artifact, descriptors, allowTrustedPresets) {
82
+ const references = collectTrustedPresetReferences(artifact);
83
+ const declared = new Set(descriptors.map(({ name }) => name));
84
+ for (const reference of references) {
85
+ if (!declared.has(reference.name))
86
+ artifactInvalid(reference.path);
87
+ }
88
+ const referenced = new Set(references.map(({ name }) => name));
89
+ for (let index = 0; index < descriptors.length; index += 1) {
90
+ if (!referenced.has(descriptors[index].name)) {
91
+ artifactInvalid(`artifact.trustedPresets[${index}]`);
92
+ }
93
+ }
94
+ if (!allowTrustedPresets && references.length !== 0) {
95
+ artifactInvalid(references[0].path);
96
+ }
97
+ }
98
+ export function collectTrustedPresetReferences(artifact) {
99
+ const out = [];
100
+ const expression = (value, path) => {
101
+ if (value.kind === 'trusted_preset') {
102
+ out.push(Object.freeze({ name: value.name, path }));
103
+ }
104
+ };
105
+ const fields = (value, path) => {
106
+ for (let index = 0; index < value.length; index += 1) {
107
+ expression(value[index].value, `${path}[${index}].value`);
108
+ }
109
+ };
110
+ const key = (value, path) => {
111
+ fields(value.fields, `${path}.fields`);
112
+ };
113
+ for (let index = 0; index < artifact.effects.operations.length; index += 1) {
114
+ const effect = artifact.effects.operations[index];
115
+ const path = `artifact.effects.operations[${index}]`;
116
+ switch (effect.kind) {
117
+ case 'upsert':
118
+ case 'patch':
119
+ key(effect.key, `${path}.key`);
120
+ fields(effect.fields, `${path}.fields`);
121
+ break;
122
+ case 'delete':
123
+ key(effect.key, `${path}.key`);
124
+ break;
125
+ case 'link':
126
+ case 'unlink':
127
+ key(effect.source, `${path}.source`);
128
+ key(effect.target, `${path}.target`);
129
+ break;
130
+ case 'invalidate_relationship':
131
+ key(effect.source, `${path}.source`);
132
+ break;
133
+ case 'invalidate_model':
134
+ break;
135
+ }
136
+ }
137
+ if (artifact.confirmations?.kind === 'finite') {
138
+ for (let index = 0; index < artifact.confirmations.expected.length; index += 1) {
139
+ const confirmation = artifact.confirmations.expected[index];
140
+ const path = `artifact.confirmations.expected[${index}]`;
141
+ key(confirmation.key, `${path}.key`);
142
+ if (confirmation.partition !== undefined) {
143
+ expression(confirmation.partition, `${path}.partition`);
144
+ }
145
+ }
146
+ }
147
+ if (artifact.directProjection?.partition !== undefined) {
148
+ expression(artifact.directProjection.partition, 'artifact.directProjection.partition');
149
+ }
150
+ return Object.freeze(out);
151
+ }
152
+ export function validateShape(shape, path, depth, active) {
153
+ if (depth > MAX_TYPE_DEPTH)
154
+ artifactInvalid(path);
155
+ switch (shape.kind) {
156
+ case 'none':
157
+ return;
158
+ case 'object':
159
+ validateDefinition(shape.definition, `${path}.definition`, depth, active);
160
+ return;
161
+ default:
162
+ artifactInvalid(`${path}.kind`);
163
+ }
164
+ }
165
+ export function validateDefinition(definition, path, depth, active) {
166
+ if (depth > MAX_TYPE_DEPTH || active.has(definition))
167
+ artifactInvalid(path);
168
+ if (!GRAPHQL_NAME.test(definition.name) || !Array.isArray(definition.fields)) {
169
+ artifactInvalid(path);
170
+ }
171
+ active.add(definition);
172
+ const names = new Set();
173
+ for (let index = 0; index < definition.fields.length; index += 1) {
174
+ const field = definition.fields[index];
175
+ const fieldPath = `${path}.fields[${index}]`;
176
+ if (!GRAPHQL_NAME.test(field.name) || !GRAPHQL_NAME.test(field.typeName)) {
177
+ artifactInvalid(fieldPath);
178
+ }
179
+ if (names.has(field.name))
180
+ artifactInvalid(`${fieldPath}.name`);
181
+ names.add(field.name);
182
+ if (typeof field.nullable !== 'boolean' ||
183
+ typeof field.list !== 'boolean' ||
184
+ typeof field.itemNullable !== 'boolean' ||
185
+ (field.itemNullable && !field.list) ||
186
+ (field.codec === undefined) === (field.nested === undefined)) {
187
+ artifactInvalid(fieldPath);
188
+ }
189
+ if (field.codec !== undefined && !isSupportedCodec(field.codec)) {
190
+ artifactInvalid(`${fieldPath}.codec`);
191
+ }
192
+ if (field.nested !== undefined) {
193
+ if (field.nested.name !== field.typeName) {
194
+ artifactInvalid(`${fieldPath}.nested.name`);
195
+ }
196
+ validateDefinition(field.nested, `${fieldPath}.nested`, depth + 1, active);
197
+ }
198
+ }
199
+ active.delete(definition);
200
+ }
201
+ export function validateDefaults(shape, defaults) {
202
+ if (defaults === undefined)
203
+ return;
204
+ if (defaults.version !== 1 || !Array.isArray(defaults.defaults)) {
205
+ artifactInvalid('artifact.inputDefaults');
206
+ }
207
+ if (shape.kind !== 'object' && defaults.defaults.length > 0) {
208
+ artifactInvalid('artifact.inputDefaults.defaults');
209
+ }
210
+ const paths = new Set();
211
+ for (let index = 0; index < defaults.defaults.length; index += 1) {
212
+ const entry = defaults.defaults[index];
213
+ const path = `artifact.inputDefaults.defaults[${index}]`;
214
+ if (!Array.isArray(entry.path) ||
215
+ entry.path.length === 0 ||
216
+ entry.path.some((segment) => typeof segment !== 'string' || !GRAPHQL_NAME.test(segment)) ||
217
+ (entry.generator !== 'uuid_v7' && entry.generator !== 'ulid')) {
218
+ artifactInvalid(path);
219
+ }
220
+ const key = entry.path.join('\u0000');
221
+ if (paths.has(key))
222
+ artifactInvalid(`${path}.path`);
223
+ paths.add(key);
224
+ if (shape.kind === 'object') {
225
+ const field = fieldAtPath(shape.definition, entry.path, path);
226
+ if (field.nullable ||
227
+ field.list ||
228
+ field.nested !== undefined ||
229
+ field.codec !== 'string' ||
230
+ (field.typeName !== 'ID' && field.typeName !== 'String')) {
231
+ artifactInvalid(path);
232
+ }
233
+ }
234
+ }
235
+ }
236
+ export function validateConfirmations(artifact) {
237
+ const confirmations = artifact.confirmations;
238
+ if (confirmations === undefined) {
239
+ if (artifact.consistency === 'fact') {
240
+ artifactInvalid('artifact.confirmations');
241
+ }
242
+ return;
243
+ }
244
+ if (confirmations.version !== 1 ||
245
+ confirmations.fallback !== 'revalidate' ||
246
+ !Array.isArray(confirmations.expected)) {
247
+ artifactInvalid('artifact.confirmations');
248
+ }
249
+ if (confirmations.kind === 'unavailable') {
250
+ if (confirmations.expected.length !== 0) {
251
+ artifactInvalid('artifact.confirmations.expected');
252
+ }
253
+ }
254
+ else if (confirmations.kind === 'finite') {
255
+ if (confirmations.expected.length === 0) {
256
+ artifactInvalid('artifact.confirmations.expected');
257
+ }
258
+ }
259
+ else {
260
+ artifactInvalid('artifact.confirmations.kind');
261
+ }
262
+ if (artifact.consistency === 'projected') {
263
+ artifactInvalid('artifact.confirmations');
264
+ }
265
+ if (confirmations.kind === 'finite') {
266
+ for (let index = 0; index < confirmations.expected.length; index += 1) {
267
+ const confirmation = confirmations.expected[index];
268
+ const path = `artifact.confirmations.expected[${index}]`;
269
+ requiredString(confirmation.projector, `${path}.projector`);
270
+ requiredString(confirmation.model, `${path}.model`);
271
+ validateKeyArtifact(confirmation.key, artifact.input, `${path}.key`);
272
+ if (confirmation.partition !== undefined) {
273
+ validateExpressionArtifact(confirmation.partition, artifact.input, `${path}.partition`);
274
+ }
275
+ }
276
+ }
277
+ }
278
+ export function validateDirectProjection(artifact) {
279
+ const direct = artifact.directProjection;
280
+ if (artifact.consistency === 'projected' && direct === undefined) {
281
+ artifactInvalid('artifact.directProjection');
282
+ }
283
+ if (artifact.consistency !== 'projected' && direct !== undefined) {
284
+ artifactInvalid('artifact.directProjection');
285
+ }
286
+ if (direct === undefined)
287
+ return;
288
+ if (direct.topology.version !== 1) {
289
+ artifactInvalid('artifact.directProjection.topology.version');
290
+ }
291
+ nonempty(direct.topology.name, 'artifact.directProjection.topology.name');
292
+ hash(direct.topology.digest, 'artifact.directProjection.topology.digest');
293
+ nonempty(direct.model, 'artifact.directProjection.model');
294
+ nonempty(direct.changeEpoch, 'artifact.directProjection.changeEpoch');
295
+ if (!Array.isArray(direct.identityFields) ||
296
+ direct.identityFields.length === 0 ||
297
+ artifact.output.kind !== 'object') {
298
+ artifactInvalid('artifact.directProjection.identityFields');
299
+ }
300
+ const identityFields = new Set();
301
+ for (let index = 0; index < direct.identityFields.length; index += 1) {
302
+ const fieldName = direct.identityFields[index];
303
+ const path = `artifact.directProjection.identityFields[${index}]`;
304
+ if (typeof fieldName !== 'string' ||
305
+ !GRAPHQL_NAME.test(fieldName) ||
306
+ identityFields.has(fieldName)) {
307
+ artifactInvalid(path);
308
+ }
309
+ identityFields.add(fieldName);
310
+ const outputField = artifact.output.definition.fields.find((field) => field.name === fieldName);
311
+ if (outputField === undefined ||
312
+ outputField.nullable ||
313
+ outputField.list ||
314
+ outputField.codec === undefined ||
315
+ outputField.nested !== undefined) {
316
+ artifactInvalid(path);
317
+ }
318
+ }
319
+ if (direct.partition !== undefined) {
320
+ validateExpressionArtifact(direct.partition, artifact.input, 'artifact.directProjection.partition');
321
+ }
322
+ }
323
+ export function validateRevalidation(artifact) {
324
+ const plan = artifact.revalidation;
325
+ if (plan.version !== 1 ||
326
+ typeof plan.required !== 'boolean' ||
327
+ !Array.isArray(plan.dependencies) ||
328
+ !Array.isArray(plan.models) ||
329
+ !Array.isArray(plan.relationships)) {
330
+ artifactInvalid('artifact.revalidation');
331
+ }
332
+ for (const [index, dependency] of plan.dependencies.entries()) {
333
+ nonempty(dependency, `artifact.revalidation.dependencies[${index}]`);
334
+ }
335
+ for (const [index, model] of plan.models.entries()) {
336
+ nonempty(model, `artifact.revalidation.models[${index}]`);
337
+ }
338
+ for (const [index, relationship] of plan.relationships.entries()) {
339
+ validateRelationshipArtifact(relationship, `artifact.revalidation.relationships[${index}]`);
340
+ }
341
+ if ((artifact.effects.operations.length === 0 ||
342
+ (artifact.consistency !== 'projected' &&
343
+ artifact.confirmations?.kind !== 'finite')) &&
344
+ !plan.required) {
345
+ artifactInvalid('artifact.revalidation.required');
346
+ }
347
+ }
348
+ export function validateEffectArtifact(effect, input, path) {
349
+ if (effect === null || typeof effect !== 'object')
350
+ artifactInvalid(path);
351
+ switch (effect.kind) {
352
+ case 'upsert':
353
+ case 'patch':
354
+ requiredString(effect.model, `${path}.model`);
355
+ validateKeyArtifact(effect.key, input, `${path}.key`);
356
+ validateFieldsArtifact(effect.fields, input, `${path}.fields`);
357
+ return;
358
+ case 'delete':
359
+ requiredString(effect.model, `${path}.model`);
360
+ validateKeyArtifact(effect.key, input, `${path}.key`);
361
+ return;
362
+ case 'link':
363
+ case 'unlink':
364
+ validateRelationshipArtifact(effect.relationship, `${path}.relationship`);
365
+ validateKeyArtifact(effect.source, input, `${path}.source`);
366
+ validateKeyArtifact(effect.target, input, `${path}.target`);
367
+ return;
368
+ case 'invalidate_model':
369
+ requiredString(effect.model, `${path}.model`);
370
+ return;
371
+ case 'invalidate_relationship':
372
+ validateRelationshipArtifact(effect.relationship, `${path}.relationship`);
373
+ validateKeyArtifact(effect.source, input, `${path}.source`);
374
+ return;
375
+ default:
376
+ artifactInvalid(`${path}.kind`);
377
+ }
378
+ }
379
+ export function validateKeyArtifact(key, input, path) {
380
+ if (key === null ||
381
+ typeof key !== 'object' ||
382
+ !Array.isArray(key.fields) ||
383
+ key.fields.length === 0) {
384
+ artifactInvalid(path);
385
+ }
386
+ validateFieldsArtifact(key.fields, input, `${path}.fields`);
387
+ }
388
+ export function validateFieldsArtifact(fields, input, path) {
389
+ if (!Array.isArray(fields))
390
+ artifactInvalid(path);
391
+ const names = new Set();
392
+ for (let index = 0; index < fields.length; index += 1) {
393
+ const field = fields[index];
394
+ const fieldPath = `${path}[${index}]`;
395
+ const name = requiredString(field.field, `${fieldPath}.field`);
396
+ if (names.has(name))
397
+ artifactInvalid(`${fieldPath}.field`);
398
+ names.add(name);
399
+ validateExpressionArtifact(field.value, input, `${fieldPath}.value`);
400
+ }
401
+ }
402
+ export function validateExpressionArtifact(expression, input, path) {
403
+ if (expression === null || typeof expression !== 'object') {
404
+ artifactInvalid(path);
405
+ }
406
+ switch (expression.kind) {
407
+ case 'input':
408
+ if (!Array.isArray(expression.path) ||
409
+ expression.path.length === 0 ||
410
+ expression.path.some((segment) => typeof segment !== 'string' || !GRAPHQL_NAME.test(segment))) {
411
+ artifactInvalid(`${path}.path`);
412
+ }
413
+ if (input.kind !== 'object')
414
+ artifactInvalid(`${path}.path`);
415
+ fieldAtPath(input.definition, expression.path, path);
416
+ return;
417
+ case 'constant':
418
+ validateArtifactJson(expression.value, `${path}.value`, new Set(), 0);
419
+ return;
420
+ case 'null':
421
+ return;
422
+ case 'trusted_preset':
423
+ trustedPresetName(expression.name, `${path}.name`);
424
+ return;
425
+ case undefined:
426
+ default:
427
+ artifactInvalid(`${path}.kind`);
428
+ }
429
+ }
430
+ export function validateRelationshipArtifact(relationship, path) {
431
+ if (relationship === null || typeof relationship !== 'object') {
432
+ artifactInvalid(path);
433
+ }
434
+ requiredString(relationship.sourceModel, `${path}.sourceModel`);
435
+ requiredString(relationship.field, `${path}.field`);
436
+ requiredString(relationship.targetModel, `${path}.targetModel`);
437
+ }
438
+ export function validateArtifactJson(value, path, active, depth) {
439
+ if (depth > MAX_TYPE_DEPTH)
440
+ artifactInvalid(path);
441
+ if (value === null ||
442
+ typeof value === 'string' ||
443
+ typeof value === 'boolean') {
444
+ return;
445
+ }
446
+ if (typeof value === 'number') {
447
+ if (!Number.isFinite(value))
448
+ artifactInvalid(path);
449
+ return;
450
+ }
451
+ if (typeof value !== 'object')
452
+ artifactInvalid(path);
453
+ if (active.has(value))
454
+ artifactInvalid(path);
455
+ active.add(value);
456
+ if (Array.isArray(value)) {
457
+ for (let index = 0; index < value.length; index += 1) {
458
+ validateArtifactJson(value[index], `${path}[${index}]`, active, depth + 1);
459
+ }
460
+ active.delete(value);
461
+ return;
462
+ }
463
+ if (!isPlainRecord(value))
464
+ artifactInvalid(path);
465
+ for (const key of Reflect.ownKeys(value)) {
466
+ if (typeof key !== 'string')
467
+ artifactInvalid(path);
468
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
469
+ if (descriptor === undefined ||
470
+ !('value' in descriptor) ||
471
+ descriptor.value === undefined) {
472
+ artifactInvalid(`${path}.${key}`);
473
+ }
474
+ validateArtifactJson(descriptor.value, `${path}.${key}`, active, depth + 1);
475
+ }
476
+ active.delete(value);
477
+ }
@@ -0,0 +1,3 @@
1
+ /** Command artifacts and prepare/verify; implementation in ./commands/. */
2
+ export { matchReplicaTrustedPresetInventory, prepareReplicaCommand, prepareReplicaCommandWithTrustedPresets, ReplicaCommandContractError, verifyReplicaCommandReceipt } from './commands/index.js';
3
+ export type { PrepareReplicaCommandOptions, ReplicaCommandArtifact, ReplicaCommandConfirmation, ReplicaCommandConfirmations, ReplicaCommandContractErrorCode, ReplicaCommandDirectProjection, ReplicaCommandEffect, ReplicaCommandEffectExpression, ReplicaCommandEffectField, ReplicaCommandEffectKey, ReplicaCommandEffectRelationship, ReplicaCommandEffects, ReplicaCommandGenerators, ReplicaCommandInputDefault, ReplicaCommandInputDefaults, ReplicaCommandRevalidationPlan, ReplicaCommandScalarCodec, ReplicaCommandShape, ReplicaCommandTypeDefinition, ReplicaCommandTypeField, ReplicaCommandVariables, ReplicaMatchedTrustedPresetInventory, ReplicaPreparedCommand, ReplicaPreparedCommandEffect, ReplicaPreparedConfirmation, ReplicaPreparedConfirmations, ReplicaPreparedEffectField, ReplicaPreparedEffectKey, ReplicaReceiptVerification, ReplicaTrustedPresetDescriptor } from './commands/index.js';
@@ -0,0 +1,2 @@
1
+ /** Command artifacts and prepare/verify; implementation in ./commands/. */
2
+ export { matchReplicaTrustedPresetInventory, prepareReplicaCommand, prepareReplicaCommandWithTrustedPresets, ReplicaCommandContractError, verifyReplicaCommandReceipt } from './commands/index.js';
@@ -0,0 +1,4 @@
1
+ import type { ReplicaDevelopmentCapability, ReplicaDiagnostics, ReplicaDiagnosticsOptions } from './types.js';
2
+ export declare function createReplicaDevelopmentCapability(): ReplicaDevelopmentCapability;
3
+ /** Framework-neutral diagnostics store shared by every framework adapter. */
4
+ export declare function createReplicaDiagnostics(options?: ReplicaDiagnosticsOptions): ReplicaDiagnostics;