@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,789 @@
1
+ import { validateReplicaOperationBinding } from '../operation-binding.js';
2
+ import { compareCodeUnits } from '../../lib/compare-code-units.js';
3
+ import { freezeRecord } from '../../lib/freeze-record.js';
4
+ import { isPlainRecord } from '../../lib/is-plain-record.js';
5
+ import { FILTER_OPERATORS, GRAPHQL_NAME, MAX_VARIABLE_CODEC_DEPTH } from './constants.js';
6
+ /**
7
+ * Apply the exact compiler-owned GraphQL input coercion contract before an
8
+ * operation can acquire cache identity or reach a transport.
9
+ */
10
+ export function canonicalizeOperationVariables(artifact, variables) {
11
+ validateReplicaOperationBinding(artifact);
12
+ const codec = artifact.variableCodec;
13
+ if (codec === undefined) {
14
+ throw new TypeError('protocol-v1 replica artifact requires variableCodec');
15
+ }
16
+ const registry = validateVariableCodec(codec);
17
+ const supplied = new Map(inputRecordEntries(variables, 'variables').map(([name, value]) => {
18
+ if (!registry.variables.has(name)) {
19
+ variableValueInvalid(`variables.${name}`, 'unknown operation variable');
20
+ }
21
+ return [name, value];
22
+ }));
23
+ const canonical = [];
24
+ for (const [name, input] of [...registry.variables].sort(([left], [right]) => compareCodeUnits(left, right))) {
25
+ const present = supplied.has(name) && supplied.get(name) !== undefined;
26
+ if (!present) {
27
+ if (!input.nullable) {
28
+ variableValueInvalid(`variables.${name}`, 'required variable is missing');
29
+ }
30
+ continue;
31
+ }
32
+ canonical.push([
33
+ name,
34
+ canonicalizeInputRef(input, supplied.get(name), registry, `variables.${name}`, new Set(), 0)
35
+ ]);
36
+ }
37
+ return freezeRecord(canonical);
38
+ }
39
+ export function validateVariableCodec(codec) {
40
+ const root = artifactRecord(codec, 'artifact.variableCodec', ['version', 'limits', 'variables', 'inputs']);
41
+ if (root.version !== 1)
42
+ variableCodecInvalid('artifact.variableCodec.version');
43
+ const rawLimits = artifactRecord(root.limits, 'artifact.variableCodec.limits', ['maxDepth', 'maxBoolWidth', 'maxInList']);
44
+ const limits = {
45
+ maxDepth: validateCodecLimit(rawLimits.maxDepth, 'artifact.variableCodec.limits.maxDepth'),
46
+ maxBoolWidth: validateCodecLimit(rawLimits.maxBoolWidth, 'artifact.variableCodec.limits.maxBoolWidth'),
47
+ maxInList: validateCodecLimit(rawLimits.maxInList, 'artifact.variableCodec.limits.maxInList')
48
+ };
49
+ const inputEntries = artifactRecordEntries(root.inputs, 'artifact.variableCodec.inputs');
50
+ const inputs = new Map();
51
+ for (const [name, definition] of inputEntries) {
52
+ assertGraphqlName(name, `artifact.variableCodec.inputs.${name}`);
53
+ inputs.set(name, definition);
54
+ }
55
+ const variableEntries = artifactRecordEntries(root.variables, 'artifact.variableCodec.variables');
56
+ const variables = new Map();
57
+ for (const [name, input] of variableEntries) {
58
+ assertGraphqlName(name, `artifact.variableCodec.variables.${name}`);
59
+ validateInputRef(input, `artifact.variableCodec.variables.${name}`, inputs, limits, new Set(), 0);
60
+ variables.set(name, input);
61
+ }
62
+ for (const [name, definition] of inputs) {
63
+ validateInputDefinition(definition, `artifact.variableCodec.inputs.${name}`, inputs, new Set(), 0);
64
+ }
65
+ return { limits, variables, inputs };
66
+ }
67
+ export function validateInputRef(value, path, inputs, limits, active, depth) {
68
+ checkCodecDepth(depth, path);
69
+ const ref = artifactRecord(value, path);
70
+ withActiveArtifact(ref, active, path, () => {
71
+ switch (ref.kind) {
72
+ case 'scalar':
73
+ exactArtifactKeys(ref, path, [
74
+ 'kind',
75
+ 'scalar',
76
+ 'codec',
77
+ 'nullable'
78
+ ]);
79
+ assertBoolean(ref.nullable, `${path}.nullable`);
80
+ validateScalarContract(ref.scalar, ref.codec, path);
81
+ return;
82
+ case 'enum':
83
+ exactArtifactKeys(ref, path, ['kind', 'name', 'values', 'nullable']);
84
+ assertGraphqlName(ref.name, `${path}.name`);
85
+ assertBoolean(ref.nullable, `${path}.nullable`);
86
+ validateStringInventory(ref.values, `${path}.values`);
87
+ return;
88
+ case 'input': {
89
+ const hasFilterBaseDepth = Object.prototype.hasOwnProperty.call(ref, 'filterBaseDepth');
90
+ exactArtifactKeys(ref, path, hasFilterBaseDepth
91
+ ? ['kind', 'name', 'nullable', 'filterBaseDepth']
92
+ : ['kind', 'name', 'nullable']);
93
+ assertGraphqlName(ref.name, `${path}.name`);
94
+ assertBoolean(ref.nullable, `${path}.nullable`);
95
+ const definition = inputs.get(ref.name);
96
+ if (definition === undefined)
97
+ variableCodecInvalid(`${path}.name`);
98
+ const definitionKind = artifactRecord(definition, `artifact.variableCodec.inputs.${ref.name}`).kind;
99
+ if (definitionKind === 'filter') {
100
+ if (!hasFilterBaseDepth) {
101
+ variableCodecInvalid(`${path}.filterBaseDepth`);
102
+ }
103
+ const filterBaseDepth = validateCodecLimit(ref.filterBaseDepth, `${path}.filterBaseDepth`);
104
+ if (filterBaseDepth > limits.maxDepth) {
105
+ variableCodecInvalid(`${path}.filterBaseDepth`);
106
+ }
107
+ }
108
+ else if (hasFilterBaseDepth) {
109
+ variableCodecInvalid(`${path}.filterBaseDepth`);
110
+ }
111
+ return;
112
+ }
113
+ case 'list': {
114
+ const hasMaxItems = Object.prototype.hasOwnProperty.call(ref, 'maxItems');
115
+ exactArtifactKeys(ref, path, hasMaxItems
116
+ ? ['kind', 'nullable', 'maxItems', 'item']
117
+ : ['kind', 'nullable', 'item']);
118
+ assertBoolean(ref.nullable, `${path}.nullable`);
119
+ if (hasMaxItems)
120
+ validateCodecLimit(ref.maxItems, `${path}.maxItems`);
121
+ validateInputRef(ref.item, `${path}.item`, inputs, limits, active, depth + 1);
122
+ return;
123
+ }
124
+ default:
125
+ variableCodecInvalid(`${path}.kind`);
126
+ }
127
+ });
128
+ }
129
+ export function validateInputDefinition(value, path, inputs, active, depth) {
130
+ checkCodecDepth(depth, path);
131
+ const definition = artifactRecord(value, path);
132
+ withActiveArtifact(definition, active, path, () => {
133
+ switch (definition.kind) {
134
+ case 'filter':
135
+ exactArtifactKeys(definition, path, [
136
+ 'kind',
137
+ 'model',
138
+ 'fields',
139
+ 'relationships'
140
+ ]);
141
+ assertNonemptyString(definition.model, `${path}.model`);
142
+ validateFilterInputDefinition(definition, path, inputs, active, depth + 1);
143
+ return;
144
+ case 'order':
145
+ exactArtifactKeys(definition, path, [
146
+ 'kind',
147
+ 'model',
148
+ 'fields',
149
+ 'values'
150
+ ]);
151
+ assertNonemptyString(definition.model, `${path}.model`);
152
+ validateOrderInputDefinition(definition, path, active);
153
+ return;
154
+ default:
155
+ variableCodecInvalid(`${path}.kind`);
156
+ }
157
+ });
158
+ }
159
+ export function validateFilterInputDefinition(definition, path, inputs, active, depth) {
160
+ const fields = artifactArray(definition.fields, `${path}.fields`);
161
+ const relationships = artifactArray(definition.relationships, `${path}.relationships`);
162
+ const names = new Set(['_and', '_or', '_not']);
163
+ for (let index = 0; index < fields.length; index += 1) {
164
+ const fieldPath = `${path}.fields[${index}]`;
165
+ const field = artifactRecord(fields[index], fieldPath, [
166
+ 'field',
167
+ 'scalar',
168
+ 'codec',
169
+ 'nullable',
170
+ 'operators'
171
+ ]);
172
+ withActiveArtifact(field, active, fieldPath, () => {
173
+ assertGraphqlName(field.field, `${fieldPath}.field`);
174
+ if (names.has(field.field))
175
+ variableCodecInvalid(`${fieldPath}.field`);
176
+ names.add(field.field);
177
+ assertBoolean(field.nullable, `${fieldPath}.nullable`);
178
+ validateScalarContract(field.scalar, field.codec, fieldPath);
179
+ const operators = artifactArray(field.operators, `${fieldPath}.operators`);
180
+ if (operators.length === 0)
181
+ variableCodecInvalid(`${fieldPath}.operators`);
182
+ const seen = new Set();
183
+ for (let operator = 0; operator < operators.length; operator += 1) {
184
+ const value = operators[operator];
185
+ if (typeof value !== 'string' ||
186
+ !FILTER_OPERATORS.has(value) ||
187
+ seen.has(value)) {
188
+ variableCodecInvalid(`${fieldPath}.operators[${operator}]`);
189
+ }
190
+ validateFilterOperatorContract(field.scalar, value, `${fieldPath}.operators[${operator}]`);
191
+ seen.add(value);
192
+ }
193
+ });
194
+ }
195
+ for (let index = 0; index < relationships.length; index += 1) {
196
+ const relationshipPath = `${path}.relationships[${index}]`;
197
+ const relationship = artifactRecord(relationships[index], relationshipPath, ['field', 'target']);
198
+ withActiveArtifact(relationship, active, relationshipPath, () => {
199
+ assertGraphqlName(relationship.field, `${relationshipPath}.field`);
200
+ if (names.has(relationship.field)) {
201
+ variableCodecInvalid(`${relationshipPath}.field`);
202
+ }
203
+ names.add(relationship.field);
204
+ const target = artifactRecord(relationship.target, `${relationshipPath}.target`);
205
+ withActiveArtifact(target, active, `${relationshipPath}.target`, () => {
206
+ if (target.kind === 'opaque') {
207
+ exactArtifactKeys(target, `${relationshipPath}.target`, ['kind']);
208
+ return;
209
+ }
210
+ if (target.kind !== 'input') {
211
+ variableCodecInvalid(`${relationshipPath}.target.kind`);
212
+ }
213
+ exactArtifactKeys(target, `${relationshipPath}.target`, ['kind', 'name']);
214
+ assertGraphqlName(target.name, `${relationshipPath}.target.name`);
215
+ const targetDefinition = inputs.get(target.name);
216
+ if (targetDefinition === undefined ||
217
+ artifactRecord(targetDefinition, `artifact.variableCodec.inputs.${target.name}`).kind !== 'filter') {
218
+ variableCodecInvalid(`${relationshipPath}.target.name`);
219
+ }
220
+ });
221
+ });
222
+ }
223
+ checkCodecDepth(depth, path);
224
+ }
225
+ export function validateOrderInputDefinition(definition, path, active) {
226
+ const fields = artifactArray(definition.fields, `${path}.fields`);
227
+ if (fields.length === 0)
228
+ variableCodecInvalid(`${path}.fields`);
229
+ const names = new Set();
230
+ for (let index = 0; index < fields.length; index += 1) {
231
+ const fieldPath = `${path}.fields[${index}]`;
232
+ const field = artifactRecord(fields[index], fieldPath, [
233
+ 'field',
234
+ 'scalar',
235
+ 'codec',
236
+ 'nullable'
237
+ ]);
238
+ withActiveArtifact(field, active, fieldPath, () => {
239
+ assertGraphqlName(field.field, `${fieldPath}.field`);
240
+ if (names.has(field.field))
241
+ variableCodecInvalid(`${fieldPath}.field`);
242
+ names.add(field.field);
243
+ assertBoolean(field.nullable, `${fieldPath}.nullable`);
244
+ validateScalarContract(field.scalar, field.codec, fieldPath);
245
+ });
246
+ }
247
+ validateStringInventory(definition.values, `${path}.values`);
248
+ }
249
+ export function canonicalizeInputRef(input, value, registry, path, active, depth) {
250
+ checkValueDepth(depth, path);
251
+ if (input.kind === 'input') {
252
+ const definition = registry.inputs.get(input.name);
253
+ if (definition === undefined) {
254
+ variableCodecInvalid(`artifact.variableCodec.inputs.${input.name}`);
255
+ }
256
+ if (definition.kind === 'filter') {
257
+ if (input.filterBaseDepth === undefined) {
258
+ variableCodecInvalid(`${path}.filterBaseDepth`);
259
+ }
260
+ checkFilterDepth(input.filterBaseDepth, registry.limits, path);
261
+ }
262
+ }
263
+ if (value === null) {
264
+ if (!input.nullable)
265
+ variableValueInvalid(path, 'non-null value required');
266
+ return null;
267
+ }
268
+ switch (input.kind) {
269
+ case 'scalar':
270
+ return canonicalizeScalar(input.scalar, input.codec, value, path);
271
+ case 'enum':
272
+ if (typeof value !== 'string' || !input.values.includes(value)) {
273
+ variableValueInvalid(path, `expected enum ${input.name}`);
274
+ }
275
+ return value;
276
+ case 'input': {
277
+ const definition = registry.inputs.get(input.name);
278
+ if (definition === undefined) {
279
+ variableCodecInvalid(`artifact.variableCodec.inputs.${input.name}`);
280
+ }
281
+ return canonicalizeInputDefinition(definition, value, registry, path, active, depth + 1, input.filterBaseDepth);
282
+ }
283
+ case 'list': {
284
+ const values = Array.isArray(value)
285
+ ? inputArrayValues(value, path)
286
+ : [value];
287
+ if (input.maxItems !== undefined && values.length > input.maxItems) {
288
+ variableValueInvalid(path, `list contains ${values.length} items, exceeding maxItems ${input.maxItems}`);
289
+ }
290
+ const tracksArray = Array.isArray(value);
291
+ if (tracksArray)
292
+ beginValue(value, active, path);
293
+ try {
294
+ return Object.freeze(values.map((entry, index) => {
295
+ const item = entry === undefined ? null : entry;
296
+ return canonicalizeInputRef(input.item, item, registry, `${path}[${index}]`, active, depth + 1);
297
+ }));
298
+ }
299
+ finally {
300
+ if (tracksArray)
301
+ active.delete(value);
302
+ }
303
+ }
304
+ }
305
+ }
306
+ export function canonicalizeInputDefinition(definition, value, registry, path, active, depth, filterBaseDepth) {
307
+ checkValueDepth(depth, path);
308
+ if (definition.kind === 'filter') {
309
+ if (filterBaseDepth === undefined) {
310
+ variableCodecInvalid(`${path}.filterBaseDepth`);
311
+ }
312
+ return canonicalizeFilterInput(definition, value, registry, path, active, depth, filterBaseDepth);
313
+ }
314
+ return canonicalizeOrderInput(definition, value, path, active, depth);
315
+ }
316
+ export function canonicalizeFilterInput(definition, value, registry, path, active, depth, filterDepth) {
317
+ checkValueDepth(depth, path);
318
+ checkFilterDepth(filterDepth, registry.limits, path);
319
+ const entries = inputRecordEntries(value, path);
320
+ beginValue(value, active, path);
321
+ try {
322
+ const fields = new Map(definition.fields.map((field) => [field.field, field]));
323
+ const relationships = new Map(definition.relationships.map((relationship) => [
324
+ relationship.field,
325
+ relationship.target
326
+ ]));
327
+ const canonical = [];
328
+ for (const [field, fieldValue] of entries.sort(([left], [right]) => compareCodeUnits(left, right))) {
329
+ if (fieldValue === undefined)
330
+ continue;
331
+ const fieldPath = `${path}.${field}`;
332
+ if (field === '_and' || field === '_or') {
333
+ if (fieldValue === null) {
334
+ canonical.push([field, null]);
335
+ continue;
336
+ }
337
+ const predicates = Array.isArray(fieldValue)
338
+ ? inputArrayValues(fieldValue, fieldPath)
339
+ : [fieldValue];
340
+ if (predicates.length > registry.limits.maxBoolWidth) {
341
+ variableValueInvalid(fieldPath, `boolean list contains ${predicates.length} items, exceeding maxBoolWidth ${registry.limits.maxBoolWidth}`);
342
+ }
343
+ if (Array.isArray(fieldValue))
344
+ beginValue(fieldValue, active, fieldPath);
345
+ try {
346
+ canonical.push([
347
+ field,
348
+ Object.freeze(predicates.map((predicate, index) => {
349
+ if (predicate === null || predicate === undefined) {
350
+ variableValueInvalid(`${fieldPath}[${index}]`, 'filter list items must be non-null');
351
+ }
352
+ return canonicalizeFilterInput(definition, predicate, registry, `${fieldPath}[${index}]`, active, depth + 1, filterDepth + 1);
353
+ }))
354
+ ]);
355
+ }
356
+ finally {
357
+ if (Array.isArray(fieldValue))
358
+ active.delete(fieldValue);
359
+ }
360
+ continue;
361
+ }
362
+ if (field === '_not') {
363
+ const childFilterDepth = filterDepth + 1;
364
+ checkFilterDepth(childFilterDepth, registry.limits, fieldPath);
365
+ canonical.push([
366
+ field,
367
+ fieldValue === null
368
+ ? null
369
+ : canonicalizeFilterInput(definition, fieldValue, registry, fieldPath, active, depth + 1, childFilterDepth)
370
+ ]);
371
+ continue;
372
+ }
373
+ const comparison = fields.get(field);
374
+ if (comparison !== undefined) {
375
+ canonical.push([
376
+ field,
377
+ fieldValue === null
378
+ ? null
379
+ : canonicalizeFilterComparison(comparison, fieldValue, fieldPath, active, depth + 1, registry.limits)
380
+ ]);
381
+ continue;
382
+ }
383
+ const relationship = relationships.get(field);
384
+ if (relationship !== undefined) {
385
+ const childFilterDepth = filterDepth + 1;
386
+ checkFilterDepth(childFilterDepth, registry.limits, fieldPath);
387
+ if (fieldValue === null) {
388
+ canonical.push([field, null]);
389
+ }
390
+ else if (relationship.kind === 'opaque') {
391
+ canonical.push([
392
+ field,
393
+ cloneCanonicalJsonObject(fieldValue, fieldPath, active, depth + 1, true)
394
+ ]);
395
+ }
396
+ else {
397
+ const target = registry.inputs.get(relationship.name);
398
+ if (target?.kind !== 'filter') {
399
+ variableCodecInvalid(`artifact.variableCodec.inputs.${relationship.name}`);
400
+ }
401
+ canonical.push([
402
+ field,
403
+ canonicalizeFilterInput(target, fieldValue, registry, fieldPath, active, depth + 1, childFilterDepth)
404
+ ]);
405
+ }
406
+ continue;
407
+ }
408
+ variableValueInvalid(fieldPath, 'unknown filter field');
409
+ }
410
+ return freezeRecord(canonical);
411
+ }
412
+ finally {
413
+ active.delete(value);
414
+ }
415
+ }
416
+ export function canonicalizeFilterComparison(field, value, path, active, depth, limits) {
417
+ checkValueDepth(depth, path);
418
+ const entries = inputRecordEntries(value, path);
419
+ beginValue(value, active, path);
420
+ try {
421
+ const allowed = new Set(field.operators);
422
+ const canonical = [];
423
+ for (const [operator, operand] of entries.sort(([left], [right]) => compareCodeUnits(left, right))) {
424
+ if (operand === undefined)
425
+ continue;
426
+ const operatorPath = `${path}.${operator}`;
427
+ if (!allowed.has(operator)) {
428
+ variableValueInvalid(operatorPath, 'unknown filter operator');
429
+ }
430
+ if (operator === '_in' || operator === '_nin') {
431
+ if (operand === null) {
432
+ variableValueInvalid(operatorPath, 'filter list must be non-null');
433
+ }
434
+ const values = Array.isArray(operand)
435
+ ? inputArrayValues(operand, operatorPath)
436
+ : [operand];
437
+ if (values.length > limits.maxInList) {
438
+ variableValueInvalid(operatorPath, `filter list contains ${values.length} items, exceeding maxInList ${limits.maxInList}`);
439
+ }
440
+ if (Array.isArray(operand))
441
+ beginValue(operand, active, operatorPath);
442
+ try {
443
+ canonical.push([
444
+ operator,
445
+ Object.freeze(values.map((item, index) => {
446
+ if (item === null || item === undefined) {
447
+ variableValueInvalid(`${operatorPath}[${index}]`, 'filter list items must be non-null');
448
+ }
449
+ return canonicalizeScalar(field.scalar, field.codec, item, `${operatorPath}[${index}]`);
450
+ }))
451
+ ]);
452
+ }
453
+ finally {
454
+ if (Array.isArray(operand))
455
+ active.delete(operand);
456
+ }
457
+ continue;
458
+ }
459
+ if (operand === null) {
460
+ canonical.push([operator, null]);
461
+ continue;
462
+ }
463
+ if (operator === '_is_null') {
464
+ if (typeof operand !== 'boolean') {
465
+ variableValueInvalid(operatorPath, 'expected boolean or null');
466
+ }
467
+ canonical.push([operator, operand]);
468
+ continue;
469
+ }
470
+ if (operator === '_like' || operator === '_ilike' || operator === '_has_key') {
471
+ if (typeof operand !== 'string') {
472
+ variableValueInvalid(operatorPath, 'expected string or null');
473
+ }
474
+ canonical.push([operator, operand]);
475
+ continue;
476
+ }
477
+ canonical.push([
478
+ operator,
479
+ canonicalizeScalar(field.scalar, field.codec, operand, operatorPath)
480
+ ]);
481
+ }
482
+ return freezeRecord(canonical);
483
+ }
484
+ finally {
485
+ active.delete(value);
486
+ }
487
+ }
488
+ export function canonicalizeOrderInput(definition, value, path, active, depth) {
489
+ checkValueDepth(depth, path);
490
+ const entries = inputRecordEntries(value, path).filter(([, fieldValue]) => fieldValue !== undefined);
491
+ if (entries.length !== 1) {
492
+ variableValueInvalid(path, 'order object must contain exactly one field');
493
+ }
494
+ const [field, direction] = entries[0];
495
+ if (!definition.fields.some((candidate) => candidate.field === field)) {
496
+ variableValueInvalid(`${path}.${field}`, 'unknown order field');
497
+ }
498
+ if (typeof direction !== 'string' || !definition.values.includes(direction)) {
499
+ variableValueInvalid(`${path}.${field}`, 'unknown order direction');
500
+ }
501
+ beginValue(value, active, path);
502
+ try {
503
+ return freezeRecord([[field, direction]]);
504
+ }
505
+ finally {
506
+ active.delete(value);
507
+ }
508
+ }
509
+ export function canonicalizeScalar(scalar, codec, value, path) {
510
+ switch (`${scalar}:${codec}`) {
511
+ case 'ID:string':
512
+ if (typeof value === 'string')
513
+ return value;
514
+ if (typeof value === 'number' && Number.isSafeInteger(value)) {
515
+ return String(Object.is(value, -0) ? 0 : value);
516
+ }
517
+ variableValueInvalid(path, 'ID must be a string or safe integer');
518
+ case 'String:string':
519
+ case 'Timestamptz:string_unvalidated_timestamp':
520
+ if (typeof value !== 'string')
521
+ variableValueInvalid(path, 'expected string');
522
+ return value;
523
+ case 'Bytea:base64':
524
+ return canonicalizeBase64(value, path);
525
+ case 'Boolean:boolean':
526
+ if (typeof value !== 'boolean')
527
+ variableValueInvalid(path, 'expected boolean');
528
+ return value;
529
+ case 'Int:int32':
530
+ if (typeof value !== 'number' ||
531
+ !Number.isInteger(value) ||
532
+ value < -2_147_483_648 ||
533
+ value > 2_147_483_647) {
534
+ variableValueInvalid(path, 'expected signed 32-bit integer');
535
+ }
536
+ return Object.is(value, -0) ? 0 : value;
537
+ case 'Float:float64':
538
+ if (typeof value !== 'number' || !Number.isFinite(value)) {
539
+ variableValueInvalid(path, 'expected finite number');
540
+ }
541
+ return Object.is(value, -0) ? 0 : value;
542
+ case 'BigInt:json_number_precision_limited':
543
+ if (typeof value !== 'number' || !Number.isSafeInteger(value)) {
544
+ variableValueInvalid(path, 'expected safe integer');
545
+ }
546
+ return Object.is(value, -0) ? 0 : value;
547
+ case 'JSON:json':
548
+ return cloneCanonicalJsonValue(value, path, new Set(), 0, false);
549
+ default:
550
+ variableCodecInvalid(path);
551
+ }
552
+ }
553
+ export function canonicalizeBase64(value, path) {
554
+ if (typeof value !== 'string')
555
+ variableValueInvalid(path, 'expected base64 string');
556
+ const decode = globalThis.atob;
557
+ const encode = globalThis.btoa;
558
+ if (typeof decode !== 'function' || typeof encode !== 'function') {
559
+ variableValueInvalid(path, 'base64 codec is unavailable in this runtime');
560
+ }
561
+ try {
562
+ const canonical = encode(decode(value));
563
+ if (canonical !== value) {
564
+ variableValueInvalid(path, 'expected canonical standard base64');
565
+ }
566
+ return canonical;
567
+ }
568
+ catch {
569
+ variableValueInvalid(path, 'expected canonical standard base64');
570
+ }
571
+ }
572
+ export function cloneCanonicalJsonObject(value, path, active, depth, omitUndefined) {
573
+ const entries = inputRecordEntries(value, path);
574
+ checkValueDepth(depth, path);
575
+ beginValue(value, active, path);
576
+ try {
577
+ const canonical = [];
578
+ for (const [key, entry] of entries.sort(([left], [right]) => compareCodeUnits(left, right))) {
579
+ if (entry === undefined && omitUndefined)
580
+ continue;
581
+ if (entry === undefined)
582
+ variableValueInvalid(`${path}.${key}`, 'expected JSON value');
583
+ canonical.push([
584
+ key,
585
+ cloneCanonicalJsonValue(entry, `${path}.${key}`, active, depth + 1, omitUndefined)
586
+ ]);
587
+ }
588
+ return freezeRecord(canonical);
589
+ }
590
+ finally {
591
+ active.delete(value);
592
+ }
593
+ }
594
+ export function cloneCanonicalJsonValue(value, path, active, depth, omitUndefined) {
595
+ checkValueDepth(depth, path);
596
+ if (value === null || typeof value === 'string' || typeof value === 'boolean') {
597
+ return value;
598
+ }
599
+ if (typeof value === 'number') {
600
+ if (!Number.isFinite(value))
601
+ variableValueInvalid(path, 'expected finite JSON number');
602
+ if (Number.isInteger(value) && !Number.isSafeInteger(value)) {
603
+ variableValueInvalid(path, 'expected safe integer or non-integer finite JSON number');
604
+ }
605
+ return Object.is(value, -0) ? 0 : value;
606
+ }
607
+ if (Array.isArray(value)) {
608
+ beginValue(value, active, path);
609
+ try {
610
+ return Object.freeze(inputArrayValues(value, path).map((entry, index) => {
611
+ if (entry === undefined) {
612
+ variableValueInvalid(`${path}[${index}]`, 'expected JSON value');
613
+ }
614
+ return cloneCanonicalJsonValue(entry, `${path}[${index}]`, active, depth + 1, omitUndefined);
615
+ }));
616
+ }
617
+ finally {
618
+ active.delete(value);
619
+ }
620
+ }
621
+ return cloneCanonicalJsonObject(value, path, active, depth, omitUndefined);
622
+ }
623
+ export function validateScalarContract(scalar, codec, path) {
624
+ if (typeof scalar !== 'string' ||
625
+ typeof codec !== 'string' ||
626
+ ![
627
+ 'ID:string',
628
+ 'String:string',
629
+ 'Bytea:base64',
630
+ 'Timestamptz:string_unvalidated_timestamp',
631
+ 'Boolean:boolean',
632
+ 'Int:int32',
633
+ 'Float:float64',
634
+ 'BigInt:json_number_precision_limited',
635
+ 'JSON:json'
636
+ ].includes(`${scalar}:${codec}`)) {
637
+ variableCodecInvalid(`${path}.codec`);
638
+ }
639
+ }
640
+ export function validateFilterOperatorContract(scalar, operator, path) {
641
+ if ((operator === '_like' || operator === '_ilike') &&
642
+ scalar !== 'String') {
643
+ variableCodecInvalid(path);
644
+ }
645
+ if ((operator === '_contains' ||
646
+ operator === '_contained_in' ||
647
+ operator === '_has_key') &&
648
+ scalar !== 'JSON') {
649
+ variableCodecInvalid(path);
650
+ }
651
+ }
652
+ export function validateStringInventory(value, path) {
653
+ const values = artifactArray(value, path);
654
+ if (values.length === 0)
655
+ variableCodecInvalid(path);
656
+ const seen = new Set();
657
+ for (let index = 0; index < values.length; index += 1) {
658
+ const entry = values[index];
659
+ if (typeof entry !== 'string' ||
660
+ !GRAPHQL_NAME.test(entry) ||
661
+ seen.has(entry)) {
662
+ variableCodecInvalid(`${path}[${index}]`);
663
+ }
664
+ seen.add(entry);
665
+ }
666
+ }
667
+ export function artifactRecord(value, path, expectedKeys) {
668
+ const entries = artifactRecordEntries(value, path);
669
+ const record = value;
670
+ if (expectedKeys !== undefined)
671
+ exactArtifactKeys(record, path, expectedKeys, entries);
672
+ return record;
673
+ }
674
+ export function artifactRecordEntries(value, path) {
675
+ return dataRecordEntries(value, path, variableCodecInvalid);
676
+ }
677
+ export function inputRecordEntries(value, path) {
678
+ return dataRecordEntries(value, path, (invalidPath) => variableValueInvalid(invalidPath, 'expected plain input object'));
679
+ }
680
+ export function dataRecordEntries(value, path, fail) {
681
+ if (!isPlainRecord(value))
682
+ fail(path);
683
+ const entries = [];
684
+ for (const key of Reflect.ownKeys(value)) {
685
+ if (typeof key !== 'string')
686
+ fail(path);
687
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
688
+ if (descriptor === undefined ||
689
+ !descriptor.enumerable ||
690
+ !('value' in descriptor)) {
691
+ fail(`${path}.${key}`);
692
+ }
693
+ entries.push([key, descriptor.value]);
694
+ }
695
+ return entries;
696
+ }
697
+ export function exactArtifactKeys(value, path, expected, entries = artifactRecordEntries(value, path)) {
698
+ const actual = new Set(entries.map(([key]) => key));
699
+ if (actual.size !== expected.length ||
700
+ expected.some((key) => !actual.has(key))) {
701
+ variableCodecInvalid(path);
702
+ }
703
+ }
704
+ export function artifactArray(value, path) {
705
+ if (!Array.isArray(value))
706
+ variableCodecInvalid(path);
707
+ return arrayDataValues(value, path, variableCodecInvalid);
708
+ }
709
+ export function inputArrayValues(value, path) {
710
+ return arrayDataValues(value, path, (invalidPath) => variableValueInvalid(invalidPath, 'expected dense data-only input array'));
711
+ }
712
+ export function arrayDataValues(value, path, fail) {
713
+ const result = [];
714
+ const indexes = new Set();
715
+ for (let index = 0; index < value.length; index += 1) {
716
+ const key = String(index);
717
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
718
+ if (descriptor === undefined ||
719
+ !descriptor.enumerable ||
720
+ !('value' in descriptor)) {
721
+ fail(`${path}[${index}]`);
722
+ }
723
+ indexes.add(key);
724
+ result.push(descriptor.value);
725
+ }
726
+ for (const key of Reflect.ownKeys(value)) {
727
+ if (key === 'length' || (typeof key === 'string' && indexes.has(key)))
728
+ continue;
729
+ fail(path);
730
+ }
731
+ return result;
732
+ }
733
+ export function withActiveArtifact(value, active, path, run) {
734
+ if (active.has(value))
735
+ variableCodecInvalid(path);
736
+ active.add(value);
737
+ try {
738
+ run();
739
+ }
740
+ finally {
741
+ active.delete(value);
742
+ }
743
+ }
744
+ export function beginValue(value, active, path) {
745
+ if (active.has(value))
746
+ variableValueInvalid(path, 'input values must not contain cycles');
747
+ active.add(value);
748
+ }
749
+ export function assertGraphqlName(value, path) {
750
+ if (typeof value !== 'string' || !GRAPHQL_NAME.test(value)) {
751
+ variableCodecInvalid(path);
752
+ }
753
+ }
754
+ export function assertNonemptyString(value, path) {
755
+ if (typeof value !== 'string' || value.length === 0)
756
+ variableCodecInvalid(path);
757
+ }
758
+ export function assertBoolean(value, path) {
759
+ if (typeof value !== 'boolean')
760
+ variableCodecInvalid(path);
761
+ }
762
+ export function validateCodecLimit(value, path) {
763
+ if (typeof value !== 'number' ||
764
+ !Number.isSafeInteger(value) ||
765
+ value < 0) {
766
+ variableCodecInvalid(path);
767
+ }
768
+ return value;
769
+ }
770
+ export function checkCodecDepth(depth, path) {
771
+ if (depth > MAX_VARIABLE_CODEC_DEPTH)
772
+ variableCodecInvalid(path);
773
+ }
774
+ export function checkValueDepth(depth, path) {
775
+ if (depth > MAX_VARIABLE_CODEC_DEPTH) {
776
+ variableValueInvalid(path, 'input nesting exceeds the supported depth');
777
+ }
778
+ }
779
+ export function checkFilterDepth(depth, limits, path) {
780
+ if (depth > limits.maxDepth) {
781
+ variableValueInvalid(path, `filter nesting reaches depth ${depth}, exceeding maxDepth ${limits.maxDepth}`);
782
+ }
783
+ }
784
+ export function variableCodecInvalid(path) {
785
+ throw new TypeError(`invalid replica variable codec at ${path}`);
786
+ }
787
+ export function variableValueInvalid(path, detail) {
788
+ throw new TypeError(`invalid GraphQL operation input at ${path}: ${detail}`);
789
+ }