@voidhash/mimic 0.0.1-alpha.1 → 0.0.1-alpha.111

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 (63) hide show
  1. package/.turbo/turbo-build.log +51 -0
  2. package/LICENSE.md +663 -0
  3. package/dist/Document-ChuFrTk1.cjs +571 -0
  4. package/dist/Document-CwiAFTIq.mjs +438 -0
  5. package/dist/Document-CwiAFTIq.mjs.map +1 -0
  6. package/dist/Presence-DKKP4v5X.d.cts +91 -0
  7. package/dist/Presence-DKKP4v5X.d.cts.map +1 -0
  8. package/dist/Presence-DdMVKcOv.mjs +110 -0
  9. package/dist/Presence-DdMVKcOv.mjs.map +1 -0
  10. package/dist/Presence-N8u7Eppr.d.mts +91 -0
  11. package/dist/Presence-N8u7Eppr.d.mts.map +1 -0
  12. package/dist/Presence-gWrmGBeu.cjs +126 -0
  13. package/dist/Primitive-CvFVxR8_.d.cts +1175 -0
  14. package/dist/Primitive-CvFVxR8_.d.cts.map +1 -0
  15. package/dist/Primitive-lEhQyGVL.d.mts +1175 -0
  16. package/dist/Primitive-lEhQyGVL.d.mts.map +1 -0
  17. package/dist/chunk-CLMFDpHK.mjs +18 -0
  18. package/dist/client/index.cjs +1456 -0
  19. package/dist/client/index.d.cts +692 -0
  20. package/dist/client/index.d.cts.map +1 -0
  21. package/dist/client/index.d.mts +692 -0
  22. package/dist/client/index.d.mts.map +1 -0
  23. package/dist/client/index.mjs +1413 -0
  24. package/dist/client/index.mjs.map +1 -0
  25. package/dist/index.cjs +2577 -0
  26. package/dist/index.d.cts +143 -0
  27. package/dist/index.d.cts.map +1 -0
  28. package/dist/index.d.mts +143 -0
  29. package/dist/index.d.mts.map +1 -0
  30. package/dist/index.mjs +2526 -0
  31. package/dist/index.mjs.map +1 -0
  32. package/dist/server/index.cjs +191 -0
  33. package/dist/server/index.d.cts +148 -0
  34. package/dist/server/index.d.cts.map +1 -0
  35. package/dist/server/index.d.mts +148 -0
  36. package/dist/server/index.d.mts.map +1 -0
  37. package/dist/server/index.mjs +182 -0
  38. package/dist/server/index.mjs.map +1 -0
  39. package/package.json +25 -13
  40. package/src/EffectSchema.ts +374 -0
  41. package/src/Primitive.ts +3 -0
  42. package/src/client/ClientDocument.ts +1 -1
  43. package/src/client/errors.ts +10 -10
  44. package/src/index.ts +1 -0
  45. package/src/primitives/Array.ts +57 -22
  46. package/src/primitives/Boolean.ts +33 -19
  47. package/src/primitives/Either.ts +379 -0
  48. package/src/primitives/Lazy.ts +16 -2
  49. package/src/primitives/Literal.ts +33 -20
  50. package/src/primitives/Number.ts +39 -26
  51. package/src/primitives/String.ts +40 -25
  52. package/src/primitives/Struct.ts +126 -29
  53. package/src/primitives/Tree.ts +119 -32
  54. package/src/primitives/TreeNode.ts +77 -30
  55. package/src/primitives/Union.ts +56 -29
  56. package/src/primitives/shared.ts +111 -9
  57. package/src/server/errors.ts +6 -6
  58. package/tests/EffectSchema.test.ts +546 -0
  59. package/tests/primitives/Array.test.ts +108 -0
  60. package/tests/primitives/Either.test.ts +707 -0
  61. package/tests/primitives/Struct.test.ts +250 -0
  62. package/tests/primitives/Tree.test.ts +250 -0
  63. package/tsdown.config.ts +1 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,2526 @@
