@panproto/core 0.5.1 → 0.7.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/dist/index.d.ts CHANGED
@@ -24,16 +24,18 @@ export { Protocol } from './protocol.js';
24
24
  export { ATPROTO_SPEC, SQL_SPEC, PROTOBUF_SPEC, GRAPHQL_SPEC, JSON_SCHEMA_SPEC, BUILTIN_PROTOCOLS, getProtocolNames, getBuiltinProtocol, } from './protocol.js';
25
25
  export { SchemaBuilder, BuiltSchema } from './schema.js';
26
26
  export { MigrationBuilder, CompiledMigration } from './migration.js';
27
- export { renameField, addField, removeField, wrapInObject, hoistField, coerceType, compose, pipeline, LensHandle, fromCombinators, } from './lens.js';
28
- export type { Combinator, RenameFieldCombinator, AddFieldCombinator, RemoveFieldCombinator, WrapInObjectCombinator, HoistFieldCombinator, CoerceTypeCombinator, ComposeCombinator, } from './lens.js';
27
+ export { LensHandle, ProtolensChainHandle, SymmetricLensHandle, } from './lens.js';
28
+ export type { SchemaTransform, ProtolensSpec, ProtolensChainSpec, ComplementSpec, DefaultRequirement, CapturedField, ElementaryStep, NaturalityResult, } from './protolens.js';
29
29
  export { Instance } from './instance.js';
30
30
  export { IoRegistry, PROTOCOL_CATEGORIES } from './io.js';
31
31
  export { FullDiffReport, CompatReport, ValidationResult } from './check.js';
32
32
  export type { FullSchemaDiff, CompatReportData, BreakingChange, NonBreakingChange, ConstraintChange, ConstraintDiff, KindChange, SchemaValidationIssue, } from './types.js';
33
33
  export type { LawCheckResult, ProtocolSpec, EdgeRule, Vertex, Edge, HyperEdge, Constraint, Variant, RecursionPoint, UsageMode, Span, VertexOptions, EdgeOptions, SchemaData, MigrationSpec, LiftResult, GetResult, DiffReport, SchemaChange, Compatibility, ExistenceReport, ExistenceError, WasmModule, WasmExports, InstanceShape, InstanceValidationResult, } from './types.js';
34
- export { TheoryHandle, TheoryBuilder, createTheory, colimit, checkMorphism, migrateModel, } from './gat.js';
34
+ export { TheoryHandle, TheoryBuilder, createTheory, colimit, checkMorphism, migrateModel, factorizeMorphism, } from './gat.js';
35
35
  export type { TheorySpec, TheoryMorphism, Sort, SortParam, GatOperation, Equation, Term, MorphismCheckResult, } from './types.js';
36
36
  export { Repository } from './vcs.js';
37
+ export { DataSetHandle } from './data.js';
38
+ export type { MigrationResult, StalenessResult } from './data.js';
37
39
  export type { VcsLogEntry, VcsStatus, VcsOpResult, VcsBlameResult, } from './types.js';
38
40
  export type { WasmGlueModule } from './wasm.js';
