@panproto/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -0
- package/dist/index.cjs +945 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +944 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,945 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const msgpack = require("@msgpack/msgpack");
|
|
4
|
+
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
5
|
+
class PanprotoError extends Error {
|
|
6
|
+
name = "PanprotoError";
|
|
7
|
+
constructor(message, options) {
|
|
8
|
+
super(message, options);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class WasmError extends PanprotoError {
|
|
12
|
+
name = "WasmError";
|
|
13
|
+
}
|
|
14
|
+
class SchemaValidationError extends PanprotoError {
|
|
15
|
+
constructor(message, errors) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.errors = errors;
|
|
18
|
+
}
|
|
19
|
+
name = "SchemaValidationError";
|
|
20
|
+
}
|
|
21
|
+
class MigrationError extends PanprotoError {
|
|
22
|
+
name = "MigrationError";
|
|
23
|
+
}
|
|
24
|
+
class ExistenceCheckError extends PanprotoError {
|
|
25
|
+
constructor(message, report) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.report = report;
|
|
28
|
+
}
|
|
29
|
+
name = "ExistenceCheckError";
|
|
30
|
+
}
|
|
31
|
+
const DEFAULT_WASM_URL = new URL("./panproto_wasm_bg.wasm", typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("index.cjs", document.baseURI).href);
|
|
32
|
+
async function loadWasm(url) {
|
|
33
|
+
const wasmUrl = url ?? DEFAULT_WASM_URL;
|
|
34
|
+
try {
|
|
35
|
+
const response = typeof wasmUrl === "string" ? await fetch(wasmUrl) : await fetch(wasmUrl);
|
|
36
|
+
const { instance } = await WebAssembly.instantiateStreaming(response);
|
|
37
|
+
const exports$1 = instance.exports;
|
|
38
|
+
const memory = instance.exports["memory"];
|
|
39
|
+
if (!memory) {
|
|
40
|
+
throw new WasmError("WASM module missing memory export");
|
|
41
|
+
}
|
|
42
|
+
return { exports: exports$1, memory };
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error instanceof WasmError) throw error;
|
|
45
|
+
throw new WasmError(
|
|
46
|
+
`Failed to load WASM module from ${String(wasmUrl)}`,
|
|
47
|
+
{ cause: error }
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const leakedHandleRegistry = new FinalizationRegistry((info) => {
|
|
52
|
+
try {
|
|
53
|
+
info.freeHandle(info.handle);
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
class WasmHandle {
|
|
58
|
+
#handle;
|
|
59
|
+
#disposed = false;
|
|
60
|
+
#freeHandle;
|
|
61
|
+
constructor(handle, freeHandle) {
|
|
62
|
+
this.#handle = handle;
|
|
63
|
+
this.#freeHandle = freeHandle;
|
|
64
|
+
leakedHandleRegistry.register(this, { handle, freeHandle }, this);
|
|
65
|
+
}
|
|
66
|
+
/** The raw WASM handle id. Only for internal use within the SDK. */
|
|
67
|
+
get id() {
|
|
68
|
+
if (this.#disposed) {
|
|
69
|
+
throw new WasmError("Attempted to use a disposed handle");
|
|
70
|
+
}
|
|
71
|
+
return this.#handle;
|
|
72
|
+
}
|
|
73
|
+
/** Whether this handle has been disposed. */
|
|
74
|
+
get disposed() {
|
|
75
|
+
return this.#disposed;
|
|
76
|
+
}
|
|
77
|
+
/** Release the underlying WASM resource. */
|
|
78
|
+
[Symbol.dispose]() {
|
|
79
|
+
if (this.#disposed) return;
|
|
80
|
+
this.#disposed = true;
|
|
81
|
+
leakedHandleRegistry.unregister(this);
|
|
82
|
+
try {
|
|
83
|
+
this.#freeHandle(this.#handle);
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function createHandle(rawHandle, wasm) {
|
|
89
|
+
return new WasmHandle(rawHandle, (h) => wasm.exports.free_handle(h));
|
|
90
|
+
}
|
|
91
|
+
function packToWasm(value) {
|
|
92
|
+
return msgpack.encode(value);
|
|
93
|
+
}
|
|
94
|
+
function unpackFromWasm(bytes) {
|
|
95
|
+
return msgpack.decode(bytes);
|
|
96
|
+
}
|
|
97
|
+
function packSchemaOps(ops) {
|
|
98
|
+
return msgpack.encode(ops);
|
|
99
|
+
}
|
|
100
|
+
function packMigrationMapping(mapping) {
|
|
101
|
+
return msgpack.encode(mapping);
|
|
102
|
+
}
|
|
103
|
+
class SchemaBuilder {
|
|
104
|
+
#protocolName;
|
|
105
|
+
#protocolHandle;
|
|
106
|
+
#wasm;
|
|
107
|
+
#ops;
|
|
108
|
+
#vertices;
|
|
109
|
+
#edges;
|
|
110
|
+
#hyperEdges;
|
|
111
|
+
#constraints;
|
|
112
|
+
#required;
|
|
113
|
+
constructor(protocolName, protocolHandle, wasm, ops = [], vertices = /* @__PURE__ */ new Map(), edges = [], hyperEdges = /* @__PURE__ */ new Map(), constraints = /* @__PURE__ */ new Map(), required = /* @__PURE__ */ new Map()) {
|
|
114
|
+
this.#protocolName = protocolName;
|
|
115
|
+
this.#protocolHandle = protocolHandle;
|
|
116
|
+
this.#wasm = wasm;
|
|
117
|
+
this.#ops = ops;
|
|
118
|
+
this.#vertices = vertices;
|
|
119
|
+
this.#edges = edges;
|
|
120
|
+
this.#hyperEdges = hyperEdges;
|
|
121
|
+
this.#constraints = constraints;
|
|
122
|
+
this.#required = required;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Add a vertex to the schema.
|
|
126
|
+
*
|
|
127
|
+
* @param id - Unique vertex identifier
|
|
128
|
+
* @param kind - Vertex kind (e.g., 'record', 'object', 'string')
|
|
129
|
+
* @param options - Optional vertex configuration (nsid, etc.)
|
|
130
|
+
* @returns A new builder with the vertex added
|
|
131
|
+
* @throws {@link SchemaValidationError} if vertex id is already in use
|
|
132
|
+
*/
|
|
133
|
+
vertex(id, kind, options) {
|
|
134
|
+
if (this.#vertices.has(id)) {
|
|
135
|
+
throw new SchemaValidationError(
|
|
136
|
+
`Vertex "${id}" already exists in schema`,
|
|
137
|
+
[`Duplicate vertex id: ${id}`]
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
const vertex = {
|
|
141
|
+
id,
|
|
142
|
+
kind,
|
|
143
|
+
nsid: options?.nsid
|
|
144
|
+
};
|
|
145
|
+
const op = {
|
|
146
|
+
op: "vertex",
|
|
147
|
+
id,
|
|
148
|
+
kind,
|
|
149
|
+
nsid: options?.nsid ?? null
|
|
150
|
+
};
|
|
151
|
+
const newVertices = new Map(this.#vertices);
|
|
152
|
+
newVertices.set(id, vertex);
|
|
153
|
+
return new SchemaBuilder(
|
|
154
|
+
this.#protocolName,
|
|
155
|
+
this.#protocolHandle,
|
|
156
|
+
this.#wasm,
|
|
157
|
+
[...this.#ops, op],
|
|
158
|
+
newVertices,
|
|
159
|
+
this.#edges,
|
|
160
|
+
this.#hyperEdges,
|
|
161
|
+
this.#constraints,
|
|
162
|
+
this.#required
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Add a directed edge to the schema.
|
|
167
|
+
*
|
|
168
|
+
* @param src - Source vertex id
|
|
169
|
+
* @param tgt - Target vertex id
|
|
170
|
+
* @param kind - Edge kind (e.g., 'record-schema', 'prop')
|
|
171
|
+
* @param options - Optional edge configuration (name, etc.)
|
|
172
|
+
* @returns A new builder with the edge added
|
|
173
|
+
* @throws {@link SchemaValidationError} if source or target vertex does not exist
|
|
174
|
+
*/
|
|
175
|
+
edge(src, tgt, kind, options) {
|
|
176
|
+
if (!this.#vertices.has(src)) {
|
|
177
|
+
throw new SchemaValidationError(
|
|
178
|
+
`Edge source "${src}" does not exist`,
|
|
179
|
+
[`Unknown source vertex: ${src}`]
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
if (!this.#vertices.has(tgt)) {
|
|
183
|
+
throw new SchemaValidationError(
|
|
184
|
+
`Edge target "${tgt}" does not exist`,
|
|
185
|
+
[`Unknown target vertex: ${tgt}`]
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
const edge = {
|
|
189
|
+
src,
|
|
190
|
+
tgt,
|
|
191
|
+
kind,
|
|
192
|
+
name: options?.name
|
|
193
|
+
};
|
|
194
|
+
const op = {
|
|
195
|
+
op: "edge",
|
|
196
|
+
src,
|
|
197
|
+
tgt,
|
|
198
|
+
kind,
|
|
199
|
+
name: options?.name ?? null
|
|
200
|
+
};
|
|
201
|
+
return new SchemaBuilder(
|
|
202
|
+
this.#protocolName,
|
|
203
|
+
this.#protocolHandle,
|
|
204
|
+
this.#wasm,
|
|
205
|
+
[...this.#ops, op],
|
|
206
|
+
this.#vertices,
|
|
207
|
+
[...this.#edges, edge],
|
|
208
|
+
this.#hyperEdges,
|
|
209
|
+
this.#constraints,
|
|
210
|
+
this.#required
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Add a hyperedge to the schema.
|
|
215
|
+
*
|
|
216
|
+
* Only valid if the protocol's schema theory includes ThHypergraph.
|
|
217
|
+
*
|
|
218
|
+
* @param id - Unique hyperedge identifier
|
|
219
|
+
* @param kind - Hyperedge kind
|
|
220
|
+
* @param signature - Label-to-vertex mapping
|
|
221
|
+
* @param parentLabel - The label identifying the parent in the signature
|
|
222
|
+
* @returns A new builder with the hyperedge added
|
|
223
|
+
*/
|
|
224
|
+
hyperEdge(id, kind, signature, parentLabel) {
|
|
225
|
+
const he = { id, kind, signature, parentLabel };
|
|
226
|
+
const op = {
|
|
227
|
+
op: "hyper_edge",
|
|
228
|
+
id,
|
|
229
|
+
kind,
|
|
230
|
+
signature,
|
|
231
|
+
parent: parentLabel
|
|
232
|
+
};
|
|
233
|
+
const newHyperEdges = new Map(this.#hyperEdges);
|
|
234
|
+
newHyperEdges.set(id, he);
|
|
235
|
+
return new SchemaBuilder(
|
|
236
|
+
this.#protocolName,
|
|
237
|
+
this.#protocolHandle,
|
|
238
|
+
this.#wasm,
|
|
239
|
+
[...this.#ops, op],
|
|
240
|
+
this.#vertices,
|
|
241
|
+
this.#edges,
|
|
242
|
+
newHyperEdges,
|
|
243
|
+
this.#constraints,
|
|
244
|
+
this.#required
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Add a constraint to a vertex.
|
|
249
|
+
*
|
|
250
|
+
* @param vertexId - The vertex to constrain
|
|
251
|
+
* @param sort - Constraint sort (e.g., 'maxLength')
|
|
252
|
+
* @param value - Constraint value
|
|
253
|
+
* @returns A new builder with the constraint added
|
|
254
|
+
*/
|
|
255
|
+
constraint(vertexId, sort, value) {
|
|
256
|
+
const c = { sort, value };
|
|
257
|
+
const op = {
|
|
258
|
+
op: "constraint",
|
|
259
|
+
vertex: vertexId,
|
|
260
|
+
sort,
|
|
261
|
+
value
|
|
262
|
+
};
|
|
263
|
+
const existing = this.#constraints.get(vertexId) ?? [];
|
|
264
|
+
const newConstraints = new Map(this.#constraints);
|
|
265
|
+
newConstraints.set(vertexId, [...existing, c]);
|
|
266
|
+
return new SchemaBuilder(
|
|
267
|
+
this.#protocolName,
|
|
268
|
+
this.#protocolHandle,
|
|
269
|
+
this.#wasm,
|
|
270
|
+
[...this.#ops, op],
|
|
271
|
+
this.#vertices,
|
|
272
|
+
this.#edges,
|
|
273
|
+
this.#hyperEdges,
|
|
274
|
+
newConstraints,
|
|
275
|
+
this.#required
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Mark edges as required for a vertex.
|
|
280
|
+
*
|
|
281
|
+
* @param vertexId - The vertex with required edges
|
|
282
|
+
* @param edges - The edges that are required
|
|
283
|
+
* @returns A new builder with the requirement added
|
|
284
|
+
*/
|
|
285
|
+
required(vertexId, edges) {
|
|
286
|
+
const op = {
|
|
287
|
+
op: "required",
|
|
288
|
+
vertex: vertexId,
|
|
289
|
+
edges: edges.map((e) => ({
|
|
290
|
+
src: e.src,
|
|
291
|
+
tgt: e.tgt,
|
|
292
|
+
kind: e.kind,
|
|
293
|
+
name: e.name ?? null
|
|
294
|
+
}))
|
|
295
|
+
};
|
|
296
|
+
const existing = this.#required.get(vertexId) ?? [];
|
|
297
|
+
const newRequired = new Map(this.#required);
|
|
298
|
+
newRequired.set(vertexId, [...existing, ...edges]);
|
|
299
|
+
return new SchemaBuilder(
|
|
300
|
+
this.#protocolName,
|
|
301
|
+
this.#protocolHandle,
|
|
302
|
+
this.#wasm,
|
|
303
|
+
[...this.#ops, op],
|
|
304
|
+
this.#vertices,
|
|
305
|
+
this.#edges,
|
|
306
|
+
this.#hyperEdges,
|
|
307
|
+
this.#constraints,
|
|
308
|
+
newRequired
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Validate and build the schema.
|
|
313
|
+
*
|
|
314
|
+
* Sends all accumulated operations to WASM for validation and construction.
|
|
315
|
+
* Returns a `BuiltSchema` that holds the WASM handle and local data.
|
|
316
|
+
*
|
|
317
|
+
* @returns The validated, built schema
|
|
318
|
+
* @throws {@link SchemaValidationError} if the schema is invalid
|
|
319
|
+
*/
|
|
320
|
+
build() {
|
|
321
|
+
const opsBytes = packSchemaOps([...this.#ops]);
|
|
322
|
+
const rawHandle = this.#wasm.exports.build_schema(
|
|
323
|
+
this.#protocolHandle.id,
|
|
324
|
+
opsBytes
|
|
325
|
+
);
|
|
326
|
+
const handle = createHandle(rawHandle, this.#wasm);
|
|
327
|
+
const data = {
|
|
328
|
+
protocol: this.#protocolName,
|
|
329
|
+
vertices: Object.fromEntries(this.#vertices),
|
|
330
|
+
edges: [...this.#edges],
|
|
331
|
+
hyperEdges: Object.fromEntries(this.#hyperEdges),
|
|
332
|
+
constraints: Object.fromEntries(
|
|
333
|
+
Array.from(this.#constraints.entries()).map(([k, v]) => [k, [...v]])
|
|
334
|
+
),
|
|
335
|
+
required: Object.fromEntries(
|
|
336
|
+
Array.from(this.#required.entries()).map(([k, v]) => [k, [...v]])
|
|
337
|
+
)
|
|
338
|
+
};
|
|
339
|
+
return new BuiltSchema(handle, data, this.#wasm);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
class BuiltSchema {
|
|
343
|
+
#handle;
|
|
344
|
+
#data;
|
|
345
|
+
#wasm;
|
|
346
|
+
constructor(handle, data, wasm) {
|
|
347
|
+
this.#handle = handle;
|
|
348
|
+
this.#data = data;
|
|
349
|
+
this.#wasm = wasm;
|
|
350
|
+
}
|
|
351
|
+
/** The WASM handle for this schema. Internal use only. */
|
|
352
|
+
get _handle() {
|
|
353
|
+
return this.#handle;
|
|
354
|
+
}
|
|
355
|
+
/** The WASM module reference. Internal use only. */
|
|
356
|
+
get _wasm() {
|
|
357
|
+
return this.#wasm;
|
|
358
|
+
}
|
|
359
|
+
/** The schema data (vertices, edges, constraints, etc.). */
|
|
360
|
+
get data() {
|
|
361
|
+
return this.#data;
|
|
362
|
+
}
|
|
363
|
+
/** The protocol name this schema belongs to. */
|
|
364
|
+
get protocol() {
|
|
365
|
+
return this.#data.protocol;
|
|
366
|
+
}
|
|
367
|
+
/** All vertices in the schema. */
|
|
368
|
+
get vertices() {
|
|
369
|
+
return this.#data.vertices;
|
|
370
|
+
}
|
|
371
|
+
/** All edges in the schema. */
|
|
372
|
+
get edges() {
|
|
373
|
+
return this.#data.edges;
|
|
374
|
+
}
|
|
375
|
+
/** Release the WASM-side schema resource. */
|
|
376
|
+
[Symbol.dispose]() {
|
|
377
|
+
this.#handle[Symbol.dispose]();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
class Protocol {
|
|
381
|
+
#handle;
|
|
382
|
+
#spec;
|
|
383
|
+
#wasm;
|
|
384
|
+
constructor(handle, spec, wasm) {
|
|
385
|
+
this.#handle = handle;
|
|
386
|
+
this.#spec = spec;
|
|
387
|
+
this.#wasm = wasm;
|
|
388
|
+
}
|
|
389
|
+
/** The protocol name. */
|
|
390
|
+
get name() {
|
|
391
|
+
return this.#spec.name;
|
|
392
|
+
}
|
|
393
|
+
/** The full protocol specification. */
|
|
394
|
+
get spec() {
|
|
395
|
+
return this.#spec;
|
|
396
|
+
}
|
|
397
|
+
/** The WASM handle. Internal use only. */
|
|
398
|
+
get _handle() {
|
|
399
|
+
return this.#handle;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Start building a schema within this protocol.
|
|
403
|
+
*
|
|
404
|
+
* @returns A new `SchemaBuilder` bound to this protocol
|
|
405
|
+
*/
|
|
406
|
+
schema() {
|
|
407
|
+
return new SchemaBuilder(this.#spec.name, this.#handle, this.#wasm);
|
|
408
|
+
}
|
|
409
|
+
/** Release the WASM-side protocol resource. */
|
|
410
|
+
[Symbol.dispose]() {
|
|
411
|
+
this.#handle[Symbol.dispose]();
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function defineProtocol(spec, wasm) {
|
|
415
|
+
const wireSpec = {
|
|
416
|
+
name: spec.name,
|
|
417
|
+
schema_theory: spec.schemaTheory,
|
|
418
|
+
instance_theory: spec.instanceTheory,
|
|
419
|
+
edge_rules: spec.edgeRules.map((r) => ({
|
|
420
|
+
edge_kind: r.edgeKind,
|
|
421
|
+
src_kinds: [...r.srcKinds],
|
|
422
|
+
tgt_kinds: [...r.tgtKinds]
|
|
423
|
+
})),
|
|
424
|
+
obj_kinds: [...spec.objKinds],
|
|
425
|
+
constraint_sorts: [...spec.constraintSorts]
|
|
426
|
+
};
|
|
427
|
+
try {
|
|
428
|
+
const bytes = packToWasm(wireSpec);
|
|
429
|
+
const rawHandle = wasm.exports.define_protocol(bytes);
|
|
430
|
+
const handle = createHandle(rawHandle, wasm);
|
|
431
|
+
return new Protocol(handle, spec, wasm);
|
|
432
|
+
} catch (error) {
|
|
433
|
+
throw new PanprotoError(
|
|
434
|
+
`Failed to define protocol "${spec.name}": ${error instanceof Error ? error.message : String(error)}`,
|
|
435
|
+
{ cause: error }
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
const ATPROTO_SPEC = {
|
|
440
|
+
name: "atproto",
|
|
441
|
+
schemaTheory: "ThConstrainedMultiGraph",
|
|
442
|
+
instanceTheory: "ThWTypeMeta",
|
|
443
|
+
edgeRules: [
|
|
444
|
+
{ edgeKind: "record-schema", srcKinds: ["record"], tgtKinds: ["object"] },
|
|
445
|
+
{ edgeKind: "prop", srcKinds: ["object"], tgtKinds: [] },
|
|
446
|
+
{ edgeKind: "item", srcKinds: ["array"], tgtKinds: [] },
|
|
447
|
+
{ edgeKind: "variant", srcKinds: ["union"], tgtKinds: [] },
|
|
448
|
+
{ edgeKind: "ref", srcKinds: [], tgtKinds: ["record"] }
|
|
449
|
+
],
|
|
450
|
+
objKinds: ["record", "object"],
|
|
451
|
+
constraintSorts: ["maxLength", "minLength", "maxGraphemes", "minGraphemes", "format"]
|
|
452
|
+
};
|
|
453
|
+
const SQL_SPEC = {
|
|
454
|
+
name: "sql",
|
|
455
|
+
schemaTheory: "ThConstrainedHypergraph",
|
|
456
|
+
instanceTheory: "ThFunctor",
|
|
457
|
+
edgeRules: [
|
|
458
|
+
{ edgeKind: "column", srcKinds: ["table"], tgtKinds: ["type"] },
|
|
459
|
+
{ edgeKind: "fk", srcKinds: ["table"], tgtKinds: ["table"] },
|
|
460
|
+
{ edgeKind: "pk", srcKinds: ["table"], tgtKinds: ["column"] }
|
|
461
|
+
],
|
|
462
|
+
objKinds: ["table"],
|
|
463
|
+
constraintSorts: ["nullable", "unique", "check", "default"]
|
|
464
|
+
};
|
|
465
|
+
const PROTOBUF_SPEC = {
|
|
466
|
+
name: "protobuf",
|
|
467
|
+
schemaTheory: "ThConstrainedGraph",
|
|
468
|
+
instanceTheory: "ThWType",
|
|
469
|
+
edgeRules: [
|
|
470
|
+
{ edgeKind: "field", srcKinds: ["message"], tgtKinds: [] },
|
|
471
|
+
{ edgeKind: "nested", srcKinds: ["message"], tgtKinds: ["message", "enum"] },
|
|
472
|
+
{ edgeKind: "value", srcKinds: ["enum"], tgtKinds: ["enum-value"] }
|
|
473
|
+
],
|
|
474
|
+
objKinds: ["message"],
|
|
475
|
+
constraintSorts: ["field-number", "repeated", "optional", "map-key", "map-value"]
|
|
476
|
+
};
|
|
477
|
+
const GRAPHQL_SPEC = {
|
|
478
|
+
name: "graphql",
|
|
479
|
+
schemaTheory: "ThConstrainedGraph",
|
|
480
|
+
instanceTheory: "ThWType",
|
|
481
|
+
edgeRules: [
|
|
482
|
+
{ edgeKind: "field", srcKinds: ["type", "input"], tgtKinds: [] },
|
|
483
|
+
{ edgeKind: "implements", srcKinds: ["type"], tgtKinds: ["interface"] },
|
|
484
|
+
{ edgeKind: "member", srcKinds: ["union"], tgtKinds: ["type"] },
|
|
485
|
+
{ edgeKind: "value", srcKinds: ["enum"], tgtKinds: ["enum-value"] }
|
|
486
|
+
],
|
|
487
|
+
objKinds: ["type", "input"],
|
|
488
|
+
constraintSorts: ["non-null", "list", "deprecated"]
|
|
489
|
+
};
|
|
490
|
+
const JSON_SCHEMA_SPEC = {
|
|
491
|
+
name: "json-schema",
|
|
492
|
+
schemaTheory: "ThConstrainedGraph",
|
|
493
|
+
instanceTheory: "ThWType",
|
|
494
|
+
edgeRules: [
|
|
495
|
+
{ edgeKind: "property", srcKinds: ["object"], tgtKinds: [] },
|
|
496
|
+
{ edgeKind: "item", srcKinds: ["array"], tgtKinds: [] },
|
|
497
|
+
{ edgeKind: "variant", srcKinds: ["oneOf", "anyOf"], tgtKinds: [] }
|
|
498
|
+
],
|
|
499
|
+
objKinds: ["object"],
|
|
500
|
+
constraintSorts: ["minLength", "maxLength", "minimum", "maximum", "pattern", "format", "required"]
|
|
501
|
+
};
|
|
502
|
+
const BUILTIN_PROTOCOLS = /* @__PURE__ */ new Map([
|
|
503
|
+
["atproto", ATPROTO_SPEC],
|
|
504
|
+
["sql", SQL_SPEC],
|
|
505
|
+
["protobuf", PROTOBUF_SPEC],
|
|
506
|
+
["graphql", GRAPHQL_SPEC],
|
|
507
|
+
["json-schema", JSON_SCHEMA_SPEC]
|
|
508
|
+
]);
|
|
509
|
+
class MigrationBuilder {
|
|
510
|
+
#src;
|
|
511
|
+
#tgt;
|
|
512
|
+
#wasm;
|
|
513
|
+
#vertexMap;
|
|
514
|
+
#edgeMap;
|
|
515
|
+
#resolvers;
|
|
516
|
+
constructor(src, tgt, wasm, vertexMap = /* @__PURE__ */ new Map(), edgeMap = [], resolvers = []) {
|
|
517
|
+
this.#src = src;
|
|
518
|
+
this.#tgt = tgt;
|
|
519
|
+
this.#wasm = wasm;
|
|
520
|
+
this.#vertexMap = vertexMap;
|
|
521
|
+
this.#edgeMap = edgeMap;
|
|
522
|
+
this.#resolvers = resolvers;
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Map a source vertex to a target vertex.
|
|
526
|
+
*
|
|
527
|
+
* @param srcVertex - Vertex id in the source schema
|
|
528
|
+
* @param tgtVertex - Vertex id in the target schema
|
|
529
|
+
* @returns A new builder with the mapping added
|
|
530
|
+
*/
|
|
531
|
+
map(srcVertex, tgtVertex) {
|
|
532
|
+
const newMap = new Map(this.#vertexMap);
|
|
533
|
+
newMap.set(srcVertex, tgtVertex);
|
|
534
|
+
return new MigrationBuilder(
|
|
535
|
+
this.#src,
|
|
536
|
+
this.#tgt,
|
|
537
|
+
this.#wasm,
|
|
538
|
+
newMap,
|
|
539
|
+
this.#edgeMap,
|
|
540
|
+
this.#resolvers
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Map a source edge to a target edge.
|
|
545
|
+
*
|
|
546
|
+
* @param srcEdge - Edge in the source schema
|
|
547
|
+
* @param tgtEdge - Edge in the target schema
|
|
548
|
+
* @returns A new builder with the edge mapping added
|
|
549
|
+
*/
|
|
550
|
+
mapEdge(srcEdge, tgtEdge) {
|
|
551
|
+
return new MigrationBuilder(
|
|
552
|
+
this.#src,
|
|
553
|
+
this.#tgt,
|
|
554
|
+
this.#wasm,
|
|
555
|
+
this.#vertexMap,
|
|
556
|
+
[...this.#edgeMap, [srcEdge, tgtEdge]],
|
|
557
|
+
this.#resolvers
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Add a resolver for ancestor contraction ambiguity.
|
|
562
|
+
*
|
|
563
|
+
* When a migration contracts nodes and the resulting edge between
|
|
564
|
+
* two vertex kinds is ambiguous, a resolver specifies which edge to use.
|
|
565
|
+
*
|
|
566
|
+
* @param srcKind - Source vertex kind in the contracted pair
|
|
567
|
+
* @param tgtKind - Target vertex kind in the contracted pair
|
|
568
|
+
* @param resolvedEdge - The edge to use for this pair
|
|
569
|
+
* @returns A new builder with the resolver added
|
|
570
|
+
*/
|
|
571
|
+
resolve(srcKind, tgtKind, resolvedEdge) {
|
|
572
|
+
return new MigrationBuilder(
|
|
573
|
+
this.#src,
|
|
574
|
+
this.#tgt,
|
|
575
|
+
this.#wasm,
|
|
576
|
+
this.#vertexMap,
|
|
577
|
+
this.#edgeMap,
|
|
578
|
+
[...this.#resolvers, [[srcKind, tgtKind], resolvedEdge]]
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* Get the current migration specification.
|
|
583
|
+
*
|
|
584
|
+
* @returns The migration spec with all accumulated mappings
|
|
585
|
+
*/
|
|
586
|
+
toSpec() {
|
|
587
|
+
return {
|
|
588
|
+
vertexMap: Object.fromEntries(this.#vertexMap),
|
|
589
|
+
edgeMap: [...this.#edgeMap],
|
|
590
|
+
resolvers: [...this.#resolvers]
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Compile the migration for fast per-record application.
|
|
595
|
+
*
|
|
596
|
+
* Sends the migration specification to WASM for compilation.
|
|
597
|
+
* The resulting `CompiledMigration` can be used to transform records.
|
|
598
|
+
*
|
|
599
|
+
* @returns A compiled migration ready for record transformation
|
|
600
|
+
* @throws {@link MigrationError} if compilation fails
|
|
601
|
+
*/
|
|
602
|
+
compile() {
|
|
603
|
+
const mapping = packMigrationMapping({
|
|
604
|
+
vertex_map: Object.fromEntries(this.#vertexMap),
|
|
605
|
+
edge_map: this.#edgeMap.map(([src, tgt]) => [
|
|
606
|
+
{ src: src.src, tgt: src.tgt, kind: src.kind, name: src.name ?? null },
|
|
607
|
+
{ src: tgt.src, tgt: tgt.tgt, kind: tgt.kind, name: tgt.name ?? null }
|
|
608
|
+
]),
|
|
609
|
+
resolver: this.#resolvers.map(([[s, t], e]) => [
|
|
610
|
+
[s, t],
|
|
611
|
+
{ src: e.src, tgt: e.tgt, kind: e.kind, name: e.name ?? null }
|
|
612
|
+
])
|
|
613
|
+
});
|
|
614
|
+
try {
|
|
615
|
+
const rawHandle = this.#wasm.exports.compile_migration(
|
|
616
|
+
this.#src._handle.id,
|
|
617
|
+
this.#tgt._handle.id,
|
|
618
|
+
mapping
|
|
619
|
+
);
|
|
620
|
+
const handle = createHandle(rawHandle, this.#wasm);
|
|
621
|
+
return new CompiledMigration(handle, this.#wasm, this.toSpec());
|
|
622
|
+
} catch (error) {
|
|
623
|
+
throw new MigrationError(
|
|
624
|
+
`Failed to compile migration: ${error instanceof Error ? error.message : String(error)}`,
|
|
625
|
+
{ cause: error }
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
class CompiledMigration {
|
|
631
|
+
#handle;
|
|
632
|
+
#wasm;
|
|
633
|
+
#spec;
|
|
634
|
+
constructor(handle, wasm, spec) {
|
|
635
|
+
this.#handle = handle;
|
|
636
|
+
this.#wasm = wasm;
|
|
637
|
+
this.#spec = spec;
|
|
638
|
+
}
|
|
639
|
+
/** The WASM handle for this migration. Internal use only. */
|
|
640
|
+
get _handle() {
|
|
641
|
+
return this.#handle;
|
|
642
|
+
}
|
|
643
|
+
/** The migration specification used to build this migration. */
|
|
644
|
+
get spec() {
|
|
645
|
+
return this.#spec;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Transform a record using this migration (forward direction).
|
|
649
|
+
*
|
|
650
|
+
* This is the hot path: data goes through WASM as MessagePack bytes
|
|
651
|
+
* with no intermediate JS-heap allocation.
|
|
652
|
+
*
|
|
653
|
+
* @param record - The input record to transform
|
|
654
|
+
* @returns The transformed record
|
|
655
|
+
* @throws {@link WasmError} if the WASM call fails
|
|
656
|
+
*/
|
|
657
|
+
lift(record) {
|
|
658
|
+
const inputBytes = packToWasm(record);
|
|
659
|
+
try {
|
|
660
|
+
const outputBytes = this.#wasm.exports.lift_record(
|
|
661
|
+
this.#handle.id,
|
|
662
|
+
inputBytes
|
|
663
|
+
);
|
|
664
|
+
const data = unpackFromWasm(outputBytes);
|
|
665
|
+
return { data };
|
|
666
|
+
} catch (error) {
|
|
667
|
+
throw new WasmError(
|
|
668
|
+
`lift_record failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
669
|
+
{ cause: error }
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Bidirectional get: extract view and complement from a record.
|
|
675
|
+
*
|
|
676
|
+
* The complement captures data discarded by the forward projection,
|
|
677
|
+
* enabling lossless round-tripping via `put()`.
|
|
678
|
+
*
|
|
679
|
+
* @param record - The input record
|
|
680
|
+
* @returns The projected view and opaque complement bytes
|
|
681
|
+
* @throws {@link WasmError} if the WASM call fails
|
|
682
|
+
*/
|
|
683
|
+
get(record) {
|
|
684
|
+
const inputBytes = packToWasm(record);
|
|
685
|
+
try {
|
|
686
|
+
const outputBytes = this.#wasm.exports.get_record(
|
|
687
|
+
this.#handle.id,
|
|
688
|
+
inputBytes
|
|
689
|
+
);
|
|
690
|
+
const result = unpackFromWasm(outputBytes);
|
|
691
|
+
return {
|
|
692
|
+
view: result.view,
|
|
693
|
+
complement: result.complement instanceof Uint8Array ? result.complement : new Uint8Array(result.complement)
|
|
694
|
+
};
|
|
695
|
+
} catch (error) {
|
|
696
|
+
throw new WasmError(
|
|
697
|
+
`get_record failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
698
|
+
{ cause: error }
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
/**
|
|
703
|
+
* Bidirectional put: restore a full record from a modified view and complement.
|
|
704
|
+
*
|
|
705
|
+
* @param view - The (possibly modified) projected view
|
|
706
|
+
* @param complement - The complement from a prior `get()` call
|
|
707
|
+
* @returns The restored full record
|
|
708
|
+
* @throws {@link WasmError} if the WASM call fails
|
|
709
|
+
*/
|
|
710
|
+
put(view, complement) {
|
|
711
|
+
const viewBytes = packToWasm(view);
|
|
712
|
+
try {
|
|
713
|
+
const outputBytes = this.#wasm.exports.put_record(
|
|
714
|
+
this.#handle.id,
|
|
715
|
+
viewBytes,
|
|
716
|
+
complement
|
|
717
|
+
);
|
|
718
|
+
const data = unpackFromWasm(outputBytes);
|
|
719
|
+
return { data };
|
|
720
|
+
} catch (error) {
|
|
721
|
+
throw new WasmError(
|
|
722
|
+
`put_record failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
723
|
+
{ cause: error }
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
/** Release the WASM-side compiled migration resource. */
|
|
728
|
+
[Symbol.dispose]() {
|
|
729
|
+
this.#handle[Symbol.dispose]();
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
function checkExistence(src, tgt, spec, wasm) {
|
|
733
|
+
const mapping = packMigrationMapping({
|
|
734
|
+
vertex_map: spec.vertexMap,
|
|
735
|
+
edge_map: spec.edgeMap.map(([s, t]) => [
|
|
736
|
+
{ src: s.src, tgt: s.tgt, kind: s.kind, name: s.name ?? null },
|
|
737
|
+
{ src: t.src, tgt: t.tgt, kind: t.kind, name: t.name ?? null }
|
|
738
|
+
]),
|
|
739
|
+
resolver: spec.resolvers.map(([[s, t], e]) => [
|
|
740
|
+
[s, t],
|
|
741
|
+
{ src: e.src, tgt: e.tgt, kind: e.kind, name: e.name ?? null }
|
|
742
|
+
])
|
|
743
|
+
});
|
|
744
|
+
const resultBytes = wasm.exports.check_existence(
|
|
745
|
+
src._handle.id,
|
|
746
|
+
tgt._handle.id,
|
|
747
|
+
mapping
|
|
748
|
+
);
|
|
749
|
+
return unpackFromWasm(resultBytes);
|
|
750
|
+
}
|
|
751
|
+
function composeMigrations(m1, m2, wasm) {
|
|
752
|
+
try {
|
|
753
|
+
const rawHandle = wasm.exports.compose_migrations(
|
|
754
|
+
m1._handle.id,
|
|
755
|
+
m2._handle.id
|
|
756
|
+
);
|
|
757
|
+
const handle = createHandle(rawHandle, wasm);
|
|
758
|
+
const composedVertexMap = {};
|
|
759
|
+
for (const [src, intermediate] of Object.entries(m1.spec.vertexMap)) {
|
|
760
|
+
const final_ = m2.spec.vertexMap[intermediate];
|
|
761
|
+
composedVertexMap[src] = final_ ?? intermediate;
|
|
762
|
+
}
|
|
763
|
+
const composedSpec = {
|
|
764
|
+
vertexMap: composedVertexMap,
|
|
765
|
+
edgeMap: [...m1.spec.edgeMap, ...m2.spec.edgeMap],
|
|
766
|
+
resolvers: [...m1.spec.resolvers, ...m2.spec.resolvers]
|
|
767
|
+
};
|
|
768
|
+
return new CompiledMigration(handle, wasm, composedSpec);
|
|
769
|
+
} catch (error) {
|
|
770
|
+
throw new MigrationError(
|
|
771
|
+
`Failed to compose migrations: ${error instanceof Error ? error.message : String(error)}`,
|
|
772
|
+
{ cause: error }
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
class Panproto {
|
|
777
|
+
#wasm;
|
|
778
|
+
#protocols;
|
|
779
|
+
constructor(wasm) {
|
|
780
|
+
this.#wasm = wasm;
|
|
781
|
+
this.#protocols = /* @__PURE__ */ new Map();
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Initialize the panproto SDK by loading the WASM module.
|
|
785
|
+
*
|
|
786
|
+
* @param wasmUrl - Optional URL or path to the WASM binary.
|
|
787
|
+
* Defaults to the bundled binary.
|
|
788
|
+
* @returns An initialized Panproto instance
|
|
789
|
+
* @throws {@link import('./types.js').WasmError} if WASM loading fails
|
|
790
|
+
*/
|
|
791
|
+
static async init(wasmUrl) {
|
|
792
|
+
const wasm = await loadWasm(wasmUrl);
|
|
793
|
+
return new Panproto(wasm);
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Get or register a protocol by name.
|
|
797
|
+
*
|
|
798
|
+
* If the protocol is a built-in (e.g., 'atproto', 'sql'), it is
|
|
799
|
+
* automatically registered on first access. Custom protocols must
|
|
800
|
+
* be registered first with {@link Panproto.defineProtocol}.
|
|
801
|
+
*
|
|
802
|
+
* @param name - The protocol name
|
|
803
|
+
* @returns The protocol instance
|
|
804
|
+
* @throws {@link PanprotoError} if the protocol is not found
|
|
805
|
+
*/
|
|
806
|
+
protocol(name) {
|
|
807
|
+
const cached = this.#protocols.get(name);
|
|
808
|
+
if (cached) return cached;
|
|
809
|
+
const builtinSpec = BUILTIN_PROTOCOLS.get(name);
|
|
810
|
+
if (builtinSpec) {
|
|
811
|
+
const proto = defineProtocol(builtinSpec, this.#wasm);
|
|
812
|
+
this.#protocols.set(name, proto);
|
|
813
|
+
return proto;
|
|
814
|
+
}
|
|
815
|
+
throw new PanprotoError(
|
|
816
|
+
`Protocol "${name}" not found. Register it with defineProtocol() first.`
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Define and register a custom protocol.
|
|
821
|
+
*
|
|
822
|
+
* @param spec - The protocol specification
|
|
823
|
+
* @returns The registered protocol
|
|
824
|
+
* @throws {@link PanprotoError} if registration fails
|
|
825
|
+
*/
|
|
826
|
+
defineProtocol(spec) {
|
|
827
|
+
const proto = defineProtocol(spec, this.#wasm);
|
|
828
|
+
this.#protocols.set(spec.name, proto);
|
|
829
|
+
return proto;
|
|
830
|
+
}
|
|
831
|
+
/**
|
|
832
|
+
* Start building a migration between two schemas.
|
|
833
|
+
*
|
|
834
|
+
* @param src - The source schema
|
|
835
|
+
* @param tgt - The target schema
|
|
836
|
+
* @returns A migration builder
|
|
837
|
+
*/
|
|
838
|
+
migration(src, tgt) {
|
|
839
|
+
return new MigrationBuilder(src, tgt, this.#wasm);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Check existence conditions for a proposed migration.
|
|
843
|
+
*
|
|
844
|
+
* Verifies that the migration specification satisfies all
|
|
845
|
+
* protocol-derived constraints (edge coverage, kind consistency,
|
|
846
|
+
* required fields, etc.).
|
|
847
|
+
*
|
|
848
|
+
* @param src - The source schema
|
|
849
|
+
* @param tgt - The target schema
|
|
850
|
+
* @param builder - The migration builder with mappings
|
|
851
|
+
* @returns The existence report
|
|
852
|
+
*/
|
|
853
|
+
checkExistence(src, tgt, builder) {
|
|
854
|
+
return checkExistence(src, tgt, builder.toSpec(), this.#wasm);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Compose two compiled migrations into a single migration.
|
|
858
|
+
*
|
|
859
|
+
* The resulting migration is equivalent to applying `m1` then `m2`.
|
|
860
|
+
*
|
|
861
|
+
* @param m1 - First migration (applied first)
|
|
862
|
+
* @param m2 - Second migration (applied second)
|
|
863
|
+
* @returns The composed migration
|
|
864
|
+
* @throws {@link import('./types.js').MigrationError} if composition fails
|
|
865
|
+
*/
|
|
866
|
+
compose(m1, m2) {
|
|
867
|
+
return composeMigrations(m1, m2, this.#wasm);
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Diff two schemas and produce a compatibility report.
|
|
871
|
+
*
|
|
872
|
+
* @param oldSchema - The old/source schema
|
|
873
|
+
* @param newSchema - The new/target schema
|
|
874
|
+
* @returns A diff report with changes and compatibility classification
|
|
875
|
+
*/
|
|
876
|
+
diff(oldSchema, newSchema) {
|
|
877
|
+
const resultBytes = this.#wasm.exports.diff_schemas(
|
|
878
|
+
oldSchema._handle.id,
|
|
879
|
+
newSchema._handle.id
|
|
880
|
+
);
|
|
881
|
+
return unpackFromWasm(resultBytes);
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Release all WASM resources held by this instance.
|
|
885
|
+
*
|
|
886
|
+
* Disposes all cached protocols. After disposal, this instance
|
|
887
|
+
* must not be used.
|
|
888
|
+
*/
|
|
889
|
+
[Symbol.dispose]() {
|
|
890
|
+
for (const proto of this.#protocols.values()) {
|
|
891
|
+
proto[Symbol.dispose]();
|
|
892
|
+
}
|
|
893
|
+
this.#protocols.clear();
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
function renameField(oldName, newName) {
|
|
897
|
+
return { type: "rename-field", old: oldName, new: newName };
|
|
898
|
+
}
|
|
899
|
+
function addField(name, vertexKind, defaultValue) {
|
|
900
|
+
return { type: "add-field", name, vertexKind, default: defaultValue };
|
|
901
|
+
}
|
|
902
|
+
function removeField(name) {
|
|
903
|
+
return { type: "remove-field", name };
|
|
904
|
+
}
|
|
905
|
+
function wrapInObject(fieldName) {
|
|
906
|
+
return { type: "wrap-in-object", fieldName };
|
|
907
|
+
}
|
|
908
|
+
function hoistField(host, field) {
|
|
909
|
+
return { type: "hoist-field", host, field };
|
|
910
|
+
}
|
|
911
|
+
function coerceType(fromKind, toKind) {
|
|
912
|
+
return { type: "coerce-type", fromKind, toKind };
|
|
913
|
+
}
|
|
914
|
+
function compose(first, second) {
|
|
915
|
+
return { type: "compose", first, second };
|
|
916
|
+
}
|
|
917
|
+
function pipeline(combinators) {
|
|
918
|
+
return combinators.reduce((acc, c) => compose(acc, c));
|
|
919
|
+
}
|
|
920
|
+
exports.ATPROTO_SPEC = ATPROTO_SPEC;
|
|
921
|
+
exports.BUILTIN_PROTOCOLS = BUILTIN_PROTOCOLS;
|
|
922
|
+
exports.BuiltSchema = BuiltSchema;
|
|
923
|
+
exports.CompiledMigration = CompiledMigration;
|
|
924
|
+
exports.ExistenceCheckError = ExistenceCheckError;
|
|
925
|
+
exports.GRAPHQL_SPEC = GRAPHQL_SPEC;
|
|
926
|
+
exports.JSON_SCHEMA_SPEC = JSON_SCHEMA_SPEC;
|
|
927
|
+
exports.MigrationBuilder = MigrationBuilder;
|
|
928
|
+
exports.MigrationError = MigrationError;
|
|
929
|
+
exports.PROTOBUF_SPEC = PROTOBUF_SPEC;
|
|
930
|
+
exports.Panproto = Panproto;
|
|
931
|
+
exports.PanprotoError = PanprotoError;
|
|
932
|
+
exports.Protocol = Protocol;
|
|
933
|
+
exports.SQL_SPEC = SQL_SPEC;
|
|
934
|
+
exports.SchemaBuilder = SchemaBuilder;
|
|
935
|
+
exports.SchemaValidationError = SchemaValidationError;
|
|
936
|
+
exports.WasmError = WasmError;
|
|
937
|
+
exports.addField = addField;
|
|
938
|
+
exports.coerceType = coerceType;
|
|
939
|
+
exports.compose = compose;
|
|
940
|
+
exports.hoistField = hoistField;
|
|
941
|
+
exports.pipeline = pipeline;
|
|
942
|
+
exports.removeField = removeField;
|
|
943
|
+
exports.renameField = renameField;
|
|
944
|
+
exports.wrapInObject = wrapInObject;
|
|
945
|
+
//# sourceMappingURL=index.cjs.map
|