1
+ import { t as __export } from "./chunk-CLMFDpHK.mjs";
2
+ import { c as Operation_exports, d as isPrefix, f as pathsEqual, l as fromDefinition, m as _defineProperty, p as pathsOverlap, r as Transaction_exports, s as ProxyEnvironment_exports, t as Document_exports, u as OperationPath_exports } from "./Document-CwiAFTIq.mjs";
3
+ import { r as _objectSpread2, t as Presence_exports } from "./Presence-DdMVKcOv.mjs";
4
+ import { Effect, Schema } from "effect";
5
+
6
+ //#region src/primitives/shared.ts
7
+ var ValidationError = class extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ _defineProperty(this, "_tag", "ValidationError");
11
+ this.name = "ValidationError";
12
+ }
13
+ };
14
+ /**
15
+ * Runs all validators against a value, throwing ValidationError if any fail.
16
+ */
17
+ function runValidators(value, validators) {
18
+ for (const validator of validators) if (!validator.validate(value)) throw new ValidationError(validator.message);
19
+ }
20
+ /**
21
+ * Checks if an operation is compatible with the given operation definitions.
22
+ * @param operation - The operation to check.
23
+ * @param operationDefinitions - The operation definitions to check against.
24
+ * @returns True if the operation is compatible, false otherwise.
25
+ */
26
+ function isCompatibleOperation(operation, operationDefinitions) {
27
+ return Object.values(operationDefinitions).some((value) => value.kind === operation.kind);
28
+ }
29
+ /**
30
+ * Applies default values to a partial input, recursively handling nested structs.
31
+ *
32
+ * Uses a two-layer approach:
33
+ * 1. First, get the struct's initial state (which includes struct-level defaults)
34
+ * 2. Then, layer the provided values on top
35
+ * 3. Finally, ensure nested structs are recursively processed
36
+ *
37
+ * @param primitive - The primitive definition containing field information
38
+ * @param value - The partial value provided by the user
39
+ * @returns The value with defaults applied for missing fields
40
+ */
41
+ function applyDefaults(primitive, value) {
42
+ if (primitive._tag === "StructPrimitive") {
43
+ var _structPrimitive$_int;
44
+ const structPrimitive = primitive;
45
+ const result = _objectSpread2(_objectSpread2({}, (_structPrimitive$_int = structPrimitive._internal.getInitialState()) !== null && _structPrimitive$_int !== void 0 ? _structPrimitive$_int : {}), value);
46
+ for (const key in structPrimitive.fields) {
47
+ const fieldPrimitive = structPrimitive.fields[key];
48
+ if (result[key] === void 0) {
49
+ const fieldDefault = fieldPrimitive._internal.getInitialState();
50
+ if (fieldDefault !== void 0) result[key] = fieldDefault;
51
+ } else if (fieldPrimitive._tag === "StructPrimitive" && typeof result[key] === "object" && result[key] !== null) result[key] = applyDefaults(fieldPrimitive, result[key]);
52
+ }
53
+ return result;
54
+ }
55
+ return value;
56
+ }
57
+
58
+ //#endregion
59
+ //#region src/OperationDefinition.ts
60
+ const make = (options) => {
61
+ return {
62
+ kind: options.kind,
63
+ payload: options.payload,
64
+ target: options.target,
65
+ apply: options.apply
66
+ };
67
+ };
68
+
69
+ //#endregion
70
+ //#region src/primitives/String.ts
71
+ var StringPrimitive = class StringPrimitive {
72
+ constructor(schema) {
73
+ _defineProperty(this, "_tag", "StringPrimitive");
74
+ _defineProperty(this, "_State", void 0);
75
+ _defineProperty(this, "_Proxy", void 0);
76
+ _defineProperty(this, "_TRequired", void 0);
77
+ _defineProperty(this, "_THasDefault", void 0);
78
+ _defineProperty(this, "TUpdateInput", void 0);
79
+ _defineProperty(this, "TSetInput", void 0);
80
+ _defineProperty(this, "_schema", void 0);
81
+ _defineProperty(this, "_opDefinitions", { set: make({
82
+ kind: "string.set",
83
+ payload: Schema.String,
84
+ target: Schema.String,
85
+ apply: (payload) => payload
86
+ }) });
87
+ _defineProperty(this, "_internal", {
88
+ createProxy: (env, operationPath) => {
89
+ const defaultValue = this._schema.defaultValue;
90
+ return {
91
+ get: () => {
92
+ const state = env.getState(operationPath);
93
+ return state !== null && state !== void 0 ? state : defaultValue;
94
+ },
95
+ set: (value) => {
96
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
97
+ },
98
+ update: (value) => {
99
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
100
+ },
101
+ toSnapshot: () => {
102
+ const state = env.getState(operationPath);
103
+ return state !== null && state !== void 0 ? state : defaultValue;
104
+ }
105
+ };
106
+ },
107
+ applyOperation: (_state, operation) => {
108
+ if (!isCompatibleOperation(operation, this._opDefinitions)) throw new ValidationError(`StringPrimitive cannot apply operation of kind: ${operation.kind}`);
109
+ const payload = operation.payload;
110
+ if (typeof payload !== "string") throw new ValidationError(`StringPrimitive.set requires a string payload, got: ${typeof payload}`);
111
+ runValidators(payload, this._schema.validators);
112
+ return payload;
113
+ },
114
+ getInitialState: () => {
115
+ return this._schema.defaultValue;
116
+ },
117
+ transformOperation: (clientOp, serverOp) => {
118
+ if (!pathsOverlap(clientOp.path, serverOp.path)) return {
119
+ type: "transformed",
120
+ operation: clientOp
121
+ };
122
+ return {
123
+ type: "transformed",
124
+ operation: clientOp
125
+ };
126
+ }
127
+ });
128
+ this._schema = schema;
129
+ }
130
+ /** Mark this string as required */
131
+ required() {
132
+ return new StringPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
133
+ }
134
+ /** Set a default value for this string */
135
+ default(defaultValue) {
136
+ return new StringPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
137
+ }
138
+ /** Add a custom validation rule */
139
+ refine(fn, message) {
140
+ return new StringPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
141
+ validate: fn,
142
+ message
143
+ }] }));
144
+ }
145
+ /** Minimum string length */
146
+ min(length) {
147
+ return this.refine((v) => v.length >= length, `String must be at least ${length} characters`);
148
+ }
149
+ /** Maximum string length */
150
+ max(length) {
151
+ return this.refine((v) => v.length <= length, `String must be at most ${length} characters`);
152
+ }
153
+ /** Exact string length */
154
+ length(exact) {
155
+ return this.refine((v) => v.length === exact, `String must be exactly ${exact} characters`);
156
+ }
157
+ /** Match a regex pattern */
158
+ regex(pattern, message) {
159
+ return this.refine((v) => pattern.test(v), message !== null && message !== void 0 ? message : `String must match pattern ${pattern}`);
160
+ }
161
+ /** Validate as email format */
162
+ email() {
163
+ const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
164
+ return this.refine((v) => emailPattern.test(v), "Invalid email format");
165
+ }
166
+ /** Validate as URL format */
167
+ url() {
168
+ return this.refine((v) => {
169
+ try {
170
+ new URL(v);
171
+ return true;
172
+ } catch (_unused) {
173
+ return false;
174
+ }
175
+ }, "Invalid URL format");
176
+ }
177
+ };
178
+ /** Creates a new StringPrimitive */
179
+ const String = () => new StringPrimitive({
180
+ required: false,
181
+ defaultValue: void 0,
182
+ validators: []
183
+ });
184
+
185
+ //#endregion
186
+ //#region src/primitives/Struct.ts
187
+ var StructPrimitive = class StructPrimitive {
188
+ constructor(schema) {
189
+ _defineProperty(this, "_tag", "StructPrimitive");
190
+ _defineProperty(this, "_State", void 0);
191
+ _defineProperty(this, "_Proxy", void 0);
192
+ _defineProperty(this, "_TRequired", void 0);
193
+ _defineProperty(this, "_THasDefault", void 0);
194
+ _defineProperty(this, "TSetInput", void 0);
195
+ _defineProperty(this, "TUpdateInput", void 0);
196
+ _defineProperty(this, "_schema", void 0);
197
+ _defineProperty(this, "_opDefinitions", { set: make({
198
+ kind: "struct.set",
199
+ payload: Schema.Unknown,
200
+ target: Schema.Unknown,
201
+ apply: (payload) => payload
202
+ }) });
203
+ _defineProperty(this, "_internal", {
204
+ createProxy: (env, operationPath) => {
205
+ const fields = this._schema.fields;
206
+ const defaultValue = this._schema.defaultValue;
207
+ const buildSnapshot = () => {
208
+ const state = env.getState(operationPath);
209
+ const snapshot = {};
210
+ let hasAnyDefinedField = false;
211
+ for (const key in fields) {
212
+ const fieldPrimitive = fields[key];
213
+ const fieldPath = operationPath.append(key);
214
+ const fieldSnapshot = fieldPrimitive._internal.createProxy(env, fieldPath).toSnapshot();
215
+ snapshot[key] = fieldSnapshot;
216
+ if (fieldSnapshot !== void 0) hasAnyDefinedField = true;
217
+ }
218
+ if (state === void 0 && defaultValue === void 0 && !hasAnyDefinedField) return;
219
+ return snapshot;
220
+ };
221
+ return new globalThis.Proxy({
222
+ get: () => {
223
+ const state = env.getState(operationPath);
224
+ return state !== null && state !== void 0 ? state : defaultValue;
225
+ },
226
+ set: (value) => {
227
+ const merged = applyDefaults(this, value);
228
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, merged));
229
+ },
230
+ update: (value) => {
231
+ for (const key in value) if (Object.prototype.hasOwnProperty.call(value, key)) {
232
+ const fieldValue = value[key];
233
+ if (fieldValue === void 0) continue;
234
+ const fieldPrimitive = fields[key];
235
+ if (!fieldPrimitive) continue;
236
+ const fieldPath = operationPath.append(key);
237
+ const fieldProxy = fieldPrimitive._internal.createProxy(env, fieldPath);
238
+ if (fieldPrimitive._tag === "StructPrimitive" && typeof fieldValue === "object" && fieldValue !== null && !Array.isArray(fieldValue)) fieldProxy.update(fieldValue);
239
+ else fieldProxy.set(fieldValue);
240
+ }
241
+ },
242
+ toSnapshot: () => {
243
+ return buildSnapshot();
244
+ }
245
+ }, {
246
+ get: (target, prop, _receiver) => {
247
+ if (prop === "get") return target.get;
248
+ if (prop === "set") return target.set;
249
+ if (prop === "update") return target.update;
250
+ if (prop === "toSnapshot") return target.toSnapshot;
251
+ if (typeof prop === "symbol") return;
252
+ if (prop in fields) {
253
+ const fieldPrimitive = fields[prop];
254
+ const fieldPath = operationPath.append(prop);
255
+ return fieldPrimitive._internal.createProxy(env, fieldPath);
256
+ }
257
+ },
258
+ has: (_target, prop) => {
259
+ if (prop === "get" || prop === "set" || prop === "update" || prop === "toSnapshot") return true;
260
+ if (typeof prop === "string" && prop in fields) return true;
261
+ return false;
262
+ }
263
+ });
264
+ },
265
+ applyOperation: (state, operation) => {
266
+ const path = operation.path;
267
+ const tokens = path.toTokens().filter((t) => t !== "");
268
+ let newState;
269
+ if (tokens.length === 0) {
270
+ if (operation.kind !== "struct.set") throw new ValidationError(`StructPrimitive root cannot apply operation of kind: ${operation.kind}`);
271
+ const payload = operation.payload;
272
+ if (typeof payload !== "object" || payload === null) throw new ValidationError(`StructPrimitive.set requires an object payload`);
273
+ newState = payload;
274
+ } else {
275
+ const fieldName = tokens[0];
276
+ if (!(fieldName in this._schema.fields)) throw new ValidationError(`Unknown field: ${globalThis.String(fieldName)}`);
277
+ const fieldPrimitive = this._schema.fields[fieldName];
278
+ const remainingPath = path.shift();
279
+ const fieldOperation = _objectSpread2(_objectSpread2({}, operation), {}, { path: remainingPath });
280
+ const currentState = state !== null && state !== void 0 ? state : {};
281
+ const currentFieldState = currentState[fieldName];
282
+ const newFieldState = fieldPrimitive._internal.applyOperation(currentFieldState, fieldOperation);
283
+ newState = _objectSpread2(_objectSpread2({}, currentState), {}, { [fieldName]: newFieldState });
284
+ }
285
+ runValidators(newState, this._schema.validators);
286
+ return newState;
287
+ },
288
+ getInitialState: () => {
289
+ if (this._schema.defaultValue !== void 0) return this._schema.defaultValue;
290
+ const fields = this._schema.fields;
291
+ const initialState = {};
292
+ let hasAnyDefault = false;
293
+ for (const key in fields) {
294
+ const fieldDefault = fields[key]._internal.getInitialState();
295
+ if (fieldDefault !== void 0) {
296
+ initialState[key] = fieldDefault;
297
+ hasAnyDefault = true;
298
+ }
299
+ }
300
+ return hasAnyDefault ? initialState : void 0;
301
+ },
302
+ transformOperation: (clientOp, serverOp) => {
303
+ const clientPath = clientOp.path;
304
+ const serverPath = serverOp.path;
305
+ if (!pathsOverlap(clientPath, serverPath)) return {
306
+ type: "transformed",
307
+ operation: clientOp
308
+ };
309
+ const clientTokens = clientPath.toTokens().filter((t) => t !== "");
310
+ const serverTokens = serverPath.toTokens().filter((t) => t !== "");
311
+ if (clientTokens.length === 0 && serverTokens.length === 0) return {
312
+ type: "transformed",
313
+ operation: clientOp
314
+ };
315
+ if (serverTokens.length === 0 && serverOp.kind === "struct.set") return {
316
+ type: "transformed",
317
+ operation: clientOp
318
+ };
319
+ if (clientTokens.length === 0 && clientOp.kind === "struct.set") return {
320
+ type: "transformed",
321
+ operation: clientOp
322
+ };
323
+ if (clientTokens.length > 0 && serverTokens.length > 0) {
324
+ const clientField = clientTokens[0];
325
+ if (clientField !== serverTokens[0]) return {
326
+ type: "transformed",
327
+ operation: clientOp
328
+ };
329
+ const fieldPrimitive = this._schema.fields[clientField];
330
+ if (!fieldPrimitive) return {
331
+ type: "transformed",
332
+ operation: clientOp
333
+ };
334
+ const clientOpForField = _objectSpread2(_objectSpread2({}, clientOp), {}, { path: clientOp.path.shift() });
335
+ const serverOpForField = _objectSpread2(_objectSpread2({}, serverOp), {}, { path: serverOp.path.shift() });
336
+ const result = fieldPrimitive._internal.transformOperation(clientOpForField, serverOpForField);
337
+ if (result.type === "transformed") return {
338
+ type: "transformed",
339
+ operation: _objectSpread2(_objectSpread2({}, result.operation), {}, { path: clientOp.path })
340
+ };
341
+ return result;
342
+ }
343
+ return {
344
+ type: "transformed",
345
+ operation: clientOp
346
+ };
347
+ }
348
+ });
349
+ this._schema = schema;
350
+ }
351
+ /** Mark this struct as required */
352
+ required() {
353
+ return new StructPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
354
+ }
355
+ /** Set a default value for this struct */
356
+ default(defaultValue) {
357
+ const merged = applyDefaults(this, defaultValue);
358
+ return new StructPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue: merged }));
359
+ }
360
+ /** Get the fields schema */
361
+ get fields() {
362
+ return this._schema.fields;
363
+ }
364
+ /** Add a custom validation rule (useful for cross-field validation) */
365
+ refine(fn, message) {
366
+ return new StructPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
367
+ validate: fn,
368
+ message
369
+ }] }));
370
+ }
371
+ };
372
+ /** Creates a new StructPrimitive with the given fields */
373
+ const Struct = (fields) => new StructPrimitive({
374
+ required: false,
375
+ defaultValue: void 0,
376
+ fields,
377
+ validators: []
378
+ });
379
+
380
+ //#endregion
381
+ //#region src/primitives/Boolean.ts
382
+ var BooleanPrimitive = class BooleanPrimitive {
383
+ constructor(schema) {
384
+ _defineProperty(this, "_tag", "BooleanPrimitive");
385
+ _defineProperty(this, "_State", void 0);
386
+ _defineProperty(this, "_Proxy", void 0);
387
+ _defineProperty(this, "_TRequired", void 0);
388
+ _defineProperty(this, "_THasDefault", void 0);
389
+ _defineProperty(this, "TUpdateInput", void 0);
390
+ _defineProperty(this, "TSetInput", void 0);
391
+ _defineProperty(this, "_schema", void 0);
392
+ _defineProperty(this, "_opDefinitions", { set: make({
393
+ kind: "boolean.set",
394
+ payload: Schema.Boolean,
395
+ target: Schema.Boolean,
396
+ apply: (payload) => payload
397
+ }) });
398
+ _defineProperty(this, "_internal", {
399
+ createProxy: (env, operationPath) => {
400
+ const defaultValue = this._schema.defaultValue;
401
+ return {
402
+ get: () => {
403
+ const state = env.getState(operationPath);
404
+ return state !== null && state !== void 0 ? state : defaultValue;
405
+ },
406
+ set: (value) => {
407
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
408
+ },
409
+ update: (value) => {
410
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
411
+ },
412
+ toSnapshot: () => {
413
+ const state = env.getState(operationPath);
414
+ return state !== null && state !== void 0 ? state : defaultValue;
415
+ }
416
+ };
417
+ },
418
+ applyOperation: (_state, operation) => {
419
+ if (operation.kind !== "boolean.set") throw new ValidationError(`BooleanPrimitive cannot apply operation of kind: ${operation.kind}`);
420
+ const payload = operation.payload;
421
+ if (typeof payload !== "boolean") throw new ValidationError(`BooleanPrimitive.set requires a boolean payload, got: ${typeof payload}`);
422
+ runValidators(payload, this._schema.validators);
423
+ return payload;
424
+ },
425
+ getInitialState: () => {
426
+ return this._schema.defaultValue;
427
+ },
428
+ transformOperation: (clientOp, serverOp) => {
429
+ if (!pathsOverlap(clientOp.path, serverOp.path)) return {
430
+ type: "transformed",
431
+ operation: clientOp
432
+ };
433
+ return {
434
+ type: "transformed",
435
+ operation: clientOp
436
+ };
437
+ }
438
+ });
439
+ this._schema = schema;
440
+ }
441
+ /** Mark this boolean as required */
442
+ required() {
443
+ return new BooleanPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
444
+ }
445
+ /** Set a default value for this boolean */
446
+ default(defaultValue) {
447
+ return new BooleanPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
448
+ }
449
+ /** Add a custom validation rule */
450
+ refine(fn, message) {
451
+ return new BooleanPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
452
+ validate: fn,
453
+ message
454
+ }] }));
455
+ }
456
+ };
457
+ /** Creates a new BooleanPrimitive */
458
+ const Boolean = () => new BooleanPrimitive({
459
+ required: false,
460
+ defaultValue: void 0,
461
+ validators: []
462
+ });
463
+
464
+ //#endregion
465
+ //#region src/primitives/Number.ts
466
+ var NumberPrimitive = class NumberPrimitive {
467
+ constructor(schema) {
468
+ _defineProperty(this, "_tag", "NumberPrimitive");
469
+ _defineProperty(this, "_State", void 0);
470
+ _defineProperty(this, "_Proxy", void 0);
471
+ _defineProperty(this, "_TRequired", void 0);
472
+ _defineProperty(this, "_THasDefault", void 0);
473
+ _defineProperty(this, "TUpdateInput", void 0);
474
+ _defineProperty(this, "TSetInput", void 0);
475
+ _defineProperty(this, "_schema", void 0);
476
+ _defineProperty(this, "_opDefinitions", { set: make({
477
+ kind: "number.set",
478
+ payload: Schema.Number,
479
+ target: Schema.Number,
480
+ apply: (payload) => payload
481
+ }) });
482
+ _defineProperty(this, "_internal", {
483
+ createProxy: (env, operationPath) => {
484
+ const defaultValue = this._schema.defaultValue;
485
+ return {
486
+ get: () => {
487
+ const state = env.getState(operationPath);
488
+ return state !== null && state !== void 0 ? state : defaultValue;
489
+ },
490
+ set: (value) => {
491
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
492
+ },
493
+ update: (value) => {
494
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
495
+ },
496
+ toSnapshot: () => {
497
+ const state = env.getState(operationPath);
498
+ return state !== null && state !== void 0 ? state : defaultValue;
499
+ }
500
+ };
501
+ },
502
+ applyOperation: (_state, operation) => {
503
+ if (operation.kind !== "number.set") throw new ValidationError(`NumberPrimitive cannot apply operation of kind: ${operation.kind}`);
504
+ const payload = operation.payload;
505
+ if (typeof payload !== "number") throw new ValidationError(`NumberPrimitive.set requires a number payload, got: ${typeof payload}`);
506
+ runValidators(payload, this._schema.validators);
507
+ return payload;
508
+ },
509
+ getInitialState: () => {
510
+ return this._schema.defaultValue;
511
+ },
512
+ transformOperation: (clientOp, serverOp) => {
513
+ if (!pathsOverlap(clientOp.path, serverOp.path)) return {
514
+ type: "transformed",
515
+ operation: clientOp
516
+ };
517
+ return {
518
+ type: "transformed",
519
+ operation: clientOp
520
+ };
521
+ }
522
+ });
523
+ this._schema = schema;
524
+ }
525
+ /** Mark this number as required */
526
+ required() {
527
+ return new NumberPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
528
+ }
529
+ /** Set a default value for this number */
530
+ default(defaultValue) {
531
+ return new NumberPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
532
+ }
533
+ /** Add a custom validation rule */
534
+ refine(fn, message) {
535
+ return new NumberPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
536
+ validate: fn,
537
+ message
538
+ }] }));
539
+ }
540
+ /** Minimum value (inclusive) */
541
+ min(value) {
542
+ return this.refine((v) => v >= value, `Number must be at least ${value}`);
543
+ }
544
+ /** Maximum value (inclusive) */
545
+ max(value) {
546
+ return this.refine((v) => v <= value, `Number must be at most ${value}`);
547
+ }
548
+ /** Must be positive (> 0) */
549
+ positive() {
550
+ return this.refine((v) => v > 0, "Number must be positive");
551
+ }
552
+ /** Must be negative (< 0) */
553
+ negative() {
554
+ return this.refine((v) => v < 0, "Number must be negative");
555
+ }
556
+ /** Must be an integer */
557
+ int() {
558
+ return this.refine((v) => globalThis.Number.isInteger(v), "Number must be an integer");
559
+ }
560
+ };
561
+ /** Creates a new NumberPrimitive */
562
+ const Number = () => new NumberPrimitive({
563
+ required: false,
564
+ defaultValue: void 0,
565
+ validators: []
566
+ });
567
+
568
+ //#endregion
569
+ //#region src/primitives/Literal.ts
570
+ var LiteralPrimitive = class LiteralPrimitive {
571
+ constructor(schema) {
572
+ _defineProperty(this, "_tag", "LiteralPrimitive");
573
+ _defineProperty(this, "_State", void 0);
574
+ _defineProperty(this, "_Proxy", void 0);
575
+ _defineProperty(this, "_TRequired", void 0);
576
+ _defineProperty(this, "_THasDefault", void 0);
577
+ _defineProperty(this, "TUpdateInput", void 0);
578
+ _defineProperty(this, "TSetInput", void 0);
579
+ _defineProperty(this, "_schema", void 0);
580
+ _defineProperty(this, "_opDefinitions", { set: make({
581
+ kind: "literal.set",
582
+ payload: Schema.Unknown,
583
+ target: Schema.Unknown,
584
+ apply: (payload) => payload
585
+ }) });
586
+ _defineProperty(this, "_internal", {
587
+ createProxy: (env, operationPath) => {
588
+ const defaultValue = this._schema.defaultValue;
589
+ return {
590
+ get: () => {
591
+ const state = env.getState(operationPath);
592
+ return state !== null && state !== void 0 ? state : defaultValue;
593
+ },
594
+ set: (value) => {
595
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
596
+ },
597
+ update: (value) => {
598
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
599
+ },
600
+ toSnapshot: () => {
601
+ const state = env.getState(operationPath);
602
+ return state !== null && state !== void 0 ? state : defaultValue;
603
+ }
604
+ };
605
+ },
606
+ applyOperation: (_state, operation) => {
607
+ if (operation.kind !== "literal.set") throw new ValidationError(`LiteralPrimitive cannot apply operation of kind: ${operation.kind}`);
608
+ const payload = operation.payload;
609
+ if (payload !== this._schema.literal) throw new ValidationError(`LiteralPrimitive.set requires the exact literal value "${globalThis.String(this._schema.literal)}", got: "${globalThis.String(payload)}"`);
610
+ return payload;
611
+ },
612
+ getInitialState: () => {
613
+ return this._schema.defaultValue;
614
+ },
615
+ transformOperation: (clientOp, serverOp) => {
616
+ if (!pathsOverlap(clientOp.path, serverOp.path)) return {
617
+ type: "transformed",
618
+ operation: clientOp
619
+ };
620
+ return {
621
+ type: "transformed",
622
+ operation: clientOp
623
+ };
624
+ }
625
+ });
626
+ this._schema = schema;
627
+ }
628
+ /** Mark this literal as required */
629
+ required() {
630
+ return new LiteralPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
631
+ }
632
+ /** Set a default value for this literal */
633
+ default(defaultValue) {
634
+ return new LiteralPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
635
+ }
636
+ /** Get the literal value this primitive represents */
637
+ get literal() {
638
+ return this._schema.literal;
639
+ }
640
+ };
641
+ /** Creates a new LiteralPrimitive with the given literal value */
642
+ const Literal = (literal) => new LiteralPrimitive({
643
+ required: false,
644
+ defaultValue: void 0,
645
+ literal
646
+ });
647
+
648
+ //#endregion
649
+ //#region src/FractionalIndex.ts
650
+ function createCharSetDicts(charSet) {
651
+ const byCode = {};
652
+ const byChar = {};
653
+ const length = charSet.length;
654
+ for (let i = 0; i < length; i++) {
655
+ const char = charSet[i];
656
+ if (char === void 0) throw new Error("invalid charSet: missing character at index " + i);
657
+ byCode[i] = char;
658
+ byChar[char] = i;
659
+ }
660
+ return {
661
+ byCode,
662
+ byChar,
663
+ length
664
+ };
665
+ }
666
+ function integerLimits(dicts, firstPositive, mostPositive, mostNegative) {
667
+ return Effect.gen(function* () {
668
+ const firstPositiveIndex = firstPositive ? dicts.byChar[firstPositive] : Math.ceil(dicts.length / 2);
669
+ const mostPositiveIndex = mostPositive ? dicts.byChar[mostPositive] : dicts.length - 1;
670
+ const mostNegativeIndex = mostNegative ? dicts.byChar[mostNegative] : 0;
671
+ if (firstPositiveIndex === void 0 || mostPositiveIndex === void 0 || mostNegativeIndex === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid charSet"));
672
+ if (mostPositiveIndex - firstPositiveIndex < 3) return yield* Effect.fail(/* @__PURE__ */ new Error("mostPositive must be at least 3 characters away from neutral"));
673
+ if (firstPositiveIndex - mostNegativeIndex < 3) return yield* Effect.fail(/* @__PURE__ */ new Error("mostNegative must be at least 3 characters away from neutral"));
674
+ const firstPositiveChar = dicts.byCode[firstPositiveIndex];
675
+ const mostPositiveChar = dicts.byCode[mostPositiveIndex];
676
+ const firstNegativeChar = dicts.byCode[firstPositiveIndex - 1];
677
+ const mostNegativeChar = dicts.byCode[mostNegativeIndex];
678
+ if (firstPositiveChar === void 0 || mostPositiveChar === void 0 || firstNegativeChar === void 0 || mostNegativeChar === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid charSet"));
679
+ return {
680
+ firstPositive: firstPositiveChar,
681
+ mostPositive: mostPositiveChar,
682
+ firstNegative: firstNegativeChar,
683
+ mostNegative: mostNegativeChar
684
+ };
685
+ });
686
+ }
687
+ function paddingDict(jitterRange, charSetLength) {
688
+ const paddingDict$1 = {};
689
+ for (let i = 0; i < 100; i++) {
690
+ const value = Math.pow(charSetLength, i);
691
+ paddingDict$1[i] = value;
692
+ if (value > jitterRange) break;
693
+ }
694
+ return paddingDict$1;
695
+ }
696
+ function validateChars(characters) {
697
+ if (characters.length < 7) return Effect.fail(/* @__PURE__ */ new Error("charSet must be at least 7 characters long"));
698
+ if (!(characters.split("").sort().join("") === characters)) return Effect.fail(/* @__PURE__ */ new Error("charSet must be sorted"));
699
+ return Effect.void;
700
+ }
701
+ function indexCharacterSet(options) {
702
+ return Effect.gen(function* () {
703
+ var _options$jitterRange;
704
+ yield* validateChars(options.chars);
705
+ const dicts = createCharSetDicts(options.chars);
706
+ const limits = yield* integerLimits(dicts, options.firstPositive, options.mostPositive, options.mostNegative);
707
+ const jitterRange = (_options$jitterRange = options.jitterRange) !== null && _options$jitterRange !== void 0 ? _options$jitterRange : Math.floor(Math.pow(dicts.length, 3) / 5);
708
+ const paddingRange = paddingDict(jitterRange, dicts.length);
709
+ const first = dicts.byCode[0];
710
+ const last = dicts.byCode[dicts.length - 1];
711
+ if (first === void 0 || last === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid charSet"));
712
+ return {
713
+ chars: options.chars,
714
+ byChar: dicts.byChar,
715
+ byCode: dicts.byCode,
716
+ length: dicts.length,
717
+ first,
718
+ last,
719
+ firstPositive: limits.firstPositive,
720
+ mostPositive: limits.mostPositive,
721
+ firstNegative: limits.firstNegative,
722
+ mostNegative: limits.mostNegative,
723
+ jitterRange,
724
+ paddingDict: paddingRange
725
+ };
726
+ });
727
+ }
728
+ let _base62CharSet = null;
729
+ function base62CharSet() {
730
+ if (_base62CharSet) return _base62CharSet;
731
+ _base62CharSet = Effect.runSync(indexCharacterSet({
732
+ chars: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
733
+ firstPositive: "a",
734
+ mostPositive: "z",
735
+ mostNegative: "A"
736
+ }));
737
+ return _base62CharSet;
738
+ }
739
+ function makeSameLength(a, b, pad, fillChar, forceLength) {
740
+ const max = forceLength !== null && forceLength !== void 0 ? forceLength : Math.max(a.length, b.length);
741
+ if (pad === "start") return [a.padStart(max, fillChar), b.padStart(max, fillChar)];
742
+ return [a.padEnd(max, fillChar), b.padEnd(max, fillChar)];
743
+ }
744
+ function distanceBetween(a, b, charSet) {
745
+ const indexA = charSet.byChar[a];
746
+ const indexB = charSet.byChar[b];
747
+ if (indexA === void 0 || indexB === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character in distance calculation"));
748
+ return Effect.succeed(Math.abs(indexA - indexB));
749
+ }
750
+ function integerLengthFromSecondLevel(key, direction, charSet) {
751
+ if (key.length === 0) return Effect.succeed(0);
752
+ const firstChar = key[0];
753
+ if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) return Effect.fail(/* @__PURE__ */ new Error("invalid firstChar on key"));
754
+ if (firstChar === charSet.mostPositive && direction === "positive") return Effect.gen(function* () {
755
+ const totalPositiveRoom = yield* distanceBetween(firstChar, charSet.mostNegative, charSet);
756
+ const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet);
757
+ return totalPositiveRoom + 1 + rest;
758
+ });
759
+ if (firstChar === charSet.mostNegative && direction === "negative") return Effect.gen(function* () {
760
+ const totalNegativeRoom = yield* distanceBetween(firstChar, charSet.mostPositive, charSet);
761
+ const rest = yield* integerLengthFromSecondLevel(key.slice(1), direction, charSet);
762
+ return totalNegativeRoom + 1 + rest;
763
+ });
764
+ if (direction === "positive") return Effect.gen(function* () {
765
+ return (yield* distanceBetween(firstChar, charSet.mostNegative, charSet)) + 2;
766
+ });
767
+ else return Effect.gen(function* () {
768
+ return (yield* distanceBetween(firstChar, charSet.mostPositive, charSet)) + 2;
769
+ });
770
+ }
771
+ function integerLength(head, charSet) {
772
+ if (head.length === 0) return Effect.fail(/* @__PURE__ */ new Error("head cannot be empty"));
773
+ const firstChar = head[0];
774
+ if (!firstChar || firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) return Effect.fail(/* @__PURE__ */ new Error("invalid firstChar on key"));
775
+ if (firstChar === charSet.mostPositive) return Effect.gen(function* () {
776
+ const firstLevel = yield* distanceBetween(firstChar, charSet.firstPositive, charSet);
777
+ const rest = yield* integerLengthFromSecondLevel(head.slice(1), "positive", charSet);
778
+ return firstLevel + 1 + rest;
779
+ });
780
+ if (firstChar === charSet.mostNegative) return Effect.gen(function* () {
781
+ const firstLevel = yield* distanceBetween(firstChar, charSet.firstNegative, charSet);
782
+ const rest = yield* integerLengthFromSecondLevel(head.slice(1), "negative", charSet);
783
+ return firstLevel + 1 + rest;
784
+ });
785
+ if (firstChar >= charSet.firstPositive) return Effect.gen(function* () {
786
+ return (yield* distanceBetween(firstChar, charSet.firstPositive, charSet)) + 2;
787
+ });
788
+ else return Effect.gen(function* () {
789
+ return (yield* distanceBetween(firstChar, charSet.firstNegative, charSet)) + 2;
790
+ });
791
+ }
792
+ function encodeToCharSet(int, charSet) {
793
+ if (int === 0) {
794
+ const zero = charSet.byCode[0];
795
+ if (zero === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid charSet: missing code 0"));
796
+ return Effect.succeed(zero);
797
+ }
798
+ let res = "";
799
+ const max = charSet.length;
800
+ while (int > 0) {
801
+ const code = charSet.byCode[int % max];
802
+ if (code === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character code in encodeToCharSet"));
803
+ res = code + res;
804
+ int = Math.floor(int / max);
805
+ }
806
+ return Effect.succeed(res);
807
+ }
808
+ function decodeCharSetToNumber(key, charSet) {
809
+ let res = 0;
810
+ const length = key.length;
811
+ const max = charSet.length;
812
+ for (let i = 0; i < length; i++) {
813
+ const char = key[i];
814
+ if (char === void 0) continue;
815
+ const charIndex = charSet.byChar[char];
816
+ if (charIndex === void 0) continue;
817
+ res += charIndex * Math.pow(max, length - i - 1);
818
+ }
819
+ return res;
820
+ }
821
+ function addCharSetKeys(a, b, charSet) {
822
+ const base = charSet.length;
823
+ const [paddedA, paddedB] = makeSameLength(a, b, "start", charSet.first);
824
+ const result = [];
825
+ let carry = 0;
826
+ for (let i = paddedA.length - 1; i >= 0; i--) {
827
+ const charA = paddedA[i];
828
+ const charB = paddedB[i];
829
+ if (!charA || !charB) return Effect.fail(/* @__PURE__ */ new Error("invalid character in addCharSetKeys"));
830
+ const digitA = charSet.byChar[charA];
831
+ const digitB = charSet.byChar[charB];
832
+ if (digitA === void 0 || digitB === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character in addCharSetKeys"));
833
+ const sum = digitA + digitB + carry;
834
+ carry = Math.floor(sum / base);
835
+ const remainder = sum % base;
836
+ const codeChar = charSet.byCode[remainder];
837
+ if (codeChar === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character code in addCharSetKeys"));
838
+ result.unshift(codeChar);
839
+ }
840
+ if (carry > 0) {
841
+ const carryChar = charSet.byCode[carry];
842
+ if (carryChar === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid carry character code"));
843
+ result.unshift(carryChar);
844
+ }
845
+ return Effect.succeed(result.join(""));
846
+ }
847
+ function subtractCharSetKeys(a, b, charSet, stripLeadingZeros = true) {
848
+ const base = charSet.length;
849
+ const [paddedA, paddedB] = makeSameLength(a, b, "start", charSet.first);
850
+ const result = [];
851
+ let borrow = 0;
852
+ for (let i = paddedA.length - 1; i >= 0; i--) {
853
+ const charA = paddedA[i];
854
+ const charB = paddedB[i];
855
+ if (!charA || !charB) return Effect.fail(/* @__PURE__ */ new Error("invalid character in subtractCharSetKeys"));
856
+ let digitA = charSet.byChar[charA];
857
+ const digitBValue = charSet.byChar[charB];
858
+ if (digitA === void 0 || digitBValue === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character in subtractCharSetKeys"));
859
+ const digitB = digitBValue + borrow;
860
+ if (digitA < digitB) {
861
+ borrow = 1;
862
+ digitA += base;
863
+ } else borrow = 0;
864
+ const difference = digitA - digitB;
865
+ const codeChar = charSet.byCode[difference];
866
+ if (codeChar === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid character code in subtractCharSetKeys"));
867
+ result.unshift(codeChar);
868
+ }
869
+ if (borrow > 0) return Effect.fail(/* @__PURE__ */ new Error("Subtraction result is negative. Ensure a is greater than or equal to b."));
870
+ while (stripLeadingZeros && result.length > 1 && result[0] === charSet.first) result.shift();
871
+ return Effect.succeed(result.join(""));
872
+ }
873
+ function incrementKey(key, charSet) {
874
+ const one = charSet.byCode[1];
875
+ if (one === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid charSet: missing code 1"));
876
+ return addCharSetKeys(key, one, charSet);
877
+ }
878
+ function decrementKey(key, charSet) {
879
+ const one = charSet.byCode[1];
880
+ if (one === void 0) return Effect.fail(/* @__PURE__ */ new Error("invalid charSet: missing code 1"));
881
+ return subtractCharSetKeys(key, one, charSet, false);
882
+ }
883
+ function lexicalDistance(a, b, charSet) {
884
+ const [lower, upper] = makeSameLength(a, b, "end", charSet.first).sort();
885
+ return Effect.gen(function* () {
886
+ return decodeCharSetToNumber(yield* subtractCharSetKeys(upper, lower, charSet), charSet);
887
+ });
888
+ }
889
+ function midPoint(lower, upper, charSet) {
890
+ return Effect.gen(function* () {
891
+ let [paddedLower, paddedUpper] = makeSameLength(lower, upper, "end", charSet.first);
892
+ let distance = yield* lexicalDistance(paddedLower, paddedUpper, charSet);
893
+ if (distance === 1) {
894
+ paddedLower = paddedLower.padEnd(paddedLower.length + 1, charSet.first);
895
+ distance = charSet.length;
896
+ }
897
+ const mid = yield* encodeToCharSet(Math.floor(distance / 2), charSet);
898
+ return yield* addCharSetKeys(paddedLower, mid, charSet);
899
+ });
900
+ }
901
+ function startKey(charSet) {
902
+ return charSet.firstPositive + charSet.byCode[0];
903
+ }
904
+ function validInteger(integer, charSet) {
905
+ return Effect.gen(function* () {
906
+ return (yield* integerLength(integer, charSet)) === integer.length;
907
+ });
908
+ }
909
+ function validateOrderKey(orderKey, charSet) {
910
+ return Effect.gen(function* () {
911
+ yield* getIntegerPart(orderKey, charSet);
912
+ });
913
+ }
914
+ function getIntegerPart(orderKey, charSet) {
915
+ return Effect.gen(function* () {
916
+ const integerPartLength = yield* integerLength(integerHead(orderKey, charSet), charSet);
917
+ if (integerPartLength > orderKey.length) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid order key length: " + orderKey));
918
+ return orderKey.slice(0, integerPartLength);
919
+ });
920
+ }
921
+ function validateInteger(integer, charSet) {
922
+ return Effect.gen(function* () {
923
+ if (!(yield* validInteger(integer, charSet))) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid integer length: " + integer));
924
+ });
925
+ }
926
+ function integerHead(integer, charSet) {
927
+ let i = 0;
928
+ if (integer[0] === charSet.mostPositive) while (integer[i] === charSet.mostPositive) i = i + 1;
929
+ if (integer[0] === charSet.mostNegative) while (integer[i] === charSet.mostNegative) i = i + 1;
930
+ return integer.slice(0, i + 1);
931
+ }
932
+ function splitInteger(integer, charSet) {
933
+ return Effect.gen(function* () {
934
+ const head = integerHead(integer, {
935
+ firstPositive: charSet.firstPositive,
936
+ mostPositive: charSet.mostPositive,
937
+ firstNegative: charSet.firstNegative,
938
+ mostNegative: charSet.mostNegative
939
+ });
940
+ return [head, integer.slice(head.length)];
941
+ });
942
+ }
943
+ function incrementIntegerHead(head, charSet) {
944
+ return Effect.gen(function* () {
945
+ const inPositiveRange = head >= charSet.firstPositive;
946
+ const nextHead = yield* incrementKey(head, charSet);
947
+ const headIsLimitMax = head[head.length - 1] === charSet.mostPositive;
948
+ const nextHeadIsLimitMax = nextHead[nextHead.length - 1] === charSet.mostPositive;
949
+ if (inPositiveRange && nextHeadIsLimitMax) return nextHead + charSet.mostNegative;
950
+ if (!inPositiveRange && headIsLimitMax) return head.slice(0, head.length - 1);
951
+ return nextHead;
952
+ });
953
+ }
954
+ function decrementIntegerHead(head, charSet) {
955
+ return Effect.gen(function* () {
956
+ const inPositiveRange = head >= charSet.firstPositive;
957
+ const headIsLimitMin = head[head.length - 1] === charSet.mostNegative;
958
+ if (inPositiveRange && headIsLimitMin) return yield* decrementKey(head.slice(0, head.length - 1), charSet);
959
+ if (!inPositiveRange && headIsLimitMin) return head + charSet.mostPositive;
960
+ return yield* decrementKey(head, charSet);
961
+ });
962
+ }
963
+ function startOnNewHead(head, limit, charSet) {
964
+ return Effect.gen(function* () {
965
+ const newLength = yield* integerLength(head, charSet);
966
+ const fillCharCode = limit === "upper" ? charSet.length - 1 : 0;
967
+ const fillChar = charSet.byCode[fillCharCode];
968
+ if (fillChar === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid fill character code"));
969
+ return head + fillChar.repeat(newLength - head.length);
970
+ });
971
+ }
972
+ function incrementInteger(integer, charSet) {
973
+ return Effect.gen(function* () {
974
+ yield* validateInteger(integer, charSet);
975
+ const [head, digs] = yield* splitInteger(integer, charSet);
976
+ const maxChar = charSet.byCode[charSet.length - 1];
977
+ if (maxChar === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid charSet: missing max character"));
978
+ if (digs.split("").some((d) => d !== maxChar)) return head + (yield* incrementKey(digs, charSet));
979
+ return yield* startOnNewHead(yield* incrementIntegerHead(head, charSet), "lower", charSet);
980
+ });
981
+ }
982
+ function decrementInteger(integer, charSet) {
983
+ return Effect.gen(function* () {
984
+ yield* validateInteger(integer, charSet);
985
+ const [head, digs] = yield* splitInteger(integer, charSet);
986
+ const minChar = charSet.byCode[0];
987
+ if (minChar === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error("invalid charSet: missing min character"));
988
+ if (digs.split("").some((d) => d !== minChar)) return head + (yield* decrementKey(digs, charSet));
989
+ return yield* startOnNewHead(yield* decrementIntegerHead(head, charSet), "upper", charSet);
990
+ });
991
+ }
992
+ /**
993
+ * Generate a key between two other keys.
994
+ * If either lower or upper is null, the key will be generated at the start or end of the list.
995
+ */
996
+ function generateKeyBetween(lower, upper, charSet = base62CharSet()) {
997
+ return Effect.gen(function* () {
998
+ if (lower !== null) yield* validateOrderKey(lower, charSet);
999
+ if (upper !== null) yield* validateOrderKey(upper, charSet);
1000
+ if (lower === null && upper === null) return startKey(charSet);
1001
+ if (lower === null) return yield* decrementInteger(yield* getIntegerPart(upper, charSet), charSet);
1002
+ if (upper === null) return yield* incrementInteger(yield* getIntegerPart(lower, charSet), charSet);
1003
+ if (lower >= upper) return yield* Effect.fail(/* @__PURE__ */ new Error(lower + " >= " + upper));
1004
+ return yield* midPoint(lower, upper, charSet);
1005
+ });
1006
+ }
1007
+
1008
+ //#endregion
1009
+ //#region src/primitives/Array.ts
1010
+ /**
1011
+ * Sort array entries by their fractional position
1012
+ */
1013
+ const sortByPos = (entries) => [...entries].sort((a, b) => a.pos < b.pos ? -1 : a.pos > b.pos ? 1 : 0);
1014
+ /**
1015
+ * Generate a fractional position between two positions
1016
+ */
1017
+ const generatePosBetween = (left, right) => {
1018
+ const charSet = base62CharSet();
1019
+ return Effect.runSync(generateKeyBetween(left, right, charSet));
1020
+ };
1021
+ var ArrayPrimitive = class ArrayPrimitive {
1022
+ constructor(schema) {
1023
+ _defineProperty(this, "_tag", "ArrayPrimitive");
1024
+ _defineProperty(this, "_State", void 0);
1025
+ _defineProperty(this, "_Proxy", void 0);
1026
+ _defineProperty(this, "_TRequired", void 0);
1027
+ _defineProperty(this, "_THasDefault", void 0);
1028
+ _defineProperty(this, "TSetInput", void 0);
1029
+ _defineProperty(this, "TUpdateInput", void 0);
1030
+ _defineProperty(this, "_schema", void 0);
1031
+ _defineProperty(this, "_opDefinitions", {
1032
+ set: make({
1033
+ kind: "array.set",
1034
+ payload: Schema.Unknown,
1035
+ target: Schema.Unknown,
1036
+ apply: (payload) => payload
1037
+ }),
1038
+ insert: make({
1039
+ kind: "array.insert",
1040
+ payload: Schema.Unknown,
1041
+ target: Schema.Unknown,
1042
+ apply: (payload) => payload
1043
+ }),
1044
+ remove: make({
1045
+ kind: "array.remove",
1046
+ payload: Schema.Unknown,
1047
+ target: Schema.Unknown,
1048
+ apply: (payload) => payload
1049
+ }),
1050
+ move: make({
1051
+ kind: "array.move",
1052
+ payload: Schema.Unknown,
1053
+ target: Schema.Unknown,
1054
+ apply: (payload) => payload
1055
+ })
1056
+ });
1057
+ _defineProperty(this, "_internal", {
1058
+ createProxy: (env, operationPath) => {
1059
+ const elementPrimitive = this._schema.element;
1060
+ const getCurrentState = () => {
1061
+ const state = env.getState(operationPath);
1062
+ if (!state || !globalThis.Array.isArray(state)) return [];
1063
+ return sortByPos(state);
1064
+ };
1065
+ const applyElementDefaults = (value) => {
1066
+ return applyDefaults(elementPrimitive, value);
1067
+ };
1068
+ return {
1069
+ get: () => {
1070
+ return getCurrentState();
1071
+ },
1072
+ set: (values) => {
1073
+ const entries = [];
1074
+ let prevPos = null;
1075
+ for (const value of values) {
1076
+ const id = env.generateId();
1077
+ const pos = generatePosBetween(prevPos, null);
1078
+ const mergedValue = applyElementDefaults(value);
1079
+ entries.push({
1080
+ id,
1081
+ pos,
1082
+ value: mergedValue
1083
+ });
1084
+ prevPos = pos;
1085
+ }
1086
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, entries));
1087
+ },
1088
+ push: (value) => {
1089
+ const sorted = getCurrentState();
1090
+ const lastPos = sorted.length > 0 ? sorted[sorted.length - 1].pos : null;
1091
+ const id = env.generateId();
1092
+ const pos = generatePosBetween(lastPos, null);
1093
+ const mergedValue = applyElementDefaults(value);
1094
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1095
+ id,
1096
+ pos,
1097
+ value: mergedValue
1098
+ }));
1099
+ },
1100
+ insertAt: (index, value) => {
1101
+ const sorted = getCurrentState();
1102
+ const leftPos = index > 0 && sorted[index - 1] ? sorted[index - 1].pos : null;
1103
+ const rightPos = index < sorted.length && sorted[index] ? sorted[index].pos : null;
1104
+ const id = env.generateId();
1105
+ const pos = generatePosBetween(leftPos, rightPos);
1106
+ const mergedValue = applyElementDefaults(value);
1107
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1108
+ id,
1109
+ pos,
1110
+ value: mergedValue
1111
+ }));
1112
+ },
1113
+ remove: (id) => {
1114
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.remove, { id }));
1115
+ },
1116
+ move: (id, toIndex) => {
1117
+ const without = getCurrentState().filter((e) => e.id !== id);
1118
+ const clampedIndex = Math.max(0, Math.min(toIndex, without.length));
1119
+ const pos = generatePosBetween(clampedIndex > 0 && without[clampedIndex - 1] ? without[clampedIndex - 1].pos : null, clampedIndex < without.length && without[clampedIndex] ? without[clampedIndex].pos : null);
1120
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
1121
+ id,
1122
+ pos
1123
+ }));
1124
+ },
1125
+ at: (id) => {
1126
+ const elementPath = operationPath.append(id);
1127
+ return elementPrimitive._internal.createProxy(env, elementPath);
1128
+ },
1129
+ find: (predicate) => {
1130
+ const found = getCurrentState().find((entry) => predicate(entry.value, entry.id));
1131
+ if (!found) return void 0;
1132
+ const elementPath = operationPath.append(found.id);
1133
+ return elementPrimitive._internal.createProxy(env, elementPath);
1134
+ },
1135
+ toSnapshot: () => {
1136
+ return getCurrentState().map((entry) => {
1137
+ const elementPath = operationPath.append(entry.id);
1138
+ const elementProxy = elementPrimitive._internal.createProxy(env, elementPath);
1139
+ return {
1140
+ id: entry.id,
1141
+ value: elementProxy.toSnapshot()
1142
+ };
1143
+ });
1144
+ }
1145
+ };
1146
+ },
1147
+ applyOperation: (state, operation) => {
1148
+ const path = operation.path;
1149
+ const tokens = path.toTokens().filter((t) => t !== "");
1150
+ const currentState = state !== null && state !== void 0 ? state : [];
1151
+ let newState;
1152
+ if (tokens.length === 0) switch (operation.kind) {
1153
+ case "array.set": {
1154
+ const payload = operation.payload;
1155
+ if (!globalThis.Array.isArray(payload)) throw new ValidationError(`ArrayPrimitive.set requires an array payload`);
1156
+ newState = payload;
1157
+ break;
1158
+ }
1159
+ case "array.insert": {
1160
+ const { id, pos, value } = operation.payload;
1161
+ newState = [...currentState, {
1162
+ id,
1163
+ pos,
1164
+ value
1165
+ }];
1166
+ break;
1167
+ }
1168
+ case "array.remove": {
1169
+ const { id } = operation.payload;
1170
+ newState = currentState.filter((entry) => entry.id !== id);
1171
+ break;
1172
+ }
1173
+ case "array.move": {
1174
+ const { id, pos } = operation.payload;
1175
+ newState = currentState.map((entry) => entry.id === id ? _objectSpread2(_objectSpread2({}, entry), {}, { pos }) : entry);
1176
+ break;
1177
+ }
1178
+ default: throw new ValidationError(`ArrayPrimitive cannot apply operation of kind: ${operation.kind}`);
1179
+ }
1180
+ else {
1181
+ const elementId = tokens[0];
1182
+ const entryIndex = currentState.findIndex((entry) => entry.id === elementId);
1183
+ if (entryIndex === -1) throw new ValidationError(`Array element not found with ID: ${elementId}`);
1184
+ const elementPrimitive = this._schema.element;
1185
+ const remainingPath = path.shift();
1186
+ const elementOperation = _objectSpread2(_objectSpread2({}, operation), {}, { path: remainingPath });
1187
+ const currentEntry = currentState[entryIndex];
1188
+ const newValue = elementPrimitive._internal.applyOperation(currentEntry.value, elementOperation);
1189
+ const mutableState = [...currentState];
1190
+ mutableState[entryIndex] = _objectSpread2(_objectSpread2({}, currentEntry), {}, { value: newValue });
1191
+ newState = mutableState;
1192
+ }
1193
+ runValidators(newState, this._schema.validators);
1194
+ return newState;
1195
+ },
1196
+ getInitialState: () => {
1197
+ return this._schema.defaultValue;
1198
+ },
1199
+ transformOperation: (clientOp, serverOp) => {
1200
+ const clientPath = clientOp.path;
1201
+ const serverPath = serverOp.path;
1202
+ if (!pathsOverlap(clientPath, serverPath)) return {
1203
+ type: "transformed",
1204
+ operation: clientOp
1205
+ };
1206
+ if (serverOp.kind === "array.remove") {
1207
+ const removedId = serverOp.payload.id;
1208
+ const clientTokens$1 = clientPath.toTokens().filter((t) => t !== "");
1209
+ const serverTokens$1 = serverPath.toTokens().filter((t) => t !== "");
1210
+ if (clientTokens$1.length > serverTokens$1.length) {
1211
+ if (clientTokens$1[serverTokens$1.length] === removedId) return { type: "noop" };
1212
+ }
1213
+ }
1214
+ if (serverOp.kind === "array.insert" && clientOp.kind === "array.insert") return {
1215
+ type: "transformed",
1216
+ operation: clientOp
1217
+ };
1218
+ if (serverOp.kind === "array.move" && clientOp.kind === "array.move") {
1219
+ if (serverOp.payload.id === clientOp.payload.id) return {
1220
+ type: "transformed",
1221
+ operation: clientOp
1222
+ };
1223
+ return {
1224
+ type: "transformed",
1225
+ operation: clientOp
1226
+ };
1227
+ }
1228
+ if (pathsEqual(clientPath, serverPath)) return {
1229
+ type: "transformed",
1230
+ operation: clientOp
1231
+ };
1232
+ if (serverOp.kind === "array.set" && isPrefix(serverPath, clientPath)) return {
1233
+ type: "transformed",
1234
+ operation: clientOp
1235
+ };
1236
+ const clientTokens = clientPath.toTokens().filter((t) => t !== "");
1237
+ const serverTokens = serverPath.toTokens().filter((t) => t !== "");
1238
+ if (clientTokens.length > 0 && serverTokens.length > 0) {
1239
+ if (clientTokens[0] !== serverTokens[0]) return {
1240
+ type: "transformed",
1241
+ operation: clientOp
1242
+ };
1243
+ const elementPrimitive = this._schema.element;
1244
+ const clientOpForElement = _objectSpread2(_objectSpread2({}, clientOp), {}, { path: clientOp.path.shift() });
1245
+ const serverOpForElement = _objectSpread2(_objectSpread2({}, serverOp), {}, { path: serverOp.path.shift() });
1246
+ const result = elementPrimitive._internal.transformOperation(clientOpForElement, serverOpForElement);
1247
+ if (result.type === "transformed") return {
1248
+ type: "transformed",
1249
+ operation: _objectSpread2(_objectSpread2({}, result.operation), {}, { path: clientOp.path })
1250
+ };
1251
+ return result;
1252
+ }
1253
+ return {
1254
+ type: "transformed",
1255
+ operation: clientOp
1256
+ };
1257
+ }
1258
+ });
1259
+ this._schema = schema;
1260
+ }
1261
+ /** Mark this array as required */
1262
+ required() {
1263
+ return new ArrayPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
1264
+ }
1265
+ /** Set a default value for this array */
1266
+ default(defaultValue) {
1267
+ return new ArrayPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
1268
+ }
1269
+ /** Get the element primitive */
1270
+ get element() {
1271
+ return this._schema.element;
1272
+ }
1273
+ /** Add a custom validation rule */
1274
+ refine(fn, message) {
1275
+ return new ArrayPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
1276
+ validate: fn,
1277
+ message
1278
+ }] }));
1279
+ }
1280
+ /** Minimum array length */
1281
+ minLength(length) {
1282
+ return this.refine((v) => v.length >= length, `Array must have at least ${length} elements`);
1283
+ }
1284
+ /** Maximum array length */
1285
+ maxLength(length) {
1286
+ return this.refine((v) => v.length <= length, `Array must have at most ${length} elements`);
1287
+ }
1288
+ };
1289
+ /** Creates a new ArrayPrimitive with the given element type */
1290
+ const Array$1 = (element) => new ArrayPrimitive({
1291
+ required: false,
1292
+ defaultValue: void 0,
1293
+ element,
1294
+ validators: []
1295
+ });
1296
+
1297
+ //#endregion
1298
+ //#region src/primitives/Lazy.ts
1299
+ var LazyPrimitive = class {
1300
+ constructor(thunk) {
1301
+ _defineProperty(this, "_tag", "LazyPrimitive");
1302
+ _defineProperty(this, "_State", void 0);
1303
+ _defineProperty(this, "_Proxy", void 0);
1304
+ _defineProperty(this, "_TRequired", void 0);
1305
+ _defineProperty(this, "_THasDefault", void 0);
1306
+ _defineProperty(this, "TSetInput", void 0);
1307
+ _defineProperty(this, "TUpdateInput", void 0);
1308
+ _defineProperty(this, "_thunk", void 0);
1309
+ _defineProperty(this, "_resolved", void 0);
1310
+ _defineProperty(this, "_internal", {
1311
+ createProxy: (env, operationPath) => {
1312
+ return this._resolve()._internal.createProxy(env, operationPath);
1313
+ },
1314
+ applyOperation: (state, operation) => {
1315
+ return this._resolve()._internal.applyOperation(state, operation);
1316
+ },
1317
+ getInitialState: () => {
1318
+ return this._resolve()._internal.getInitialState();
1319
+ },
1320
+ transformOperation: (clientOp, serverOp) => {
1321
+ return this._resolve()._internal.transformOperation(clientOp, serverOp);
1322
+ }
1323
+ });
1324
+ this._thunk = thunk;
1325
+ }
1326
+ /** Resolve and cache the lazy primitive */
1327
+ _resolve() {
1328
+ if (this._resolved === void 0) this._resolved = this._thunk();
1329
+ return this._resolved;
1330
+ }
1331
+ /** Mark this lazy primitive as required (delegates to resolved) */
1332
+ required() {
1333
+ return this;
1334
+ }
1335
+ };
1336
+ /** Creates a new LazyPrimitive with the given thunk */
1337
+ const Lazy = (thunk) => new LazyPrimitive(thunk);
1338
+
1339
+ //#endregion
1340
+ //#region src/primitives/Union.ts
1341
+ var UnionPrimitive = class UnionPrimitive {
1342
+ constructor(schema) {
1343
+ _defineProperty(this, "_tag", "UnionPrimitive");
1344
+ _defineProperty(this, "_State", void 0);
1345
+ _defineProperty(this, "_Proxy", void 0);
1346
+ _defineProperty(this, "_TRequired", void 0);
1347
+ _defineProperty(this, "_THasDefault", void 0);
1348
+ _defineProperty(this, "TSetInput", void 0);
1349
+ _defineProperty(this, "TUpdateInput", void 0);
1350
+ _defineProperty(this, "_schema", void 0);
1351
+ _defineProperty(this, "_opDefinitions", { set: make({
1352
+ kind: "union.set",
1353
+ payload: Schema.Unknown,
1354
+ target: Schema.Unknown,
1355
+ apply: (payload) => payload
1356
+ }) });
1357
+ _defineProperty(this, "_internal", {
1358
+ createProxy: (env, operationPath) => {
1359
+ const variants = this._schema.variants;
1360
+ const defaultValue = this._schema.defaultValue;
1361
+ return {
1362
+ get: () => {
1363
+ const state = env.getState(operationPath);
1364
+ return state !== null && state !== void 0 ? state : defaultValue;
1365
+ },
1366
+ set: (value) => {
1367
+ const merged = this._applyVariantDefaults(value);
1368
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, merged));
1369
+ },
1370
+ as: (variant) => {
1371
+ const variantPrimitive = variants[variant];
1372
+ if (!variantPrimitive) throw new ValidationError(`Unknown variant: ${globalThis.String(variant)}`);
1373
+ return variantPrimitive._internal.createProxy(env, operationPath);
1374
+ },
1375
+ match: (handlers) => {
1376
+ const state = env.getState(operationPath);
1377
+ if (!state) return void 0;
1378
+ const variantKey = this._findVariantKey(state);
1379
+ if (!variantKey) return void 0;
1380
+ const handler = handlers[variantKey];
1381
+ if (!handler) return void 0;
1382
+ return handler(variants[variantKey]._internal.createProxy(env, operationPath));
1383
+ },
1384
+ toSnapshot: () => {
1385
+ const state = env.getState(operationPath);
1386
+ const effectiveState = state !== null && state !== void 0 ? state : defaultValue;
1387
+ if (!effectiveState) return;
1388
+ const variantKey = this._findVariantKey(effectiveState);
1389
+ if (!variantKey) return;
1390
+ return variants[variantKey]._internal.createProxy(env, operationPath).toSnapshot();
1391
+ }
1392
+ };
1393
+ },
1394
+ applyOperation: (state, operation) => {
1395
+ if (operation.path.toTokens().filter((t) => t !== "").length === 0) {
1396
+ if (operation.kind !== "union.set") throw new ValidationError(`UnionPrimitive root cannot apply operation of kind: ${operation.kind}`);
1397
+ const payload = operation.payload;
1398
+ if (typeof payload !== "object" || payload === null) throw new ValidationError(`UnionPrimitive.set requires an object payload`);
1399
+ if (payload[this._schema.discriminator] === void 0) throw new ValidationError(`UnionPrimitive.set requires a "${this._schema.discriminator}" discriminator field`);
1400
+ return payload;
1401
+ }
1402
+ if (state === void 0) throw new ValidationError(`Cannot apply nested operation to undefined union state`);
1403
+ const variantKey = this._findVariantKey(state);
1404
+ if (variantKey === void 0) throw new ValidationError(`Cannot determine active variant from state`);
1405
+ return this._schema.variants[variantKey]._internal.applyOperation(state, operation);
1406
+ },
1407
+ getInitialState: () => {
1408
+ return this._schema.defaultValue;
1409
+ },
1410
+ transformOperation: (clientOp, serverOp) => {
1411
+ const clientPath = clientOp.path;
1412
+ const serverPath = serverOp.path;
1413
+ if (!pathsOverlap(clientPath, serverPath)) return {
1414
+ type: "transformed",
1415
+ operation: clientOp
1416
+ };
1417
+ const clientTokens = clientPath.toTokens().filter((t) => t !== "");
1418
+ const serverTokens = serverPath.toTokens().filter((t) => t !== "");
1419
+ if (clientTokens.length === 0 && serverTokens.length === 0) return {
1420
+ type: "transformed",
1421
+ operation: clientOp
1422
+ };
1423
+ if (serverTokens.length === 0 && serverOp.kind === "union.set") return {
1424
+ type: "transformed",
1425
+ operation: clientOp
1426
+ };
1427
+ if (clientTokens.length === 0 && clientOp.kind === "union.set") return {
1428
+ type: "transformed",
1429
+ operation: clientOp
1430
+ };
1431
+ if (clientTokens.length > 0 && serverTokens.length > 0) {
1432
+ if (clientTokens[0] !== serverTokens[0]) return {
1433
+ type: "transformed",
1434
+ operation: clientOp
1435
+ };
1436
+ const variantKeys = Object.keys(this._schema.variants);
1437
+ if (variantKeys.length === 0) return {
1438
+ type: "transformed",
1439
+ operation: clientOp
1440
+ };
1441
+ return this._schema.variants[variantKeys[0]]._internal.transformOperation(clientOp, serverOp);
1442
+ }
1443
+ return {
1444
+ type: "transformed",
1445
+ operation: clientOp
1446
+ };
1447
+ }
1448
+ });
1449
+ this._schema = schema;
1450
+ }
1451
+ /** Mark this union as required */
1452
+ required() {
1453
+ return new UnionPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
1454
+ }
1455
+ /** Set a default value for this union */
1456
+ default(defaultValue) {
1457
+ const merged = this._applyVariantDefaults(defaultValue);
1458
+ return new UnionPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue: merged }));
1459
+ }
1460
+ /** Get the discriminator field name */
1461
+ get discriminator() {
1462
+ return this._schema.discriminator;
1463
+ }
1464
+ /** Get the variants */
1465
+ get variants() {
1466
+ return this._schema.variants;
1467
+ }
1468
+ /** Find the variant key from a state value */
1469
+ _findVariantKey(state) {
1470
+ if (typeof state !== "object" || state === null) return;
1471
+ const discriminatorValue = state[this._schema.discriminator];
1472
+ for (const key in this._schema.variants) {
1473
+ const discriminatorField = this._schema.variants[key].fields[this._schema.discriminator];
1474
+ if (discriminatorField && discriminatorField._tag === "LiteralPrimitive") {
1475
+ if (discriminatorField.literal === discriminatorValue) return key;
1476
+ }
1477
+ }
1478
+ }
1479
+ /** Apply defaults to a variant value based on the discriminator */
1480
+ _applyVariantDefaults(value) {
1481
+ const variantKey = this._findVariantKey(value);
1482
+ if (!variantKey) return value;
1483
+ const variantPrimitive = this._schema.variants[variantKey];
1484
+ return applyDefaults(variantPrimitive, value);
1485
+ }
1486
+ };
1487
+ function Union(options) {
1488
+ var _options$discriminato;
1489
+ return new UnionPrimitive({
1490
+ required: false,
1491
+ defaultValue: void 0,
1492
+ discriminator: (_options$discriminato = options.discriminator) !== null && _options$discriminato !== void 0 ? _options$discriminato : "type",
1493
+ variants: options.variants
1494
+ });
1495
+ }
1496
+
1497
+ //#endregion
1498
+ //#region src/primitives/Either.ts
1499
+ var EitherPrimitive = class EitherPrimitive {
1500
+ constructor(schema) {
1501
+ _defineProperty(this, "_tag", "EitherPrimitive");
1502
+ _defineProperty(this, "_State", void 0);
1503
+ _defineProperty(this, "_Proxy", void 0);
1504
+ _defineProperty(this, "_TRequired", void 0);
1505
+ _defineProperty(this, "_THasDefault", void 0);
1506
+ _defineProperty(this, "TUpdateInput", void 0);
1507
+ _defineProperty(this, "TSetInput", void 0);
1508
+ _defineProperty(this, "_schema", void 0);
1509
+ _defineProperty(this, "_opDefinitions", { set: make({
1510
+ kind: "either.set",
1511
+ payload: Schema.Unknown,
1512
+ target: Schema.Unknown,
1513
+ apply: (payload) => payload
1514
+ }) });
1515
+ _defineProperty(this, "_internal", {
1516
+ createProxy: (env, operationPath) => {
1517
+ const defaultValue = this._schema.defaultValue;
1518
+ return {
1519
+ get: () => {
1520
+ const state = env.getState(operationPath);
1521
+ return state !== null && state !== void 0 ? state : defaultValue;
1522
+ },
1523
+ set: (value) => {
1524
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
1525
+ },
1526
+ update: (value) => {
1527
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, value));
1528
+ },
1529
+ match: (handlers) => {
1530
+ const currentState = env.getState(operationPath);
1531
+ const effectiveState = currentState !== null && currentState !== void 0 ? currentState : defaultValue;
1532
+ if (effectiveState === void 0) return void 0;
1533
+ const valueType = this._getValueType(effectiveState);
1534
+ if (!valueType) return void 0;
1535
+ switch (valueType) {
1536
+ case "string":
1537
+ var _handlers$string;
1538
+ return (_handlers$string = handlers.string) === null || _handlers$string === void 0 ? void 0 : _handlers$string.call(handlers, effectiveState);
1539
+ case "number":
1540
+ var _handlers$number;
1541
+ return (_handlers$number = handlers.number) === null || _handlers$number === void 0 ? void 0 : _handlers$number.call(handlers, effectiveState);
1542
+ case "boolean":
1543
+ var _handlers$boolean;
1544
+ return (_handlers$boolean = handlers.boolean) === null || _handlers$boolean === void 0 ? void 0 : _handlers$boolean.call(handlers, effectiveState);
1545
+ case "literal":
1546
+ var _handlers$literal;
1547
+ return (_handlers$literal = handlers.literal) === null || _handlers$literal === void 0 ? void 0 : _handlers$literal.call(handlers, effectiveState);
1548
+ default: return;
1549
+ }
1550
+ },
1551
+ toSnapshot: () => {
1552
+ const state = env.getState(operationPath);
1553
+ return state !== null && state !== void 0 ? state : defaultValue;
1554
+ }
1555
+ };
1556
+ },
1557
+ applyOperation: (_state, operation) => {
1558
+ if (operation.kind !== "either.set") throw new ValidationError(`EitherPrimitive cannot apply operation of kind: ${operation.kind}`);
1559
+ const payload = operation.payload;
1560
+ this._validateAndApplyToVariant(payload, operation.path);
1561
+ return payload;
1562
+ },
1563
+ getInitialState: () => {
1564
+ return this._schema.defaultValue;
1565
+ },
1566
+ transformOperation: (clientOp, serverOp) => {
1567
+ if (!pathsOverlap(clientOp.path, serverOp.path)) return {
1568
+ type: "transformed",
1569
+ operation: clientOp
1570
+ };
1571
+ return {
1572
+ type: "transformed",
1573
+ operation: clientOp
1574
+ };
1575
+ }
1576
+ });
1577
+ this._schema = schema;
1578
+ }
1579
+ /** Mark this either as required */
1580
+ required() {
1581
+ return new EitherPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
1582
+ }
1583
+ /** Set a default value for this either */
1584
+ default(defaultValue) {
1585
+ return new EitherPrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
1586
+ }
1587
+ /** Get the variants */
1588
+ get variants() {
1589
+ return this._schema.variants;
1590
+ }
1591
+ /**
1592
+ * Determine the type category of a value based on the variants
1593
+ */
1594
+ _getValueType(value) {
1595
+ const valueType = typeof value;
1596
+ for (const variant of this._schema.variants) if (variant._tag === "LiteralPrimitive") {
1597
+ if (value === variant.literal) return "literal";
1598
+ }
1599
+ if (valueType === "string") {
1600
+ for (const variant of this._schema.variants) if (variant._tag === "StringPrimitive") return "string";
1601
+ }
1602
+ if (valueType === "number") {
1603
+ for (const variant of this._schema.variants) if (variant._tag === "NumberPrimitive") return "number";
1604
+ }
1605
+ if (valueType === "boolean") {
1606
+ for (const variant of this._schema.variants) if (variant._tag === "BooleanPrimitive") return "boolean";
1607
+ }
1608
+ }
1609
+ /**
1610
+ * Find the matching variant for a value.
1611
+ * For literals, matches exact value. For other types, matches by typeof.
1612
+ */
1613
+ _findMatchingVariant(value) {
1614
+ const valueType = typeof value;
1615
+ for (const variant of this._schema.variants) if (variant._tag === "LiteralPrimitive") {
1616
+ if (value === variant.literal) return variant;
1617
+ }
1618
+ if (valueType === "string") {
1619
+ for (const variant of this._schema.variants) if (variant._tag === "StringPrimitive") return variant;
1620
+ }
1621
+ if (valueType === "number") {
1622
+ for (const variant of this._schema.variants) if (variant._tag === "NumberPrimitive") return variant;
1623
+ }
1624
+ if (valueType === "boolean") {
1625
+ for (const variant of this._schema.variants) if (variant._tag === "BooleanPrimitive") return variant;
1626
+ }
1627
+ }
1628
+ /**
1629
+ * Get the operation kind for a variant
1630
+ */
1631
+ _getVariantOperationKind(variant) {
1632
+ switch (variant._tag) {
1633
+ case "StringPrimitive": return "string.set";
1634
+ case "NumberPrimitive": return "number.set";
1635
+ case "BooleanPrimitive": return "boolean.set";
1636
+ case "LiteralPrimitive": return "literal.set";
1637
+ default: return "unknown.set";
1638
+ }
1639
+ }
1640
+ /**
1641
+ * Validate a value against the matching variant, including running its validators.
1642
+ * Throws ValidationError if the value doesn't match any variant or fails validation.
1643
+ */
1644
+ _validateAndApplyToVariant(value, path) {
1645
+ const matchingVariant = this._findMatchingVariant(value);
1646
+ if (!matchingVariant) throw new ValidationError(`EitherPrimitive.set requires a value matching one of: ${this._schema.variants.map((v) => v._tag).join(", ")}, got: ${typeof value}`);
1647
+ const syntheticOp = {
1648
+ kind: this._getVariantOperationKind(matchingVariant),
1649
+ path,
1650
+ payload: value
1651
+ };
1652
+ matchingVariant._internal.applyOperation(void 0, syntheticOp);
1653
+ }
1654
+ };
1655
+ /**
1656
+ * Creates a new EitherPrimitive with the given scalar variant types.
1657
+ * Validators defined on the variants are applied when validating values.
1658
+ *
1659
+ * @example
1660
+ * ```typescript
1661
+ * // String or number
1662
+ * const value = Either(String(), Number());
1663
+ *
1664
+ * // String, number, or boolean
1665
+ * const status = Either(String(), Number(), Boolean()).default("pending");
1666
+ *
1667
+ * // With literal types
1668
+ * const mode = Either(Literal("auto"), Literal("manual"), Number());
1669
+ *
1670
+ * // With validators - validates string length and number range
1671
+ * const constrained = Either(
1672
+ * String().min(2).max(50),
1673
+ * Number().max(255)
1674
+ * );
1675
+ * ```
1676
+ */
1677
+ function Either(...variants) {
1678
+ if (variants.length === 0) throw new ValidationError("Either requires at least one variant");
1679
+ return new EitherPrimitive({
1680
+ required: false,
1681
+ defaultValue: void 0,
1682
+ variants
1683
+ });
1684
+ }
1685
+
1686
+ //#endregion
1687
+ //#region src/primitives/TreeNode.ts
1688
+ /**
1689
+ * Symbol used to identify the Self placeholder
1690
+ */
1691
+ const TreeNodeSelfSymbol = Symbol.for("TreeNode.Self");
1692
+ /**
1693
+ * Special placeholder for self-referential tree nodes.
1694
+ * Use this in the children array when a node type can contain itself.
1695
+ *
1696
+ * @example
1697
+ * ```typescript
1698
+ * const FolderNode = TreeNode("folder", {
1699
+ * data: Struct({ name: String() }),
1700
+ * children: [TreeNodeSelf], // Folder can contain other folders
1701
+ * });
1702
+ * ```
1703
+ */
1704
+ const TreeNodeSelf = {
1705
+ _tag: "TreeNodeSelf",
1706
+ _symbol: TreeNodeSelfSymbol
1707
+ };
1708
+ /**
1709
+ * Check if a value is the Self placeholder
1710
+ */
1711
+ const isSelf = (value) => {
1712
+ return typeof value === "object" && value !== null && "_symbol" in value && value._symbol === TreeNodeSelfSymbol;
1713
+ };
1714
+ /**
1715
+ * TreeNodePrimitive - defines a node type with its data schema and allowed children
1716
+ */
1717
+ var TreeNodePrimitive = class {
1718
+ constructor(type, config) {
1719
+ _defineProperty(this, "_tag", "TreeNodePrimitive");
1720
+ _defineProperty(this, "_Type", void 0);
1721
+ _defineProperty(this, "_Data", void 0);
1722
+ _defineProperty(this, "_Children", void 0);
1723
+ _defineProperty(this, "TSetInput", void 0);
1724
+ _defineProperty(this, "TUpdateInput", void 0);
1725
+ _defineProperty(this, "_type", void 0);
1726
+ _defineProperty(this, "_data", void 0);
1727
+ _defineProperty(this, "_children", void 0);
1728
+ _defineProperty(this, "_resolvedChildren", void 0);
1729
+ this._type = type;
1730
+ this._data = config.data;
1731
+ this._children = config.children;
1732
+ }
1733
+ /** Get the node type identifier */
1734
+ get type() {
1735
+ return this._type;
1736
+ }
1737
+ /** Get the data primitive */
1738
+ get data() {
1739
+ return this._data;
1740
+ }
1741
+ /** Get resolved children (resolves lazy thunk if needed, replaces Self with this node) */
1742
+ get children() {
1743
+ if (this._resolvedChildren === void 0) this._resolvedChildren = (typeof this._children === "function" ? this._children() : this._children).map((child) => isSelf(child) ? this : child);
1744
+ return this._resolvedChildren;
1745
+ }
1746
+ /** Check if a child type is allowed */
1747
+ isChildAllowed(childType) {
1748
+ return this.children.some((child) => child.type === childType);
1749
+ }
1750
+ };
1751
+ /** Creates a new TreeNodePrimitive with the given type and config */
1752
+ const TreeNode = (type, config) => new TreeNodePrimitive(type, config);
1753
+
1754
+ //#endregion
1755
+ //#region src/primitives/Tree.ts
1756
+ /**
1757
+ * Helper to get children sorted by position
1758
+ */
1759
+ const getOrderedChildren = (nodes, parentId) => {
1760
+ return [...nodes].filter((n) => n.parentId === parentId).sort((a, b) => a.pos < b.pos ? -1 : a.pos > b.pos ? 1 : 0);
1761
+ };
1762
+ /**
1763
+ * Get all descendant IDs of a node (recursive)
1764
+ */
1765
+ const getDescendantIds = (nodes, nodeId) => {
1766
+ const children = nodes.filter((n) => n.parentId === nodeId);
1767
+ const descendantIds = [];
1768
+ for (const child of children) {
1769
+ descendantIds.push(child.id);
1770
+ descendantIds.push(...getDescendantIds(nodes, child.id));
1771
+ }
1772
+ return descendantIds;
1773
+ };
1774
+ /**
1775
+ * Check if moving a node to a new parent would create a cycle
1776
+ */
1777
+ const wouldCreateCycle = (nodes, nodeId, newParentId) => {
1778
+ if (newParentId === null) return false;
1779
+ if (newParentId === nodeId) return true;
1780
+ return getDescendantIds(nodes, nodeId).includes(newParentId);
1781
+ };
1782
+ /**
1783
+ * Generate a fractional position between two positions
1784
+ */
1785
+ const generateTreePosBetween = (left, right) => {
1786
+ const charSet = base62CharSet();
1787
+ return Effect.runSync(generateKeyBetween(left, right, charSet));
1788
+ };
1789
+ var TreePrimitive = class TreePrimitive {
1790
+ constructor(schema) {
1791
+ _defineProperty(this, "_tag", "TreePrimitive");
1792
+ _defineProperty(this, "_State", void 0);
1793
+ _defineProperty(this, "_Proxy", void 0);
1794
+ _defineProperty(this, "_TRequired", void 0);
1795
+ _defineProperty(this, "_THasDefault", void 0);
1796
+ _defineProperty(this, "TSetInput", void 0);
1797
+ _defineProperty(this, "TUpdateInput", void 0);
1798
+ _defineProperty(this, "_schema", void 0);
1799
+ _defineProperty(this, "_nodeTypeRegistry", void 0);
1800
+ _defineProperty(this, "_opDefinitions", {
1801
+ set: make({
1802
+ kind: "tree.set",
1803
+ payload: Schema.Unknown,
1804
+ target: Schema.Unknown,
1805
+ apply: (payload) => payload
1806
+ }),
1807
+ insert: make({
1808
+ kind: "tree.insert",
1809
+ payload: Schema.Unknown,
1810
+ target: Schema.Unknown,
1811
+ apply: (payload) => payload
1812
+ }),
1813
+ remove: make({
1814
+ kind: "tree.remove",
1815
+ payload: Schema.Unknown,
1816
+ target: Schema.Unknown,
1817
+ apply: (payload) => payload
1818
+ }),
1819
+ move: make({
1820
+ kind: "tree.move",
1821
+ payload: Schema.Unknown,
1822
+ target: Schema.Unknown,
1823
+ apply: (payload) => payload
1824
+ })
1825
+ });
1826
+ _defineProperty(this, "_internal", {
1827
+ createProxy: (env, operationPath) => {
1828
+ const getCurrentState = () => {
1829
+ const state = env.getState(operationPath);
1830
+ return state !== null && state !== void 0 ? state : [];
1831
+ };
1832
+ const getParentType = (parentId) => {
1833
+ var _parent$type;
1834
+ if (parentId === null) return null;
1835
+ const parent = getCurrentState().find((n) => n.id === parentId);
1836
+ return (_parent$type = parent === null || parent === void 0 ? void 0 : parent.type) !== null && _parent$type !== void 0 ? _parent$type : null;
1837
+ };
1838
+ const createNodeProxy = (nodeState) => {
1839
+ return {
1840
+ id: nodeState.id,
1841
+ type: nodeState.type,
1842
+ is: (nodeType) => {
1843
+ return nodeState.type === nodeType.type;
1844
+ },
1845
+ as: (nodeType) => {
1846
+ if (nodeState.type !== nodeType.type) throw new ValidationError(`Node is of type "${nodeState.type}", not "${nodeType.type}"`);
1847
+ const nodePath = operationPath.append(nodeState.id);
1848
+ const dataProxy = nodeType.data._internal.createProxy(env, nodePath);
1849
+ return {
1850
+ id: nodeState.id,
1851
+ type: nodeType.type,
1852
+ data: dataProxy,
1853
+ get: () => nodeState,
1854
+ update: (value) => {
1855
+ dataProxy.update(value);
1856
+ }
1857
+ };
1858
+ },
1859
+ get: () => nodeState
1860
+ };
1861
+ };
1862
+ const buildSnapshot = (nodeId, nodes) => {
1863
+ const node = nodes.find((n) => n.id === nodeId);
1864
+ if (!node) return void 0;
1865
+ const childNodes = getOrderedChildren(nodes, nodeId);
1866
+ const children = [];
1867
+ for (const child of childNodes) {
1868
+ const childSnapshot = buildSnapshot(child.id, nodes);
1869
+ if (childSnapshot) children.push(childSnapshot);
1870
+ }
1871
+ return _objectSpread2(_objectSpread2({
1872
+ id: node.id,
1873
+ type: node.type
1874
+ }, node.data), {}, { children });
1875
+ };
1876
+ return {
1877
+ get: () => {
1878
+ return getCurrentState();
1879
+ },
1880
+ set: (nodes) => {
1881
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.set, nodes));
1882
+ },
1883
+ root: () => {
1884
+ return getCurrentState().find((n) => n.parentId === null);
1885
+ },
1886
+ children: (parentId) => {
1887
+ return getOrderedChildren(getCurrentState(), parentId);
1888
+ },
1889
+ node: (id) => {
1890
+ const nodeState = getCurrentState().find((n) => n.id === id);
1891
+ if (!nodeState) return void 0;
1892
+ return createNodeProxy(nodeState);
1893
+ },
1894
+ insertFirst: (parentId, nodeType, data) => {
1895
+ const state = getCurrentState();
1896
+ const siblings = getOrderedChildren(state, parentId);
1897
+ const pos = generateTreePosBetween(null, siblings.length > 0 ? siblings[0].pos : null);
1898
+ const id = env.generateId();
1899
+ if (parentId !== null && !state.find((n) => n.id === parentId)) throw new ValidationError(`Parent node not found: ${parentId}`);
1900
+ const parentType = getParentType(parentId);
1901
+ this._validateChildType(parentType, nodeType.type);
1902
+ if (parentId === null && state.some((n) => n.parentId === null)) throw new ValidationError("Tree already has a root node");
1903
+ const mergedData = applyDefaults(nodeType.data, data);
1904
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1905
+ id,
1906
+ type: nodeType.type,
1907
+ parentId,
1908
+ pos,
1909
+ data: mergedData
1910
+ }));
1911
+ return id;
1912
+ },
1913
+ insertLast: (parentId, nodeType, data) => {
1914
+ const state = getCurrentState();
1915
+ const siblings = getOrderedChildren(state, parentId);
1916
+ const pos = generateTreePosBetween(siblings.length > 0 ? siblings[siblings.length - 1].pos : null, null);
1917
+ const id = env.generateId();
1918
+ if (parentId !== null && !state.find((n) => n.id === parentId)) throw new ValidationError(`Parent node not found: ${parentId}`);
1919
+ const parentType = getParentType(parentId);
1920
+ this._validateChildType(parentType, nodeType.type);
1921
+ if (parentId === null && state.some((n) => n.parentId === null)) throw new ValidationError("Tree already has a root node");
1922
+ const mergedData = applyDefaults(nodeType.data, data);
1923
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1924
+ id,
1925
+ type: nodeType.type,
1926
+ parentId,
1927
+ pos,
1928
+ data: mergedData
1929
+ }));
1930
+ return id;
1931
+ },
1932
+ insertAt: (parentId, index, nodeType, data) => {
1933
+ const state = getCurrentState();
1934
+ const siblings = getOrderedChildren(state, parentId);
1935
+ const clampedIndex = Math.max(0, Math.min(index, siblings.length));
1936
+ const pos = generateTreePosBetween(clampedIndex > 0 && siblings[clampedIndex - 1] ? siblings[clampedIndex - 1].pos : null, clampedIndex < siblings.length && siblings[clampedIndex] ? siblings[clampedIndex].pos : null);
1937
+ const id = env.generateId();
1938
+ if (parentId !== null && !state.find((n) => n.id === parentId)) throw new ValidationError(`Parent node not found: ${parentId}`);
1939
+ const parentType = getParentType(parentId);
1940
+ this._validateChildType(parentType, nodeType.type);
1941
+ if (parentId === null && state.some((n) => n.parentId === null)) throw new ValidationError("Tree already has a root node");
1942
+ const mergedData = applyDefaults(nodeType.data, data);
1943
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1944
+ id,
1945
+ type: nodeType.type,
1946
+ parentId,
1947
+ pos,
1948
+ data: mergedData
1949
+ }));
1950
+ return id;
1951
+ },
1952
+ insertAfter: (siblingId, nodeType, data) => {
1953
+ var _nextSibling$pos;
1954
+ const state = getCurrentState();
1955
+ const sibling = state.find((n) => n.id === siblingId);
1956
+ if (!sibling) throw new ValidationError(`Sibling node not found: ${siblingId}`);
1957
+ const parentId = sibling.parentId;
1958
+ const siblings = getOrderedChildren(state, parentId);
1959
+ const nextSibling = siblings[siblings.findIndex((n) => n.id === siblingId) + 1];
1960
+ const pos = generateTreePosBetween(sibling.pos, (_nextSibling$pos = nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.pos) !== null && _nextSibling$pos !== void 0 ? _nextSibling$pos : null);
1961
+ const id = env.generateId();
1962
+ const parentType = getParentType(parentId);
1963
+ this._validateChildType(parentType, nodeType.type);
1964
+ const mergedData = applyDefaults(nodeType.data, data);
1965
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1966
+ id,
1967
+ type: nodeType.type,
1968
+ parentId,
1969
+ pos,
1970
+ data: mergedData
1971
+ }));
1972
+ return id;
1973
+ },
1974
+ insertBefore: (siblingId, nodeType, data) => {
1975
+ var _prevSibling$pos;
1976
+ const state = getCurrentState();
1977
+ const sibling = state.find((n) => n.id === siblingId);
1978
+ if (!sibling) throw new ValidationError(`Sibling node not found: ${siblingId}`);
1979
+ const parentId = sibling.parentId;
1980
+ const siblings = getOrderedChildren(state, parentId);
1981
+ const prevSibling = siblings[siblings.findIndex((n) => n.id === siblingId) - 1];
1982
+ const pos = generateTreePosBetween((_prevSibling$pos = prevSibling === null || prevSibling === void 0 ? void 0 : prevSibling.pos) !== null && _prevSibling$pos !== void 0 ? _prevSibling$pos : null, sibling.pos);
1983
+ const id = env.generateId();
1984
+ const parentType = getParentType(parentId);
1985
+ this._validateChildType(parentType, nodeType.type);
1986
+ const mergedData = applyDefaults(nodeType.data, data);
1987
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.insert, {
1988
+ id,
1989
+ type: nodeType.type,
1990
+ parentId,
1991
+ pos,
1992
+ data: mergedData
1993
+ }));
1994
+ return id;
1995
+ },
1996
+ remove: (id) => {
1997
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.remove, { id }));
1998
+ },
1999
+ move: (nodeId, newParentId, toIndex) => {
2000
+ var _state$find$type, _state$find;
2001
+ const state = getCurrentState();
2002
+ const node = state.find((n) => n.id === nodeId);
2003
+ if (!node) throw new ValidationError(`Node not found: ${nodeId}`);
2004
+ if (newParentId !== null && !state.find((n) => n.id === newParentId)) throw new ValidationError(`Parent node not found: ${newParentId}`);
2005
+ if (wouldCreateCycle(state, nodeId, newParentId)) throw new ValidationError("Move would create a cycle in the tree");
2006
+ const newParentType = newParentId === null ? null : (_state$find$type = (_state$find = state.find((n) => n.id === newParentId)) === null || _state$find === void 0 ? void 0 : _state$find.type) !== null && _state$find$type !== void 0 ? _state$find$type : null;
2007
+ this._validateChildType(newParentType, node.type);
2008
+ if (node.parentId === null && newParentId !== null) throw new ValidationError("Cannot move root node to have a parent");
2009
+ const siblings = getOrderedChildren(state, newParentId).filter((n) => n.id !== nodeId);
2010
+ const clampedIndex = Math.max(0, Math.min(toIndex, siblings.length));
2011
+ const pos = generateTreePosBetween(clampedIndex > 0 && siblings[clampedIndex - 1] ? siblings[clampedIndex - 1].pos : null, clampedIndex < siblings.length && siblings[clampedIndex] ? siblings[clampedIndex].pos : null);
2012
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
2013
+ id: nodeId,
2014
+ parentId: newParentId,
2015
+ pos
2016
+ }));
2017
+ },
2018
+ moveAfter: (nodeId, siblingId) => {
2019
+ var _state$find$type2, _state$find2, _nextSibling$pos2;
2020
+ const state = getCurrentState();
2021
+ const node = state.find((n) => n.id === nodeId);
2022
+ const sibling = state.find((n) => n.id === siblingId);
2023
+ if (!node) throw new ValidationError(`Node not found: ${nodeId}`);
2024
+ if (!sibling) throw new ValidationError(`Sibling node not found: ${siblingId}`);
2025
+ const newParentId = sibling.parentId;
2026
+ if (wouldCreateCycle(state, nodeId, newParentId)) throw new ValidationError("Move would create a cycle in the tree");
2027
+ const newParentType = newParentId === null ? null : (_state$find$type2 = (_state$find2 = state.find((n) => n.id === newParentId)) === null || _state$find2 === void 0 ? void 0 : _state$find2.type) !== null && _state$find$type2 !== void 0 ? _state$find$type2 : null;
2028
+ this._validateChildType(newParentType, node.type);
2029
+ if (node.parentId === null && newParentId !== null) throw new ValidationError("Cannot move root node to have a parent");
2030
+ const siblings = getOrderedChildren(state, newParentId).filter((n) => n.id !== nodeId);
2031
+ const nextSibling = siblings[siblings.findIndex((n) => n.id === siblingId) + 1];
2032
+ const pos = generateTreePosBetween(sibling.pos, (_nextSibling$pos2 = nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.pos) !== null && _nextSibling$pos2 !== void 0 ? _nextSibling$pos2 : null);
2033
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
2034
+ id: nodeId,
2035
+ parentId: newParentId,
2036
+ pos
2037
+ }));
2038
+ },
2039
+ moveBefore: (nodeId, siblingId) => {
2040
+ var _state$find$type3, _state$find3, _prevSibling$pos2;
2041
+ const state = getCurrentState();
2042
+ const node = state.find((n) => n.id === nodeId);
2043
+ const sibling = state.find((n) => n.id === siblingId);
2044
+ if (!node) throw new ValidationError(`Node not found: ${nodeId}`);
2045
+ if (!sibling) throw new ValidationError(`Sibling node not found: ${siblingId}`);
2046
+ const newParentId = sibling.parentId;
2047
+ if (wouldCreateCycle(state, nodeId, newParentId)) throw new ValidationError("Move would create a cycle in the tree");
2048
+ const newParentType = newParentId === null ? null : (_state$find$type3 = (_state$find3 = state.find((n) => n.id === newParentId)) === null || _state$find3 === void 0 ? void 0 : _state$find3.type) !== null && _state$find$type3 !== void 0 ? _state$find$type3 : null;
2049
+ this._validateChildType(newParentType, node.type);
2050
+ if (node.parentId === null && newParentId !== null) throw new ValidationError("Cannot move root node to have a parent");
2051
+ const siblings = getOrderedChildren(state, newParentId).filter((n) => n.id !== nodeId);
2052
+ const prevSibling = siblings[siblings.findIndex((n) => n.id === siblingId) - 1];
2053
+ const pos = generateTreePosBetween((_prevSibling$pos2 = prevSibling === null || prevSibling === void 0 ? void 0 : prevSibling.pos) !== null && _prevSibling$pos2 !== void 0 ? _prevSibling$pos2 : null, sibling.pos);
2054
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
2055
+ id: nodeId,
2056
+ parentId: newParentId,
2057
+ pos
2058
+ }));
2059
+ },
2060
+ moveToFirst: (nodeId, newParentId) => {
2061
+ var _state$find$type4, _state$find4;
2062
+ const state = getCurrentState();
2063
+ const node = state.find((n) => n.id === nodeId);
2064
+ if (!node) throw new ValidationError(`Node not found: ${nodeId}`);
2065
+ if (newParentId !== null && !state.find((n) => n.id === newParentId)) throw new ValidationError(`Parent node not found: ${newParentId}`);
2066
+ if (wouldCreateCycle(state, nodeId, newParentId)) throw new ValidationError("Move would create a cycle in the tree");
2067
+ const newParentType = newParentId === null ? null : (_state$find$type4 = (_state$find4 = state.find((n) => n.id === newParentId)) === null || _state$find4 === void 0 ? void 0 : _state$find4.type) !== null && _state$find$type4 !== void 0 ? _state$find$type4 : null;
2068
+ this._validateChildType(newParentType, node.type);
2069
+ if (node.parentId === null && newParentId !== null) throw new ValidationError("Cannot move root node to have a parent");
2070
+ const siblings = getOrderedChildren(state, newParentId).filter((n) => n.id !== nodeId);
2071
+ const pos = generateTreePosBetween(null, siblings.length > 0 ? siblings[0].pos : null);
2072
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
2073
+ id: nodeId,
2074
+ parentId: newParentId,
2075
+ pos
2076
+ }));
2077
+ },
2078
+ moveToLast: (nodeId, newParentId) => {
2079
+ var _state$find$type5, _state$find5;
2080
+ const state = getCurrentState();
2081
+ const node = state.find((n) => n.id === nodeId);
2082
+ if (!node) throw new ValidationError(`Node not found: ${nodeId}`);
2083
+ if (newParentId !== null && !state.find((n) => n.id === newParentId)) throw new ValidationError(`Parent node not found: ${newParentId}`);
2084
+ if (wouldCreateCycle(state, nodeId, newParentId)) throw new ValidationError("Move would create a cycle in the tree");
2085
+ const newParentType = newParentId === null ? null : (_state$find$type5 = (_state$find5 = state.find((n) => n.id === newParentId)) === null || _state$find5 === void 0 ? void 0 : _state$find5.type) !== null && _state$find$type5 !== void 0 ? _state$find$type5 : null;
2086
+ this._validateChildType(newParentType, node.type);
2087
+ if (node.parentId === null && newParentId !== null) throw new ValidationError("Cannot move root node to have a parent");
2088
+ const siblings = getOrderedChildren(state, newParentId).filter((n) => n.id !== nodeId);
2089
+ const pos = generateTreePosBetween(siblings.length > 0 ? siblings[siblings.length - 1].pos : null, null);
2090
+ env.addOperation(fromDefinition(operationPath, this._opDefinitions.move, {
2091
+ id: nodeId,
2092
+ parentId: newParentId,
2093
+ pos
2094
+ }));
2095
+ },
2096
+ at: (id, nodeType) => {
2097
+ const node = getCurrentState().find((n) => n.id === id);
2098
+ if (!node) throw new ValidationError(`Node not found: ${id}`);
2099
+ if (node.type !== nodeType.type) throw new ValidationError(`Node is of type "${node.type}", not "${nodeType.type}"`);
2100
+ const nodePath = operationPath.append(id);
2101
+ return nodeType.data._internal.createProxy(env, nodePath);
2102
+ },
2103
+ updateAt: (id, nodeType, value) => {
2104
+ const node = getCurrentState().find((n) => n.id === id);
2105
+ if (!node) throw new ValidationError(`Node not found: ${id}`);
2106
+ if (node.type !== nodeType.type) throw new ValidationError(`Node is of type "${node.type}", not "${nodeType.type}"`);
2107
+ const nodePath = operationPath.append(id);
2108
+ nodeType.data._internal.createProxy(env, nodePath).update(value);
2109
+ },
2110
+ toSnapshot: () => {
2111
+ const state = getCurrentState();
2112
+ const rootNode = state.find((n) => n.parentId === null);
2113
+ if (!rootNode) return void 0;
2114
+ return buildSnapshot(rootNode.id, state);
2115
+ }
2116
+ };
2117
+ },
2118
+ applyOperation: (state, operation) => {
2119
+ const path = operation.path;
2120
+ const tokens = path.toTokens().filter((t) => t !== "");
2121
+ const currentState = state !== null && state !== void 0 ? state : [];
2122
+ let newState;
2123
+ if (tokens.length === 0) switch (operation.kind) {
2124
+ case "tree.set": {
2125
+ const payload = operation.payload;
2126
+ if (!globalThis.Array.isArray(payload)) throw new ValidationError(`TreePrimitive.set requires an array payload`);
2127
+ newState = payload;
2128
+ break;
2129
+ }
2130
+ case "tree.insert": {
2131
+ const { id, type, parentId, pos, data } = operation.payload;
2132
+ newState = [...currentState, {
2133
+ id,
2134
+ type,
2135
+ parentId,
2136
+ pos,
2137
+ data
2138
+ }];
2139
+ break;
2140
+ }
2141
+ case "tree.remove": {
2142
+ const { id } = operation.payload;
2143
+ const descendantIds = getDescendantIds(currentState, id);
2144
+ const idsToRemove = new Set([id, ...descendantIds]);
2145
+ newState = currentState.filter((node) => !idsToRemove.has(node.id));
2146
+ break;
2147
+ }
2148
+ case "tree.move": {
2149
+ const { id, parentId, pos } = operation.payload;
2150
+ newState = currentState.map((node) => node.id === id ? _objectSpread2(_objectSpread2({}, node), {}, {
2151
+ parentId,
2152
+ pos
2153
+ }) : node);
2154
+ break;
2155
+ }
2156
+ default: throw new ValidationError(`TreePrimitive cannot apply operation of kind: ${operation.kind}`);
2157
+ }
2158
+ else {
2159
+ const nodeId = tokens[0];
2160
+ const nodeIndex = currentState.findIndex((node$1) => node$1.id === nodeId);
2161
+ if (nodeIndex === -1) throw new ValidationError(`Tree node not found with ID: ${nodeId}`);
2162
+ const node = currentState[nodeIndex];
2163
+ const nodeTypePrimitive = this._getNodeTypePrimitive(node.type);
2164
+ const remainingPath = path.shift();
2165
+ const nodeOperation = _objectSpread2(_objectSpread2({}, operation), {}, { path: remainingPath });
2166
+ const newData = nodeTypePrimitive.data._internal.applyOperation(node.data, nodeOperation);
2167
+ const mutableState = [...currentState];
2168
+ mutableState[nodeIndex] = _objectSpread2(_objectSpread2({}, node), {}, { data: newData });
2169
+ newState = mutableState;
2170
+ }
2171
+ runValidators(newState, this._schema.validators);
2172
+ return newState;
2173
+ },
2174
+ getInitialState: () => {
2175
+ var _rootNodeType$data$_i;
2176
+ if (this._schema.defaultValue !== void 0) return this._schema.defaultValue;
2177
+ const rootNodeType = this._schema.root;
2178
+ const rootData = (_rootNodeType$data$_i = rootNodeType.data._internal.getInitialState()) !== null && _rootNodeType$data$_i !== void 0 ? _rootNodeType$data$_i : {};
2179
+ const rootId = crypto.randomUUID();
2180
+ const rootPos = generateTreePosBetween(null, null);
2181
+ return [{
2182
+ id: rootId,
2183
+ type: rootNodeType.type,
2184
+ parentId: null,
2185
+ pos: rootPos,
2186
+ data: rootData
2187
+ }];
2188
+ },
2189
+ transformOperation: (clientOp, serverOp) => {
2190
+ const clientPath = clientOp.path;
2191
+ const serverPath = serverOp.path;
2192
+ if (!pathsOverlap(clientPath, serverPath)) return {
2193
+ type: "transformed",
2194
+ operation: clientOp
2195
+ };
2196
+ if (serverOp.kind === "tree.remove") {
2197
+ const removedId = serverOp.payload.id;
2198
+ const clientTokens$1 = clientPath.toTokens().filter((t) => t !== "");
2199
+ const serverTokens$1 = serverPath.toTokens().filter((t) => t !== "");
2200
+ if (clientOp.kind === "tree.move") {
2201
+ const movePayload = clientOp.payload;
2202
+ if (movePayload.id === removedId || movePayload.parentId === removedId) return { type: "noop" };
2203
+ }
2204
+ if (clientOp.kind === "tree.insert") {
2205
+ if (clientOp.payload.parentId === removedId) return { type: "noop" };
2206
+ }
2207
+ if (clientTokens$1.length > serverTokens$1.length) {
2208
+ if (clientTokens$1[serverTokens$1.length] === removedId) return { type: "noop" };
2209
+ }
2210
+ }
2211
+ if (serverOp.kind === "tree.insert" && clientOp.kind === "tree.insert") return {
2212
+ type: "transformed",
2213
+ operation: clientOp
2214
+ };
2215
+ if (serverOp.kind === "tree.move" && clientOp.kind === "tree.move") {
2216
+ if (serverOp.payload.id === clientOp.payload.id) return {
2217
+ type: "transformed",
2218
+ operation: clientOp
2219
+ };
2220
+ return {
2221
+ type: "transformed",
2222
+ operation: clientOp
2223
+ };
2224
+ }
2225
+ if (pathsEqual(clientPath, serverPath)) return {
2226
+ type: "transformed",
2227
+ operation: clientOp
2228
+ };
2229
+ if (serverOp.kind === "tree.set" && isPrefix(serverPath, clientPath)) return {
2230
+ type: "transformed",
2231
+ operation: clientOp
2232
+ };
2233
+ const clientTokens = clientPath.toTokens().filter((t) => t !== "");
2234
+ const serverTokens = serverPath.toTokens().filter((t) => t !== "");
2235
+ if (clientTokens.length > 0 && serverTokens.length > 0) {
2236
+ if (clientTokens[0] !== serverTokens[0]) return {
2237
+ type: "transformed",
2238
+ operation: clientOp
2239
+ };
2240
+ return {
2241
+ type: "transformed",
2242
+ operation: clientOp
2243
+ };
2244
+ }
2245
+ return {
2246
+ type: "transformed",
2247
+ operation: clientOp
2248
+ };
2249
+ }
2250
+ });
2251
+ this._schema = schema;
2252
+ }
2253
+ /** Mark this tree as required */
2254
+ required() {
2255
+ return new TreePrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { required: true }));
2256
+ }
2257
+ /** Set a default value for this tree */
2258
+ default(defaultValue) {
2259
+ return new TreePrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { defaultValue }));
2260
+ }
2261
+ /** Get the root node type */
2262
+ get root() {
2263
+ return this._schema.root;
2264
+ }
2265
+ /** Add a custom validation rule */
2266
+ refine(fn, message) {
2267
+ return new TreePrimitive(_objectSpread2(_objectSpread2({}, this._schema), {}, { validators: [...this._schema.validators, {
2268
+ validate: fn,
2269
+ message
2270
+ }] }));
2271
+ }
2272
+ /**
2273
+ * Build a registry of all node types reachable from root
2274
+ */
2275
+ _buildNodeTypeRegistry() {
2276
+ if (this._nodeTypeRegistry !== void 0) return this._nodeTypeRegistry;
2277
+ const registry = /* @__PURE__ */ new Map();
2278
+ const visited = /* @__PURE__ */ new Set();
2279
+ const visit = (node) => {
2280
+ if (visited.has(node.type)) return;
2281
+ visited.add(node.type);
2282
+ registry.set(node.type, node);
2283
+ for (const child of node.children) visit(child);
2284
+ };
2285
+ visit(this._schema.root);
2286
+ this._nodeTypeRegistry = registry;
2287
+ return registry;
2288
+ }
2289
+ /**
2290
+ * Get a node type primitive by its type string
2291
+ */
2292
+ _getNodeTypePrimitive(type) {
2293
+ const nodeType = this._buildNodeTypeRegistry().get(type);
2294
+ if (!nodeType) throw new ValidationError(`Unknown node type: ${type}`);
2295
+ return nodeType;
2296
+ }
2297
+ /**
2298
+ * Validate that a node type can be a child of a parent node type
2299
+ */
2300
+ _validateChildType(parentType, childType) {
2301
+ if (parentType === null) {
2302
+ if (childType !== this._schema.root.type) throw new ValidationError(`Root node must be of type "${this._schema.root.type}", got "${childType}"`);
2303
+ return;
2304
+ }
2305
+ const parentNodePrimitive = this._getNodeTypePrimitive(parentType);
2306
+ if (!parentNodePrimitive.isChildAllowed(childType)) throw new ValidationError(`Node type "${childType}" is not allowed as a child of "${parentType}". Allowed types: ${parentNodePrimitive.children.map((c) => c.type).join(", ") || "none"}`);
2307
+ }
2308
+ };
2309
+ /** Creates a new TreePrimitive with the given root node type */
2310
+ const Tree = (options) => new TreePrimitive({
2311
+ required: false,
2312
+ defaultValue: void 0,
2313
+ root: options.root,
2314
+ validators: []
2315
+ });
2316
+
2317
+ //#endregion
2318
+ //#region src/Primitive.ts
2319
+ var Primitive_exports = /* @__PURE__ */ __export({
2320
+ Array: () => Array$1,
2321
+ ArrayPrimitive: () => ArrayPrimitive,
2322
+ Boolean: () => Boolean,
2323
+ BooleanPrimitive: () => BooleanPrimitive,
2324
+ Either: () => Either,
2325
+ EitherPrimitive: () => EitherPrimitive,
2326
+ Lazy: () => Lazy,
2327
+ LazyPrimitive: () => LazyPrimitive,
2328
+ Literal: () => Literal,
2329
+ LiteralPrimitive: () => LiteralPrimitive,
2330
+ Number: () => Number,
2331
+ NumberPrimitive: () => NumberPrimitive,
2332
+ String: () => String,
2333
+ StringPrimitive: () => StringPrimitive,
2334
+ Struct: () => Struct,
2335
+ StructPrimitive: () => StructPrimitive,
2336
+ Tree: () => Tree,
2337
+ TreeNode: () => TreeNode,
2338
+ TreeNodePrimitive: () => TreeNodePrimitive,
2339
+ TreeNodeSelf: () => TreeNodeSelf,
2340
+ TreePrimitive: () => TreePrimitive,
2341
+ Union: () => Union,
2342
+ UnionPrimitive: () => UnionPrimitive,
2343
+ ValidationError: () => ValidationError,
2344
+ applyDefaults: () => applyDefaults,
2345
+ isCompatibleOperation: () => isCompatibleOperation,
2346
+ runValidators: () => runValidators
2347
+ });
2348
+
2349
+ //#endregion
2350
+ //#region src/Transform.ts
2351
+ var Transform_exports = {};
2352
+
2353
+ //#endregion
2354
+ //#region src/EffectSchema.ts
2355
+ /**
2356
+ * Effect.Schema utilities for converting Mimic primitives to Effect.Schema schemas.
2357
+ *
2358
+ * @since 0.0.1
2359
+ */
2360
+ var EffectSchema_exports = /* @__PURE__ */ __export({
2361
+ TreeNodeStateSchema: () => TreeNodeStateSchema,
2362
+ toSetSchema: () => toSetSchema,
2363
+ toUpdateSchema: () => toUpdateSchema
2364
+ });
2365
+ /**
2366
+ * Schema for a tree node state (flat storage format).
2367
+ */
2368
+ const TreeNodeStateSchema = Schema.Struct({
2369
+ id: Schema.String,
2370
+ type: Schema.String,
2371
+ parentId: Schema.NullOr(Schema.String),
2372
+ pos: Schema.String,
2373
+ data: Schema.Unknown
2374
+ });
2375
+ /**
2376
+ * Check if a field is required for set operations.
2377
+ * A field is required if: TRequired is true AND THasDefault is false.
2378
+ *
2379
+ * We determine this by checking the primitive's schema properties.
2380
+ */
2381
+ function isRequiredForSet(primitive) {
2382
+ const schema = primitive._schema;
2383
+ if (!schema) return false;
2384
+ return schema.required === true && schema.defaultValue === void 0;
2385
+ }
2386
+ /**
2387
+ * Get the base Effect.Schema for a primitive type (without optional wrapper).
2388
+ */
2389
+ function getBaseSchema(primitive) {
2390
+ switch (primitive._tag) {
2391
+ case "StringPrimitive": return Schema.String;
2392
+ case "NumberPrimitive": return Schema.Number;
2393
+ case "BooleanPrimitive": return Schema.Boolean;
2394
+ case "LiteralPrimitive": {
2395
+ var _schema$literal, _schema;
2396
+ const literalPrimitive = primitive;
2397
+ const literalValue = (_schema$literal = (_schema = literalPrimitive._schema) === null || _schema === void 0 ? void 0 : _schema.literal) !== null && _schema$literal !== void 0 ? _schema$literal : literalPrimitive.literal;
2398
+ return Schema.Literal(literalValue);
2399
+ }
2400
+ case "StructPrimitive": return buildStructSetSchema(primitive);
2401
+ case "ArrayPrimitive": {
2402
+ const elementSchema = buildElementSetSchema(primitive.element);
2403
+ return Schema.Array(elementSchema);
2404
+ }
2405
+ case "UnionPrimitive": return buildUnionSetSchema(primitive);
2406
+ case "EitherPrimitive": return buildEitherSchema(primitive);
2407
+ case "LazyPrimitive": {
2408
+ var _resolve, _resolve2;
2409
+ const lazyPrimitive = primitive;
2410
+ return getBaseSchema((_resolve = (_resolve2 = lazyPrimitive._resolve) === null || _resolve2 === void 0 ? void 0 : _resolve2.call(lazyPrimitive)) !== null && _resolve !== void 0 ? _resolve : lazyPrimitive._thunk());
2411
+ }
2412
+ case "TreeNodePrimitive": return buildStructSetSchema(primitive.data);
2413
+ case "TreePrimitive": return Schema.Array(TreeNodeStateSchema);
2414
+ default: return Schema.Unknown;
2415
+ }
2416
+ }
2417
+ /**
2418
+ * Build the set schema for a struct primitive.
2419
+ * Required fields (required=true, no default) are non-optional.
2420
+ * Other fields are wrapped with Schema.optional.
2421
+ */
2422
+ function buildStructSetSchema(structPrimitive) {
2423
+ const fields = structPrimitive.fields;
2424
+ const schemaFields = {};
2425
+ for (const key in fields) {
2426
+ const fieldPrimitive = fields[key];
2427
+ const baseSchema = getBaseSchema(fieldPrimitive);
2428
+ if (isRequiredForSet(fieldPrimitive)) schemaFields[key] = baseSchema;
2429
+ else schemaFields[key] = Schema.optional(baseSchema);
2430
+ }
2431
+ return Schema.Struct(schemaFields);
2432
+ }
2433
+ /**
2434
+ * Build the update schema for a struct primitive.
2435
+ * All fields are optional for partial updates.
2436
+ */
2437
+ function buildStructUpdateSchema(structPrimitive) {
2438
+ const fields = structPrimitive.fields;
2439
+ const schemaFields = {};
2440
+ for (const key in fields) {
2441
+ const fieldPrimitive = fields[key];
2442
+ let fieldSchema;
2443
+ if (fieldPrimitive._tag === "StructPrimitive") fieldSchema = buildStructUpdateSchema(fieldPrimitive);
2444
+ else fieldSchema = getBaseSchema(fieldPrimitive);
2445
+ schemaFields[key] = Schema.optional(fieldSchema);
2446
+ }
2447
+ return Schema.Struct(schemaFields);
2448
+ }
2449
+ /**
2450
+ * Build the set schema for an array element.
2451
+ * For struct elements, uses the struct's set input schema.
2452
+ */
2453
+ function buildElementSetSchema(elementPrimitive) {
2454
+ if (elementPrimitive._tag === "StructPrimitive") return buildStructSetSchema(elementPrimitive);
2455
+ return getBaseSchema(elementPrimitive);
2456
+ }
2457
+ /**
2458
+ * Build the set schema for a union primitive.
2459
+ * Creates a Schema.Union of all variant schemas.
2460
+ */
2461
+ function buildUnionSetSchema(unionPrimitive) {
2462
+ const variants = unionPrimitive.variants;
2463
+ const variantSchemas = [];
2464
+ for (const key in variants) {
2465
+ const variantPrimitive = variants[key];
2466
+ variantSchemas.push(buildStructSetSchema(variantPrimitive));
2467
+ }
2468
+ if (variantSchemas.length === 0) return Schema.Unknown;
2469
+ if (variantSchemas.length === 1) return variantSchemas[0];
2470
+ return Schema.Union(...variantSchemas);
2471
+ }
2472
+ /**
2473
+ * Build the schema for an either primitive.
2474
+ * Creates a Schema.Union of all scalar variant types.
2475
+ */
2476
+ function buildEitherSchema(eitherPrimitive) {
2477
+ const variants = eitherPrimitive.variants;
2478
+ const variantSchemas = [];
2479
+ for (const variant of variants) variantSchemas.push(getBaseSchema(variant));
2480
+ if (variantSchemas.length === 0) return Schema.Unknown;
2481
+ if (variantSchemas.length === 1) return variantSchemas[0];
2482
+ return Schema.Union(...variantSchemas);
2483
+ }
2484
+ /**
2485
+ * Build the update schema for a union primitive.
2486
+ * Creates a Schema.Union of all variant update schemas.
2487
+ */
2488
+ function buildUnionUpdateSchema(unionPrimitive) {
2489
+ const variants = unionPrimitive.variants;
2490
+ const variantSchemas = [];
2491
+ for (const key in variants) {
2492
+ const variantPrimitive = variants[key];
2493
+ variantSchemas.push(buildStructUpdateSchema(variantPrimitive));
2494
+ }
2495
+ if (variantSchemas.length === 0) return Schema.Unknown;
2496
+ if (variantSchemas.length === 1) return variantSchemas[0];
2497
+ return Schema.Union(...variantSchemas);
2498
+ }
2499
+ /**
2500
+ * Get the update schema for a primitive.
2501
+ * For structs, all fields are optional (partial updates).
2502
+ * For simple primitives, same as set schema.
2503
+ */
2504
+ function getUpdateSchema(primitive) {
2505
+ switch (primitive._tag) {
2506
+ case "StructPrimitive": return buildStructUpdateSchema(primitive);
2507
+ case "UnionPrimitive": return buildUnionUpdateSchema(primitive);
2508
+ case "TreeNodePrimitive": return buildStructUpdateSchema(primitive.data);
2509
+ case "LazyPrimitive": {
2510
+ var _resolve3, _resolve4;
2511
+ const lazyPrimitive = primitive;
2512
+ return getUpdateSchema((_resolve3 = (_resolve4 = lazyPrimitive._resolve) === null || _resolve4 === void 0 ? void 0 : _resolve4.call(lazyPrimitive)) !== null && _resolve3 !== void 0 ? _resolve3 : lazyPrimitive._thunk());
2513
+ }
2514
+ default: return getBaseSchema(primitive);
2515
+ }
2516
+ }
2517
+ function toSetSchema(primitive) {
2518
+ return getBaseSchema(primitive);
2519
+ }
2520
+ function toUpdateSchema(primitive) {
2521
+ return getUpdateSchema(primitive);
2522
+ }
2523
+
2524
+ //#endregion
2525
+ export { Document_exports as Document, EffectSchema_exports as EffectSchema, Operation_exports as Operation, OperationPath_exports as OperationPath, Presence_exports as Presence, Primitive_exports as Primitive, ProxyEnvironment_exports as ProxyEnvironment, Transaction_exports as Transaction, Transform_exports as Transform };
2526
+ //# sourceMappingURL=index.mjs.map