39
41
  export { PanprotoError, WasmError, SchemaValidationError, MigrationError, ExistenceCheckError, } from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,WAAW,EACX,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,QAAQ,EACR,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,UAAU,EACV,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5E,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,SAAS,EACT,UAAU,EACV,OAAO,EACP,cAAc,EACd,SAAS,EACT,IAAI,EACJ,aAAa,EACb,WAAW,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,EACV,WAAW,EACX,aAAa,EACb,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,OAAO,EACP,aAAa,EACb,YAAY,GACb,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,UAAU,EACV,cAAc,EACd,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EACL,aAAa,EACb,SAAS,EACT,qBAAqB,EACrB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5E,YAAY,EACV,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,qBAAqB,GACtB,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,SAAS,EACT,UAAU,EACV,OAAO,EACP,cAAc,EACd,SAAS,EACT,IAAI,EACJ,aAAa,EACb,WAAW,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,EACd,UAAU,EACV,WAAW,EACX,aAAa,EACb,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,OAAO,EACP,aAAa,EACb,YAAY,EACZ,iBAAiB,GAClB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,UAAU,EACV,cAAc,EACd,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,YAAY,EACV,WAAW,EACX,SAAS,EACT,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,OAAO,EACL,aAAa,EACb,SAAS,EACT,qBAAqB,EACrB,cAAc,EACd,mBAAmB,GACpB,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -68,7 +68,21 @@ async function loadWasm(input) {
68
68
  get_json: glue.get_json,
69
69
  put_json: glue.put_json,
70
70
  instance_element_count: glue.instance_element_count,
71
- lens_from_combinators: glue.lens_from_combinators,
71
+ auto_generate_protolens: glue.auto_generate_protolens,
72
+ instantiate_protolens: glue.instantiate_protolens,
73
+ protolens_complement_spec: glue.protolens_complement_spec,
74
+ protolens_from_diff: glue.protolens_from_diff,
75
+ protolens_compose: glue.protolens_compose,
76
+ protolens_chain_to_json: glue.protolens_chain_to_json,
77
+ factorize_morphism: glue.factorize_morphism,
78
+ symmetric_lens_from_schemas: glue.symmetric_lens_from_schemas,
79
+ symmetric_lens_sync: glue.symmetric_lens_sync,
80
+ apply_protolens_step: glue.apply_protolens_step,
81
+ protolens_from_json: glue.protolens_from_json,
82
+ protolens_fuse: glue.protolens_fuse,
83
+ protolens_lift: glue.protolens_lift,
84
+ protolens_check_applicability: glue.protolens_check_applicability,
85
+ protolens_fleet: glue.protolens_fleet,
72
86
  check_lens_laws: glue.check_lens_laws,
73
87
  check_get_put: glue.check_get_put,
74
88
  check_put_get: glue.check_put_get,
@@ -94,7 +108,16 @@ async function loadWasm(input) {
94
108
  vcs_merge: glue.vcs_merge,
95
109
  vcs_stash: glue.vcs_stash,
96
110
  vcs_stash_pop: glue.vcs_stash_pop,
97
- vcs_blame: glue.vcs_blame
111
+ vcs_blame: glue.vcs_blame,
112
+ // Phase 7: Data versioning
113
+ store_dataset: glue.store_dataset,
114
+ get_dataset: glue.get_dataset,
115
+ migrate_dataset_forward: glue.migrate_dataset_forward,
116
+ migrate_dataset_backward: glue.migrate_dataset_backward,
117
+ check_dataset_staleness: glue.check_dataset_staleness,
118
+ store_protocol_definition: glue.store_protocol_definition,
119
+ get_protocol_definition: glue.get_protocol_definition,
120
+ get_migration_complement: glue.get_migration_complement
98
121
  };
99
122
  const memory = initOutput.memory;
100
123
  if (!memory) {
@@ -168,30 +191,212 @@ function packMigrationMapping(mapping) {
168
191
  hyper_resolver: []
169
192
  });
170
193
  }
