@panproto/core 0.5.0 → 0.5.1

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 CHANGED
@@ -1,8 +1,13 @@
1
1
  # @panproto/core
2
2
 
3
- TypeScript SDK for panproto -- protocol-aware schema migration via [generalized algebraic theories](https://ncatlab.org/nlab/show/generalized+algebraic+theory).
3
+ [![npm](https://img.shields.io/npm/v/@panproto/core)](https://www.npmjs.com/package/@panproto/core)
4
+ [![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](../../LICENSE)
4
5
 
5
- This package wraps the panproto [WASM](https://webassembly.org/) module, providing a typed, ergonomic API for defining protocols, building schemas, computing migrations, and applying [lens](https://ncatlab.org/nlab/show/lens+%28in+computer+science%29)-based transformations from JavaScript and TypeScript.
6
+ TypeScript SDK for panproto. Protocol-aware schema migration via [generalized algebraic theories](https://ncatlab.org/nlab/show/generalized+algebraic+theory).
7
+
8
+ This package wraps the panproto WASM module, providing a typed, ergonomic API for defining protocols, building schemas, computing migrations, and applying lens-based transformations from JavaScript and TypeScript.
9
+
10
+ Requires Node.js >= 20.
6
11
 
7
12
  ## Installation
8
13
 
@@ -10,8 +15,6 @@ This package wraps the panproto [WASM](https://webassembly.org/) module, providi
10
15
  npm install @panproto/core
11
16
  ```
12
17
 
13
- Requires Node.js >= 20.
14
-
15
18
  ## Usage
16
19
 
17
20
  ```typescript
@@ -32,10 +35,14 @@ const diff = panproto.diff(oldSchema, newSchema);
32
35
 
33
36
  // Compile and apply a migration
34
37
  const migration = panproto.migration(srcSchema, tgtSchema)
35
- .mapVertex('old_id', 'new_id')
38
+ .map('old_id', 'new_id')
36
39
  .compile();
37
40
 
38
41
  const lifted = migration.lift(record);
42
+
43
+ // Bidirectional lens
44
+ const { view, complement } = migration.get(record);
45
+ const restored = migration.put(modifiedView, complement);
39
46
  ```
40
47
 
41
48
  ## API
@@ -47,24 +54,47 @@ const lifted = migration.lift(record);
47
54
  | `Panproto` | Main entry point; call `Panproto.init()` to load the WASM module |
48
55
  | `Protocol` | Protocol handle with schema builder factory |
49
56
  | `SchemaBuilder` / `BuiltSchema` | Fluent schema construction |
50
- | `MigrationBuilder` / `CompiledMigration` | Migration construction and compilation |
57
+ | `MigrationBuilder` / `CompiledMigration` | Migration construction, compilation, and application |
58
+ | `Instance` | Instance wrapper with JSON conversion and validation |
59
+ | `IoRegistry` | Protocol-aware parse/emit for all 76 formats |
60
+ | `Repository` | Schematic version control (init, commit, branch, merge) |
51
61
 
52
- ### Lens Combinators
62
+ ### Lens combinators
53
63
 
54
64
  | Export | Description |
55
65
  |--------|-------------|
56
66
  | `renameField` / `addField` / `removeField` | Field-level transformations |
57
67
  | `wrapInObject` / `hoistField` / `coerceType` | Structural transformations |
58
- | `compose` / `pipeline` | [Cambria](https://www.inkandswitch.com/cambria/)-style combinator composition |
68
+ | `compose` / `pipeline` | Cambria-style combinator composition |
69
+
70
+ ### Breaking change analysis
71
+
72
+ | Export | Description |
73
+ |--------|-------------|
74
+ | `FullDiffReport` | Comprehensive structural diff between two schemas |
75
+ | `CompatReport` | Protocol-aware classification into breaking/non-breaking |
76
+ | `ValidationResult` | Schema validation against protocol rules |
77
+
78
+ ### GAT engine
79
+
80
+ | Export | Description |
81
+ |--------|-------------|
82
+ | `TheoryHandle` / `TheoryBuilder` | Theory construction |
83
+ | `createTheory` / `colimit` | Build and compose theories |
84
+ | `checkMorphism` / `migrateModel` | Morphism validation and model transport |
59
85
 
60
- ### Built-in Protocol Specs
86
+ ### Built-in protocol specs
61
87
 
62
88
  `ATPROTO_SPEC`, `SQL_SPEC`, `PROTOBUF_SPEC`, `GRAPHQL_SPEC`, `JSON_SCHEMA_SPEC`, `BUILTIN_PROTOCOLS`
63
89
 
64
- ### Error Classes
90
+ ### Error classes
65
91
 
66
92
  `PanprotoError`, `WasmError`, `SchemaValidationError`, `MigrationError`, `ExistenceCheckError`
67
93
 
94
+ ## Documentation
95
+
96
+ [panproto.dev](https://panproto.dev)
97
+
68
98
  ## License
69
99
 
70
100
  [MIT](../../LICENSE)
package/dist/index.cjs CHANGED
@@ -66,6 +66,10 @@ async function loadWasm(input) {
66
66
  validate_instance: glue.validate_instance,
67
67
  instance_to_json: glue.instance_to_json,
68
68
  json_to_instance: glue.json_to_instance,
69
+ json_to_instance_with_root: glue.json_to_instance_with_root,
70
+ lift_json: glue.lift_json,
71
+ get_json: glue.get_json,
72
+ put_json: glue.put_json,
69
73
  instance_element_count: glue.instance_element_count,
70
74
  lens_from_combinators: glue.lens_from_combinators,
71
75
  check_lens_laws: glue.check_lens_laws,
@@ -158,7 +162,14 @@ function packSchemaOps(ops) {
158
162
  return msgpack.encode(ops);
159
163
  }
160
164
  function packMigrationMapping(mapping) {
161
- return msgpack.encode(mapping);
165
+ return msgpack.encode({
166
+ vertex_map: mapping.vertex_map,
167
+ edge_map: Array.from(mapping.edge_map.entries()),
168
+ hyper_edge_map: mapping.hyper_edge_map,
169
+ label_map: Array.from(mapping.label_map.entries()),
170
+ resolver: Array.from(mapping.resolver.entries()),
171
+ hyper_resolver: []
172
+ });
162
173
  }
163
174
  function renameField(oldName, newName) {
164
175
  return { type: "rename-field", old: oldName, new: newName };
@@ -1119,6 +1130,10 @@ class CompiledMigration {
1119
1130
  get _handle() {
1120
1131
  return this.#handle;
1121
1132
  }
1133
+ /** The WASM module. Internal use only. */
1134
+ get _wasm() {
1135
+ return this.#wasm;
1136
+ }
1122
1137
  /** The migration specification used to build this migration. */
1123
1138
  get spec() {
1124
1139
  return this.#spec;
@@ -1126,22 +1141,22 @@ class CompiledMigration {
1126
1141
  /**
1127
1142
  * Transform a record using this migration (forward direction).
1128
1143
  *
1129
- * This is the hot path: data goes through WASM as MessagePack bytes
1130
- * with no intermediate JS-heap allocation.
1144
+ * Accepts either a raw JS object (which will be msgpack-encoded) or
1145
+ * an `Instance` (whose pre-encoded bytes are passed directly to WASM).
1131
1146
  *
1132
- * @param record - The input record to transform
1147
+ * @param record - The input record or Instance to transform
1133
1148
  * @returns The transformed record
1134
1149
  * @throws {@link WasmError} if the WASM call fails
1135
1150
  */
1136
1151
  lift(record) {
1137
- const inputBytes = packToWasm(record);
1152
+ const inputBytes = record && typeof record === "object" && "_bytes" in record ? record._bytes : packToWasm(record);
1138
1153
  try {
1139
1154
  const outputBytes = this.#wasm.exports.lift_record(
1140
1155
  this.#handle.id,
1141
1156
  inputBytes
1142
1157
  );
1143
1158
  const data = unpackFromWasm(outputBytes);
1144
- return { data };
1159
+ return { data, _rawBytes: outputBytes };
1145
1160
  } catch (error) {
1146
1161
  throw new WasmError(
1147
1162
  `lift_record failed: ${error instanceof Error ? error.message : String(error)}`,
@@ -1160,7 +1175,7 @@ class CompiledMigration {
1160
1175
  * @throws {@link WasmError} if the WASM call fails
1161
1176
  */
1162
1177
  get(record) {
1163
- const inputBytes = packToWasm(record);
1178
+ const inputBytes = record && typeof record === "object" && "_bytes" in record ? record._bytes : packToWasm(record);
1164
1179
  try {
1165
1180
  const outputBytes = this.#wasm.exports.get_record(
1166
1181
  this.#handle.id,
@@ -1187,7 +1202,7 @@ class CompiledMigration {
1187
1202
  * @throws {@link WasmError} if the WASM call fails
1188
1203
  */
1189
1204
  put(view, complement) {
1190
- const viewBytes = packToWasm(view);
1205
+ const viewBytes = view && typeof view === "object" && "_bytes" in view ? view._bytes : packToWasm(view);
1191
1206
  try {
1192
1207
  const outputBytes = this.#wasm.exports.put_record(
1193
1208
  this.#handle.id,