171
- function renameField(oldName, newName) {
172
- return { type: "rename-field", old: oldName, new: newName };
173
- }
174
- function addField(name, vertexKind, defaultValue) {
175
- return { type: "add-field", name, vertexKind, default: defaultValue };
176
- }
177
- function removeField(name) {
178
- return { type: "remove-field", name };
179
- }
180
- function wrapInObject(fieldName) {
181
- return { type: "wrap-in-object", fieldName };
182
- }
183
- function hoistField(host, field) {
184
- return { type: "hoist-field", host, field };
185
- }
186
- function coerceType(fromKind, toKind) {
187
- return { type: "coerce-type", fromKind, toKind };
188
- }
189
- function compose(first, second) {
190
- return { type: "compose", first, second };
191
- }
192
- function pipeline(combinators) {
193
- const [first, ...rest] = combinators;
194
- return rest.reduce((acc, c) => compose(acc, c), first);
194
+ class ProtolensChainHandle {
195
+ #handle;
196
+ #wasm;
197
+ constructor(handle, wasm) {
198
+ this.#handle = handle;
199
+ this.#wasm = wasm;
200
+ }
201
+ /** The underlying WASM handle. Internal use only. */
202
+ get _handle() {
203
+ return this.#handle;
204
+ }
205
+ /**
206
+ * Auto-generate a protolens chain between two schemas.
207
+ *
208
+ * @param schema1 - The source schema
209
+ * @param schema2 - The target schema
210
+ * @param wasm - The WASM module
211
+ * @returns A ProtolensChainHandle wrapping the generated chain
212
+ * @throws {@link WasmError} if the WASM call fails
213
+ */
214
+ static autoGenerate(schema1, schema2, wasm) {
215
+ try {
216
+ const rawHandle = wasm.exports.auto_generate_protolens(schema1._handle.id, schema2._handle.id);
217
+ return new ProtolensChainHandle(createHandle(rawHandle, wasm), wasm);
218
+ } catch (error) {
219
+ throw new WasmError(
220
+ `auto_generate_protolens failed: ${error instanceof Error ? error.message : String(error)}`,
221
+ { cause: error }
222
+ );
223
+ }
224
+ }
225
+ /**
226
+ * Instantiate this protolens chain against a concrete schema.
227
+ *
228
+ * @param schema - The schema to instantiate against
229
+ * @returns A LensHandle for the instantiated lens
230
+ * @throws {@link WasmError} if the WASM call fails
231
+ */
232
+ instantiate(schema) {
233
+ try {
234
+ const rawHandle = this.#wasm.exports.instantiate_protolens(this.#handle.id, schema._handle.id);
235
+ return new LensHandle(createHandle(rawHandle, this.#wasm), this.#wasm);
236
+ } catch (error) {
237
+ throw new WasmError(
238
+ `instantiate_protolens failed: ${error instanceof Error ? error.message : String(error)}`,
239
+ { cause: error }
240
+ );
241
+ }
242
+ }
243
+ /**
244
+ * Get the complement specification for instantiation against a schema.
245
+ *
246
+ * @param schema - The schema to check requirements against
247
+ * @returns The complement spec describing defaults and captured data
248
+ * @throws {@link WasmError} if the WASM call fails
249
+ */
250
+ requirements(schema) {
251
+ try {
252
+ const bytes = this.#wasm.exports.protolens_complement_spec(this.#handle.id, schema._handle.id);
253
+ return unpackFromWasm(bytes);
254
+ } catch (error) {
255
+ throw new WasmError(
256
+ `protolens_complement_spec failed: ${error instanceof Error ? error.message : String(error)}`,
257
+ { cause: error }
258
+ );
259
+ }
260
+ }
261
+ /**
262
+ * Compose this chain with another protolens chain.
263
+ *
264
+ * @param other - The chain to compose with (applied second)
265
+ * @returns A new ProtolensChainHandle for the composed chain
266
+ * @throws {@link WasmError} if the WASM call fails
267
+ */
268
+ compose(other) {
269
+ try {
270
+ const rawHandle = this.#wasm.exports.protolens_compose(this.#handle.id, other.#handle.id);
271
+ return new ProtolensChainHandle(createHandle(rawHandle, this.#wasm), this.#wasm);
272
+ } catch (error) {
273
+ throw new WasmError(
274
+ `protolens_compose failed: ${error instanceof Error ? error.message : String(error)}`,
275
+ { cause: error }
276
+ );
277
+ }
278
+ }
279
+ /**
280
+ * Serialize this chain to a JSON string.
281
+ *
282
+ * @returns A JSON representation of the chain
283
+ * @throws {@link WasmError} if the WASM call fails
284
+ */
285
+ toJson() {
286
+ try {
287
+ const bytes = this.#wasm.exports.protolens_chain_to_json(this.#handle.id);
288
+ return new TextDecoder().decode(bytes);
289
+ } catch (error) {
290
+ throw new WasmError(
291
+ `protolens_chain_to_json failed: ${error instanceof Error ? error.message : String(error)}`,
292
+ { cause: error }
293
+ );
294
+ }
295
+ }
296
+ /**
297
+ * Deserialize a protolens chain from JSON via WASM.
298
+ *
299
+ * @param json - JSON string representing a protolens chain
300
+ * @param wasm - The WASM module
301
+ * @returns A ProtolensChainHandle wrapping the deserialized chain
302
+ * @throws {@link WasmError} if the WASM call fails or JSON is invalid
303
+ */
304
+ static fromJson(json, wasm) {
305
+ try {
306
+ const jsonBytes = new TextEncoder().encode(json);
307
+ const rawHandle = wasm.exports.protolens_from_json(jsonBytes);
308
+ return new ProtolensChainHandle(createHandle(rawHandle, wasm), wasm);
309
+ } catch (error) {
310
+ throw new WasmError(
311
+ `protolens_from_json failed: ${error instanceof Error ? error.message : String(error)}`,
312
+ { cause: error }
313
+ );
314
+ }
315
+ }
316
+ /**
317
+ * Fuse this chain into a single protolens step.
318
+ *
319
+ * Composes all steps into a single step with a composite complement,
320
+ * avoiding intermediate schema materialization.
321
+ *
322
+ * @returns A new ProtolensChainHandle containing the fused step
323
+ * @throws {@link WasmError} if the WASM call fails
324
+ */
325
+ fuse() {
326
+ try {
327
+ const rawHandle = this.#wasm.exports.protolens_fuse(this.#handle.id);
328
+ return new ProtolensChainHandle(createHandle(rawHandle, this.#wasm), this.#wasm);
329
+ } catch (error) {
330
+ throw new WasmError(
331
+ `protolens_fuse failed: ${error instanceof Error ? error.message : String(error)}`,
332
+ { cause: error }
333
+ );
334
+ }
335
+ }
336
+ /**
337
+ * Check whether this chain can be instantiated at a given schema.
338
+ *
339
+ * @param schema - The schema to check against
340
+ * @returns An object with `applicable` boolean and `reasons` array
341
+ * @throws {@link WasmError} if the WASM call fails
342
+ */
343
+ checkApplicability(schema) {
344
+ try {
345
+ const bytes = this.#wasm.exports.protolens_check_applicability(this.#handle.id, schema._handle.id);
346
+ return unpackFromWasm(bytes);
347
+ } catch (error) {
348
+ throw new WasmError(
349
+ `protolens_check_applicability failed: ${error instanceof Error ? error.message : String(error)}`,
350
+ { cause: error }
351
+ );
352
+ }
353
+ }
354
+ /**
355
+ * Lift this chain along a theory morphism.
356
+ *
357
+ * Given a morphism between theories, produces a new chain that operates
358
+ * on schemas of the codomain theory instead of the domain theory.
359
+ *
360
+ * @param morphismBytes - MessagePack-encoded theory morphism
361
+ * @returns A new ProtolensChainHandle for the lifted chain
362
+ * @throws {@link WasmError} if the WASM call fails
363
+ */
364
+ lift(morphismBytes) {
365
+ try {
366
+ const rawHandle = this.#wasm.exports.protolens_lift(this.#handle.id, morphismBytes);
367
+ return new ProtolensChainHandle(createHandle(rawHandle, this.#wasm), this.#wasm);
368
+ } catch (error) {
369
+ throw new WasmError(
370
+ `protolens_lift failed: ${error instanceof Error ? error.message : String(error)}`,
371
+ { cause: error }
372
+ );
373
+ }
374
+ }
375
+ /**
376
+ * Apply this chain to a fleet of schemas.
377
+ *
378
+ * Checks applicability and instantiates the chain against each schema.
379
+ *
380
+ * @param schemas - Array of schema handles to apply the chain to
381
+ * @returns Fleet result with applied/skipped schema names and reasons
382
+ * @throws {@link WasmError} if the WASM call fails
383
+ */
384
+ applyToFleet(schemas) {
385
+ try {
386
+ const handles = new Uint32Array(schemas.map((s) => s._handle.id));
387
+ const bytes = this.#wasm.exports.protolens_fleet(this.#handle.id, handles);
388
+ return unpackFromWasm(bytes);
389
+ } catch (error) {
390
+ throw new WasmError(
391
+ `protolens_fleet failed: ${error instanceof Error ? error.message : String(error)}`,
392
+ { cause: error }
393
+ );
394
+ }
395
+ }
396
+ /** Release the underlying WASM resource. */
397
+ [Symbol.dispose]() {
398
+ this.#handle[Symbol.dispose]();
399
+ }
195
400
  }
196
401
  class LensHandle {
197
402
  #handle;
@@ -204,6 +409,53 @@ class LensHandle {
204
409
  get _handle() {
205
410
  return this.#handle;
206
411
  }
412
+ /**
413
+ * Auto-generate a lens between two schemas.
414
+ *
415
+ * Generates a protolens chain and immediately instantiates it.
416
+ *
417
+ * @param schema1 - The source schema
418
+ * @param schema2 - The target schema
419
+ * @param wasm - The WASM module
420
+ * @returns A LensHandle wrapping the generated lens
421
+ * @throws {@link WasmError} if the WASM call fails
422
+ */
423
+ static autoGenerate(schema1, schema2, wasm) {
424
+ try {
425
+ const rawHandle = wasm.exports.auto_generate_protolens(schema1._handle.id, schema2._handle.id);
426
+ const chainHandle = createHandle(rawHandle, wasm);
427
+ const lensRaw = wasm.exports.instantiate_protolens(chainHandle.id, schema1._handle.id);
428
+ chainHandle[Symbol.dispose]();
429
+ const handle = createHandle(lensRaw, wasm);
430
+ return new LensHandle(handle, wasm);
431
+ } catch (error) {
432
+ throw new WasmError(
433
+ `autoGenerate failed: ${error instanceof Error ? error.message : String(error)}`,
434
+ { cause: error }
435
+ );
436
+ }
437
+ }
438
+ /**
439
+ * Create a lens by instantiating a protolens chain against a schema.
440
+ *
441
+ * @param chain - The protolens chain to instantiate
442
+ * @param schema - The schema to instantiate against
443
+ * @param wasm - The WASM module
444
+ * @returns A LensHandle wrapping the instantiated lens
445
+ * @throws {@link WasmError} if the WASM call fails
446
+ */
447
+ static fromChain(chain, schema, wasm) {
448
+ try {
449
+ const rawHandle = wasm.exports.instantiate_protolens(chain._handle.id, schema._handle.id);
450
+ const handle = createHandle(rawHandle, wasm);
451
+ return new LensHandle(handle, wasm);
452
+ } catch (error) {
453
+ throw new WasmError(
454
+ `fromChain failed: ${error instanceof Error ? error.message : String(error)}`,
455
+ { cause: error }
456
+ );
457
+ }
458
+ }
207
459
  /**
208
460
  * Forward projection: extract the view from a record.
209
461
  *
@@ -321,40 +573,74 @@ class LensHandle {
321
573
  this.#handle[Symbol.dispose]();
322
574
  }
323
575
  }
324
- function fromCombinators(schema, protocol, wasm, ...combinators) {
325
- const wireCombs = combinators.map(combinatorToWire);
326
- const combBytes = packToWasm(wireCombs);
327
- try {
328
- const rawHandle = wasm.exports.lens_from_combinators(
329
- schema._handle.id,
330
- protocol._handle.id,
331
- combBytes
332
- );
333
- const handle = createHandle(rawHandle, wasm);
334
- return new LensHandle(handle, wasm);
335
- } catch (error) {
336
- throw new WasmError(
337
- `lens_from_combinators failed: ${error instanceof Error ? error.message : String(error)}`,
338
- { cause: error }
339
- );
576
+ class SymmetricLensHandle {
577
+ #handle;
578
+ #wasm;
579
+ constructor(handle, wasm) {
580
+ this.#handle = handle;
581
+ this.#wasm = wasm;
340
582
  }
341
- }
342
- function combinatorToWire(combinator) {
343
- switch (combinator.type) {
344
- case "rename-field":
345
- return { RenameField: { old: combinator.old, new: combinator.new } };
346
- case "add-field":
347
- return { AddField: { name: combinator.name, vertex_kind: combinator.vertexKind, default: combinator.default } };
348
- case "remove-field":
349
- return { RemoveField: { name: combinator.name } };
350
- case "wrap-in-object":
351
- return { WrapInObject: { field_name: combinator.fieldName } };
352
- case "hoist-field":
353
- return { HoistField: { host: combinator.host, field: combinator.field } };
354
- case "coerce-type":
355
- return { CoerceType: { from_kind: combinator.fromKind, to_kind: combinator.toKind } };
356
- case "compose":
357
- return { Compose: [combinatorToWire(combinator.first), combinatorToWire(combinator.second)] };
583
+ /**
584
+ * Create a symmetric lens between two schemas.
585
+ *
586
+ * @param schema1 - The left schema
587
+ * @param schema2 - The right schema
588
+ * @param wasm - The WASM module
589
+ * @returns A SymmetricLensHandle for bidirectional sync
590
+ * @throws {@link WasmError} if the WASM call fails
591
+ */
592
+ static fromSchemas(schema1, schema2, wasm) {
593
+ try {
594
+ const rawHandle = wasm.exports.symmetric_lens_from_schemas(schema1._handle.id, schema2._handle.id);
595
+ return new SymmetricLensHandle(createHandle(rawHandle, wasm), wasm);
596
+ } catch (error) {
597
+ throw new WasmError(
598
+ `symmetric_lens_from_schemas failed: ${error instanceof Error ? error.message : String(error)}`,
599
+ { cause: error }
600
+ );
601
+ }
602
+ }
603
+ /**
604
+ * Synchronize left view to right view.
605
+ *
606
+ * @param leftView - MessagePack-encoded left view data
607
+ * @param leftComplement - Opaque complement bytes from a prior sync
608
+ * @returns The synchronized right view and updated complement
609
+ * @throws {@link WasmError} if the WASM call fails
610
+ */
611
+ syncLeftToRight(leftView, leftComplement) {
612
+ try {
613
+ const bytes = this.#wasm.exports.symmetric_lens_sync(this.#handle.id, leftView, leftComplement, 0);
614
+ return unpackFromWasm(bytes);
615
+ } catch (error) {
616
+ throw new WasmError(
617
+ `symmetric_lens_sync (left-to-right) failed: ${error instanceof Error ? error.message : String(error)}`,
618
+ { cause: error }
619
+ );
620
+ }
621
+ }
622
+ /**
623
+ * Synchronize right view to left view.
624
+ *
625
+ * @param rightView - MessagePack-encoded right view data
626
+ * @param rightComplement - Opaque complement bytes from a prior sync
627
+ * @returns The synchronized left view and updated complement
628
+ * @throws {@link WasmError} if the WASM call fails
629
+ */
630
+ syncRightToLeft(rightView, rightComplement) {
631
+ try {
632
+ const bytes = this.#wasm.exports.symmetric_lens_sync(this.#handle.id, rightView, rightComplement, 1);
633
+ return unpackFromWasm(bytes);
634
+ } catch (error) {
635
+ throw new WasmError(
636
+ `symmetric_lens_sync (right-to-left) failed: ${error instanceof Error ? error.message : String(error)}`,
637
+ { cause: error }
638
+ );
639
+ }
640
+ }
641
+ /** Release the underlying WASM resource. */
642
+ [Symbol.dispose]() {
643
+ this.#handle[Symbol.dispose]();
358
644
  }
359
645
  }
360
646
  class FullDiffReport {
@@ -1700,6 +1986,70 @@ class Repository {
1700
1986
  this.#handle[Symbol.dispose]();
1701
1987
  }
1702
1988
  }
1989
+ class DataSetHandle {
1990
+ #handle;
1991
+ #wasm;
1992
+ constructor(handle, wasm) {
1993
+ this.#handle = handle;
1994
+ this.#wasm = wasm;
1995
+ }
1996
+ /** The WASM handle for this data set. Internal use only. */
1997
+ get _handle() {
1998
+ return this.#handle;
1999
+ }
2000
+ /** Store a data set from a JavaScript object, bound to a schema. */
2001
+ static fromData(data, schema, wasm) {
2002
+ const jsonBytes = new TextEncoder().encode(JSON.stringify(data));
2003
+ const rawHandle = wasm.exports.store_dataset(schema._handle.id, jsonBytes);
2004
+ return new DataSetHandle(createHandle(rawHandle, wasm), wasm);
2005
+ }
2006
+ /** Retrieve the data as MessagePack-encoded bytes. */
2007
+ getData() {
2008
+ const bytes = this.#wasm.exports.get_dataset(this.#handle.id);
2009
+ return unpackFromWasm(bytes);
2010
+ }
2011
+ /** Migrate this data set forward to a new schema. */
2012
+ migrateForward(srcSchema, tgtSchema) {
2013
+ const bytes = this.#wasm.exports.migrate_dataset_forward(
2014
+ this.#handle.id,
2015
+ srcSchema._handle.id,
2016
+ tgtSchema._handle.id
2017
+ );
2018
+ const result = unpackFromWasm(bytes);
2019
+ const complementBytes = this.#wasm.exports.get_dataset(result.complement_handle);
2020
+ this.#wasm.exports.free_handle(result.complement_handle);
2021
+ return {
2022
+ data: new DataSetHandle(createHandle(result.data_handle, this.#wasm), this.#wasm),
2023
+ complement: new Uint8Array(complementBytes)
2024
+ };
2025
+ }
2026
+ /** Migrate this data set backward using a complement. */
2027
+ migrateBackward(complement, srcSchema, tgtSchema) {
2028
+ const rawHandle = this.#wasm.exports.migrate_dataset_backward(
2029
+ this.#handle.id,
2030
+ complement,
2031
+ srcSchema._handle.id,
2032
+ tgtSchema._handle.id
2033
+ );
2034
+ return new DataSetHandle(createHandle(rawHandle, this.#wasm), this.#wasm);
2035
+ }
2036
+ /** Check if this data set is stale relative to a schema. */
2037
+ isStale(schema) {
2038
+ const bytes = this.#wasm.exports.check_dataset_staleness(
2039
+ this.#handle.id,
2040
+ schema._handle.id
2041
+ );
2042
+ const raw = unpackFromWasm(bytes);
2043
+ return {
2044
+ stale: raw.stale,
2045
+ dataSchemaId: raw.data_schema_id,
2046
+ targetSchemaId: raw.target_schema_id
2047
+ };
2048
+ }
2049
+ [Symbol.dispose]() {
2050
+ this.#handle[Symbol.dispose]();
2051
+ }
2052
+ }
1703
2053
  class Panproto {
1704
2054
  #wasm;
1705
2055
  #protocols;
@@ -1929,6 +2279,76 @@ class Panproto {
1929
2279
  initRepo(protocolName) {
1930
2280
  return Repository.init(protocolName, this.#wasm);
1931
2281
  }
2282
+ /**
2283
+ * Convert data from one schema to another using an auto-generated lens.
2284
+ *
2285
+ * This is a convenience method that generates a protolens, applies the
2286
+ * forward projection, and disposes the lens automatically.
2287
+ *
2288
+ * @param data - The input data (Uint8Array of MessagePack, or a plain object)
2289
+ * @param opts - Conversion options specifying source and target schemas
2290
+ * @returns The converted data
2291
+ * @throws {@link WasmError} if lens generation or conversion fails
2292
+ */
2293
+ async convert(data, opts) {
2294
+ const lens = LensHandle.autoGenerate(opts.from, opts.to, this.#wasm);
2295
+ try {
2296
+ const input = data instanceof Uint8Array ? data : packToWasm(data);
2297
+ const result = lens.get(input);
2298
+ return result.view;
2299
+ } finally {
2300
+ lens[Symbol.dispose]();
2301
+ }
2302
+ }
2303
+ /**
2304
+ * Create an auto-generated lens between two schemas.
2305
+ *
2306
+ * @param from - The source schema
2307
+ * @param to - The target schema
2308
+ * @returns A LensHandle for the generated lens
2309
+ * @throws {@link WasmError} if lens generation fails
2310
+ */
2311
+ lens(from, to) {
2312
+ return LensHandle.autoGenerate(from, to, this.#wasm);
2313
+ }
2314
+ /**
2315
+ * Create a protolens chain between two schemas.
2316
+ *
2317
+ * The returned chain is schema-independent and can be instantiated
2318
+ * against different concrete schemas.
2319
+ *
2320
+ * @param from - The source schema
2321
+ * @param to - The target schema
2322
+ * @returns A ProtolensChainHandle for the generated chain
2323
+ * @throws {@link WasmError} if chain generation fails
2324
+ */
2325
+ protolensChain(from, to) {
2326
+ return ProtolensChainHandle.autoGenerate(from, to, this.#wasm);
2327
+ }
2328
+ /**
2329
+ * Store and track a data set against a schema.
2330
+ *
2331
+ * @param data - The data to store (array of records or a single object)
2332
+ * @param schema - The schema this data conforms to
2333
+ * @returns A disposable DataSetHandle
2334
+ */
2335
+ dataSet(data, schema) {
2336
+ return DataSetHandle.fromData(data, schema, this.#wasm);
2337
+ }
2338
+ /**
2339
+ * Migrate data forward between two schemas.
2340
+ *
2341
+ * Auto-generates a lens and migrates each record, returning the
2342
+ * migrated data and a complement for backward migration.
2343
+ *
2344
+ * @param data - The data set to migrate
2345
+ * @param from - The source schema
2346
+ * @param to - The target schema
2347
+ * @returns The migration result with new data and complement
2348
+ */
2349
+ migrateData(data, from, to) {
2350
+ return data.migrateForward(from, to);
2351
+ }
1932
2352
  /**
1933
2353
  * Release all WASM resources held by this instance.
1934
2354
  *
@@ -2062,12 +2482,24 @@ function migrateModel(sortInterp, morphism, wasm) {
2062
2482
  const resultBytes = wasm.exports.migrate_model(modelBytes, morphBytes);
2063
2483
  return unpackFromWasm(resultBytes);
2064
2484
  }
2485
+ function factorizeMorphism(morphismBytes, domain, codomain, wasm) {
2486
+ try {
2487
+ const bytes = wasm.exports.factorize_morphism(morphismBytes, domain._handle.id, codomain._handle.id);
2488
+ return unpackFromWasm(bytes);
2489
+ } catch (error) {
2490
+ throw new WasmError(
2491
+ `factorize_morphism failed: ${error instanceof Error ? error.message : String(error)}`,
2492
+ { cause: error }
2493
+ );
2494
+ }
2495
+ }
2065
2496
  export {
2066
2497
  ATPROTO_SPEC,
2067
2498
  BUILTIN_PROTOCOLS,
2068
2499
  BuiltSchema,
2069
2500
  CompatReport,
2070
2501
  CompiledMigration,
2502
+ DataSetHandle,
2071
2503
  ExistenceCheckError,
2072
2504
  FullDiffReport,
2073
2505
  GRAPHQL_SPEC,
@@ -2082,28 +2514,22 @@ export {
2082
2514
  Panproto,
2083
2515
  PanprotoError,
2084
2516
  Protocol,
2517
+ ProtolensChainHandle,
2085
2518
  Repository,
2086
2519
  SQL_SPEC,
2087
2520
  SchemaBuilder,
2088
2521
  SchemaValidationError,
2522
+ SymmetricLensHandle,
2089
2523
  TheoryBuilder,
2090
2524
  TheoryHandle,
2091
2525
  ValidationResult,
2092
2526
  WasmError,
2093
- addField,
2094
2527
  checkMorphism,
2095
- coerceType,
2096
2528
  colimit,
2097
- compose,
2098
2529
  createTheory,
2099
- fromCombinators,
2530
+ factorizeMorphism,
2100
2531
  getBuiltinProtocol,
2101
2532
  getProtocolNames,
2102
- hoistField,
2103
- migrateModel,
2104
- pipeline,
2105
- removeField,
2106
- renameField,
2107
- wrapInObject
2533
+ migrateModel
2108
2534
  };
2109
2535
  //# sourceMappingURL=index.js.map