@voidhash/mimic 1.0.0-beta.15 → 1.0.0-beta.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Document.cjs +0 -3
- package/dist/Document.d.mts.map +1 -1
- package/dist/Document.mjs +0 -3
- package/dist/Document.mjs.map +1 -1
- package/dist/EffectSchema.cjs +3 -3
- package/dist/EffectSchema.d.cts +5 -5
- package/dist/EffectSchema.d.cts.map +1 -1
- package/dist/EffectSchema.d.mts +5 -5
- package/dist/EffectSchema.d.mts.map +1 -1
- package/dist/EffectSchema.mjs +3 -3
- package/dist/EffectSchema.mjs.map +1 -1
- package/dist/FractionalIndex.mjs.map +1 -1
- package/dist/Operation.d.cts +4 -4
- package/dist/Operation.d.cts.map +1 -1
- package/dist/Operation.d.mts +4 -4
- package/dist/Operation.d.mts.map +1 -1
- package/dist/Operation.mjs.map +1 -1
- package/dist/OperationDefinition.d.cts +2 -2
- package/dist/OperationDefinition.d.cts.map +1 -1
- package/dist/OperationDefinition.d.mts +2 -2
- package/dist/OperationDefinition.d.mts.map +1 -1
- package/dist/OperationDefinition.mjs.map +1 -1
- package/dist/Presence.mjs.map +1 -1
- package/dist/Primitive.d.cts +2 -2
- package/dist/Primitive.d.mts +2 -2
- package/dist/SchemaJSON.cjs +305 -0
- package/dist/SchemaJSON.d.cts +11 -0
- package/dist/SchemaJSON.d.cts.map +1 -0
- package/dist/SchemaJSON.d.mts +11 -0
- package/dist/SchemaJSON.d.mts.map +1 -0
- package/dist/SchemaJSON.mjs +301 -0
- package/dist/SchemaJSON.mjs.map +1 -0
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/dist/primitives/Array.cjs +12 -2
- package/dist/primitives/Array.d.cts.map +1 -1
- package/dist/primitives/Array.d.mts.map +1 -1
- package/dist/primitives/Array.mjs +12 -2
- package/dist/primitives/Array.mjs.map +1 -1
- package/dist/primitives/Boolean.mjs.map +1 -1
- package/dist/primitives/Either.mjs.map +1 -1
- package/dist/primitives/Literal.mjs.map +1 -1
- package/dist/primitives/Number.cjs +27 -5
- package/dist/primitives/Number.d.cts.map +1 -1
- package/dist/primitives/Number.d.mts.map +1 -1
- package/dist/primitives/Number.mjs +27 -5
- package/dist/primitives/Number.mjs.map +1 -1
- package/dist/primitives/String.cjs +44 -13
- package/dist/primitives/String.d.cts.map +1 -1
- package/dist/primitives/String.d.mts.map +1 -1
- package/dist/primitives/String.mjs +44 -13
- package/dist/primitives/String.mjs.map +1 -1
- package/dist/primitives/Struct.cjs +48 -9
- package/dist/primitives/Struct.d.cts +22 -3
- package/dist/primitives/Struct.d.cts.map +1 -1
- package/dist/primitives/Struct.d.mts +22 -3
- package/dist/primitives/Struct.d.mts.map +1 -1
- package/dist/primitives/Struct.mjs +48 -9
- package/dist/primitives/Struct.mjs.map +1 -1
- package/dist/primitives/Union.mjs.map +1 -1
- package/dist/primitives/shared.cjs +2 -5
- package/dist/primitives/shared.d.cts +2 -4
- package/dist/primitives/shared.d.cts.map +1 -1
- package/dist/primitives/shared.d.mts +2 -4
- package/dist/primitives/shared.d.mts.map +1 -1
- package/dist/primitives/shared.mjs +2 -5
- package/dist/primitives/shared.mjs.map +1 -1
- package/package.json +15 -8
- package/src/Document.ts +13 -4
- package/src/EffectSchema.ts +3 -3
- package/src/FractionalIndex.ts +18 -18
- package/src/Operation.ts +5 -5
- package/src/OperationDefinition.ts +2 -2
- package/src/Presence.ts +3 -3
- package/src/SchemaJSON.ts +396 -0
- package/src/index.ts +1 -0
- package/src/primitives/Array.ts +18 -8
- package/src/primitives/Boolean.ts +2 -2
- package/src/primitives/Either.ts +2 -2
- package/src/primitives/Literal.ts +2 -2
- package/src/primitives/Number.ts +44 -22
- package/src/primitives/String.ts +61 -34
- package/src/primitives/Struct.ts +100 -12
- package/src/primitives/Union.ts +1 -1
- package/src/primitives/shared.ts +12 -2
- package/.turbo/turbo-build.log +0 -270
- package/tests/Document.test.ts +0 -557
- package/tests/EffectSchema.test.ts +0 -546
- package/tests/FractionalIndex.test.ts +0 -377
- package/tests/OperationPath.test.ts +0 -151
- package/tests/Presence.test.ts +0 -321
- package/tests/Primitive.test.ts +0 -381
- package/tests/client/ClientDocument.test.ts +0 -1981
- package/tests/client/WebSocketTransport.test.ts +0 -1217
- package/tests/primitives/Array.test.ts +0 -526
- package/tests/primitives/Boolean.test.ts +0 -126
- package/tests/primitives/Either.test.ts +0 -707
- package/tests/primitives/Lazy.test.ts +0 -143
- package/tests/primitives/Literal.test.ts +0 -122
- package/tests/primitives/Number.test.ts +0 -133
- package/tests/primitives/String.test.ts +0 -128
- package/tests/primitives/Struct.test.ts +0 -1044
- package/tests/primitives/Tree.test.ts +0 -1139
- package/tests/primitives/TreeNode.test.ts +0 -50
- package/tests/primitives/Union.test.ts +0 -554
- package/tests/server/ServerDocument.test.ts +0 -903
- package/tsconfig.build.json +0 -24
- package/tsconfig.json +0 -8
- package/tsdown.config.ts +0 -18
- package/vitest.mts +0 -11
|
@@ -223,13 +223,19 @@ var StructPrimitive = class StructPrimitive {
|
|
|
223
223
|
validators: []
|
|
224
224
|
});
|
|
225
225
|
}
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
partial(options) {
|
|
227
|
+
const stripDefaults = options === null || options === void 0 ? void 0 : options.stripDefaults;
|
|
228
228
|
const partialFields = {};
|
|
229
229
|
for (const key in this._schema.fields) {
|
|
230
230
|
const field = this._schema.fields[key];
|
|
231
|
-
partialFields[key] = this._makeFieldOptional(field);
|
|
231
|
+
partialFields[key] = this._makeFieldOptional(field, stripDefaults);
|
|
232
232
|
}
|
|
233
|
+
if (stripDefaults) return new StructPrimitive({
|
|
234
|
+
required: this._schema.required,
|
|
235
|
+
defaultValue: void 0,
|
|
236
|
+
fields: partialFields,
|
|
237
|
+
validators: []
|
|
238
|
+
});
|
|
233
239
|
return new StructPrimitive({
|
|
234
240
|
required: this._schema.required,
|
|
235
241
|
defaultValue: void 0,
|
|
@@ -237,13 +243,46 @@ var StructPrimitive = class StructPrimitive {
|
|
|
237
243
|
validators: []
|
|
238
244
|
});
|
|
239
245
|
}
|
|
240
|
-
_makeFieldOptional(field) {
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
246
|
+
_makeFieldOptional(field, stripDefaults) {
|
|
247
|
+
const maybeStripped = stripDefaults ? this._stripDefaultsRecursively(field) : field;
|
|
248
|
+
const fieldWithSchema = maybeStripped;
|
|
249
|
+
if (fieldWithSchema._schema && typeof fieldWithSchema._schema === "object") {
|
|
250
|
+
const Constructor = maybeStripped.constructor;
|
|
251
|
+
return new Constructor(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, fieldWithSchema._schema), {}, { required: false }));
|
|
252
|
+
}
|
|
253
|
+
return maybeStripped;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Recursively strips defaults from a primitive and nested child primitives.
|
|
257
|
+
* This is used by partial({ stripDefaults: true }) so omitted fields resolve to undefined.
|
|
258
|
+
*/
|
|
259
|
+
_stripDefaultsRecursively(field) {
|
|
260
|
+
const fieldWithSchema = field;
|
|
261
|
+
if (!fieldWithSchema._schema || typeof fieldWithSchema._schema !== "object") return field;
|
|
262
|
+
const nextSchema = require_objectSpread2._objectSpread2({}, fieldWithSchema._schema);
|
|
263
|
+
if (nextSchema["fields"] && typeof nextSchema["fields"] === "object" && !Array.isArray(nextSchema["fields"])) {
|
|
264
|
+
const nextFields = {};
|
|
265
|
+
for (const key in nextSchema["fields"]) {
|
|
266
|
+
const nestedField = nextSchema["fields"][key];
|
|
267
|
+
nextFields[key] = this._stripDefaultsRecursively(nestedField);
|
|
268
|
+
}
|
|
269
|
+
nextSchema["fields"] = nextFields;
|
|
270
|
+
}
|
|
271
|
+
if (nextSchema["element"] && typeof nextSchema["element"] === "object") nextSchema["element"] = this._stripDefaultsRecursively(nextSchema["element"]);
|
|
272
|
+
if (Array.isArray(nextSchema["variants"])) nextSchema["variants"] = nextSchema["variants"].map((variant) => this._stripDefaultsRecursively(variant));
|
|
273
|
+
else if (nextSchema["variants"] && typeof nextSchema["variants"] === "object") {
|
|
274
|
+
const nextVariants = {};
|
|
275
|
+
for (const key in nextSchema["variants"]) {
|
|
276
|
+
const nestedVariant = nextSchema["variants"][key];
|
|
277
|
+
nextVariants[key] = this._stripDefaultsRecursively(nestedVariant);
|
|
278
|
+
}
|
|
279
|
+
nextSchema["variants"] = nextVariants;
|
|
245
280
|
}
|
|
246
|
-
|
|
281
|
+
if (nextSchema["root"] && typeof nextSchema["root"] === "object") nextSchema["root"] = this._stripDefaultsRecursively(nextSchema["root"]);
|
|
282
|
+
if ("defaultValue" in nextSchema) nextSchema["defaultValue"] = void 0;
|
|
283
|
+
if ("defaultInput" in nextSchema) nextSchema["defaultInput"] = void 0;
|
|
284
|
+
const Constructor = field.constructor;
|
|
285
|
+
return new Constructor(nextSchema);
|
|
247
286
|
}
|
|
248
287
|
_isRequiredWithoutDefault(field) {
|
|
249
288
|
var _schema;
|
|
@@ -53,11 +53,20 @@ type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = { readonl
|
|
|
53
53
|
* Preserves the primitive structure while changing the required flag.
|
|
54
54
|
*/
|
|
55
55
|
type MakeOptional<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, infer H, infer SI, infer UI> ? Primitive<S, P, false, H, SI, UI> : T;
|
|
56
|
+
/**
|
|
57
|
+
* Transforms a primitive type to make it optional and strip its default (TRequired = false, THasDefault = false).
|
|
58
|
+
*/
|
|
59
|
+
type MakeOptionalNoDefault<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, any, infer SI, infer UI> ? Primitive<S, P, false, false, SI, UI> : T;
|
|
56
60
|
/**
|
|
57
61
|
* Maps each field in a struct to its optional version.
|
|
58
62
|
* All fields become optional (TRequired = false).
|
|
59
63
|
*/
|
|
60
64
|
type PartialFields<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptional<TFields[K]> };
|
|
65
|
+
/**
|
|
66
|
+
* Maps each field in a struct to its optional version with defaults stripped.
|
|
67
|
+
* All fields become optional (TRequired = false) and lose their defaults (THasDefault = false).
|
|
68
|
+
*/
|
|
69
|
+
type PartialFieldsNoDefault<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptionalNoDefault<TFields[K]> };
|
|
61
70
|
/**
|
|
62
71
|
* Maps a schema definition to its proxy type.
|
|
63
72
|
* Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.
|
|
@@ -99,14 +108,24 @@ declare class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TReq
|
|
|
99
108
|
refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault>;
|
|
100
109
|
/** Extend this struct with additional fields */
|
|
101
110
|
extend<TNewFields extends Record<string, AnyPrimitive>>(newFields: TNewFields): StructPrimitive<TFields & TNewFields, TRequired, THasDefault>;
|
|
102
|
-
/** Make all properties of this struct optional (TRequired = false for all fields) */
|
|
103
|
-
partial(
|
|
111
|
+
/** Make all properties of this struct optional (TRequired = false for all fields), optionally stripping defaults */
|
|
112
|
+
partial(options: {
|
|
113
|
+
stripDefaults: true;
|
|
114
|
+
}): StructPrimitive<PartialFieldsNoDefault<TFields>, TRequired, THasDefault>;
|
|
115
|
+
partial(options?: {
|
|
116
|
+
stripDefaults?: boolean;
|
|
117
|
+
}): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>;
|
|
104
118
|
private _makeFieldOptional;
|
|
119
|
+
/**
|
|
120
|
+
* Recursively strips defaults from a primitive and nested child primitives.
|
|
121
|
+
* This is used by partial({ stripDefaults: true }) so omitted fields resolve to undefined.
|
|
122
|
+
*/
|
|
123
|
+
private _stripDefaultsRecursively;
|
|
105
124
|
private _isRequiredWithoutDefault;
|
|
106
125
|
readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>>;
|
|
107
126
|
}
|
|
108
127
|
/** Creates a new StructPrimitive with the given fields */
|
|
109
128
|
declare const Struct: <TFields extends Record<string, AnyPrimitive>>(fields: TFields) => StructPrimitive<TFields, false, false>;
|
|
110
129
|
//#endregion
|
|
111
|
-
export { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
|
|
130
|
+
export { InferStructSnapshot, InferStructState, MakeOptional, MakeOptionalNoDefault, PartialFields, PartialFieldsNoDefault, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
|
|
112
131
|
//# sourceMappingURL=Struct.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Struct.d.cts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":";;;;;;AAM8L;AAYhJ;KAAzC,gBAK+C,CAAA,CAAA,CAAA,GALzB,CAKyB,SALf,SAKe,CAAA,GAAA,EAAA,GAAA,EAAA,IAAA,EAAA,KAAA,CAAA,GAAA,IAAA,GAAA,KAAA;;;;KAA/C,eAC4C,CAAA,gBADZ,MACY,CAAA,MAAA,EADG,YACH,CAAA,CAAA,GAAA,QAAzB,MAAV,OAAU,GAAA,gBAAA,CAAiB,OAAjB,CAAyB,CAAzB,CAAA,CAAA,SAAA,IAAA,GAA4C,CAA5C,GAAA,KAAA,EAA4C,CAAA,MAC5D,OAD4D,CAAA;;;AACrD;KAKV,eAA+C,CAAA,gBAAf,MAAe,CAAA,MAAA,EAAA,YAAA,CAAA,CAAA,GAAA,QAAf,MACvB,OADuB,GACb,gBADa,CACI,OADJ,CACY,CADZ,CAAA,CAAA,SAAA,IAAA,GAAA,KAAA,GACuC,CADvC,EACvB,CAAA,MACN,OADM,CAAA;;;;;;;AASF,KAAA,cAAc,CAAA,gBAAiB,MAAjB,CAAA,MAAA,EAAgC,YAAhC,CAAA,CAAA,GAAA,iBACP,eADuC,CACvB,OADuB,CAAA,GACZ,aADY,CACE,OADF,CACU,CADV,CAAA,CAAA,EAAf,GAAA,iBAExB,eADgB,CACA,OADA,CAAA,IACY,aADZ,CAC0B,OAD1B,CACkC,CADlC,CAAA,CAAA,EAAhB;;;;;;KAQd,mBAPwD,CAAA,gBAOpB,MAPoB,CAAA,MAAA,EAOL,YAPK,CAAA,EAAA,kBAAA,OAAA,EAAA,oBAAA,OAAA,CAAA,GAQ3D,UAR2D,CAQhD,cARgD,CAQjC,OARiC,CAAA,EAQvB,SARuB,EAQZ,WARY,CAAA;;;;AAAc;KActE,sBAPmD,CAAA,gBAOZ,MAPY,CAAA,MAAA,EAOG,YAPH,CAAA,CAAA,GAOoB,iBAPpB,CAOsC,OAPtC,CAAA;;;;;AACP,KAarC,gBAbqC,CAAA,gBAaJ,MAbI,CAAA,MAAA,EAaW,YAbX,CAAA,CAAA,GAAA,iBAA/C,MAcqB,OAdrB,GAc+B,UAd/B,CAc0C,OAd1C,CAckD,CAdlD,CAAA,CAAA,EAAU;AAAA;;;;AAMgE,KAehE,mBAfgE,CAAA,gBAe5B,MAf4B,CAAA,MAAA,EAeb,YAfa,CAAA,CAAA,GAAA,iBAAiB,MAgBtE,OAhBsE,GAgB5D,aAhB4D,CAgB9C,OAhB8C,CAgBtC,CAhBsC,CAAA,CAAA,EAO7F;;;;;AACoD,KAexC,iBAfwC,CAAA,gBAeN,MAfM,CAAA,MAAA,EAeS,YAfT,CAAA,CAAA,GAAA,iBAAnB,MAgBV,OAhBU,IAgBC,gBAhBD,CAgBkB,OAhBlB,CAgB0B,CAhB1B,CAAA,CAAA,EAAU;AAO3C;;;;AAC+C,KAenC,YAfmC,CAAA,UAeZ,YAfY,CAAA,GAeI,CAfJ,SAec,SAfd,CAAA,KAAA,EAAA,EAAA,KAAA,EAAA,EAAA,GAAA,EAAA,KAAA,EAAA,EAAA,KAAA,GAAA,EAAA,KAAA,GAAA,CAAA,GAgB3C,SAhB2C,CAgBjC,CAhBiC,EAgB9B,CAhB8B,EAAA,KAAA,EAgBpB,CAhBoB,EAgBjB,EAhBiB,EAgBb,EAhBa,CAAA,GAiB3C,CAjB2C;;;;
|
|
1
|
+
{"version":3,"file":"Struct.d.cts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -54,11 +54,20 @@ type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = { readonl
|
|
|
54
54
|
* Preserves the primitive structure while changing the required flag.
|
|
55
55
|
*/
|
|
56
56
|
type MakeOptional<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, infer H, infer SI, infer UI> ? Primitive<S, P, false, H, SI, UI> : T;
|
|
57
|
+
/**
|
|
58
|
+
* Transforms a primitive type to make it optional and strip its default (TRequired = false, THasDefault = false).
|
|
59
|
+
*/
|
|
60
|
+
type MakeOptionalNoDefault<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, any, infer SI, infer UI> ? Primitive<S, P, false, false, SI, UI> : T;
|
|
57
61
|
/**
|
|
58
62
|
* Maps each field in a struct to its optional version.
|
|
59
63
|
* All fields become optional (TRequired = false).
|
|
60
64
|
*/
|
|
61
65
|
type PartialFields<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptional<TFields[K]> };
|
|
66
|
+
/**
|
|
67
|
+
* Maps each field in a struct to its optional version with defaults stripped.
|
|
68
|
+
* All fields become optional (TRequired = false) and lose their defaults (THasDefault = false).
|
|
69
|
+
*/
|
|
70
|
+
type PartialFieldsNoDefault<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptionalNoDefault<TFields[K]> };
|
|
62
71
|
/**
|
|
63
72
|
* Maps a schema definition to its proxy type.
|
|
64
73
|
* Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.
|
|
@@ -100,14 +109,24 @@ declare class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TReq
|
|
|
100
109
|
refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault>;
|
|
101
110
|
/** Extend this struct with additional fields */
|
|
102
111
|
extend<TNewFields extends Record<string, AnyPrimitive>>(newFields: TNewFields): StructPrimitive<TFields & TNewFields, TRequired, THasDefault>;
|
|
103
|
-
/** Make all properties of this struct optional (TRequired = false for all fields) */
|
|
104
|
-
partial(
|
|
112
|
+
/** Make all properties of this struct optional (TRequired = false for all fields), optionally stripping defaults */
|
|
113
|
+
partial(options: {
|
|
114
|
+
stripDefaults: true;
|
|
115
|
+
}): StructPrimitive<PartialFieldsNoDefault<TFields>, TRequired, THasDefault>;
|
|
116
|
+
partial(options?: {
|
|
117
|
+
stripDefaults?: boolean;
|
|
118
|
+
}): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>;
|
|
105
119
|
private _makeFieldOptional;
|
|
120
|
+
/**
|
|
121
|
+
* Recursively strips defaults from a primitive and nested child primitives.
|
|
122
|
+
* This is used by partial({ stripDefaults: true }) so omitted fields resolve to undefined.
|
|
123
|
+
*/
|
|
124
|
+
private _stripDefaultsRecursively;
|
|
106
125
|
private _isRequiredWithoutDefault;
|
|
107
126
|
readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>>;
|
|
108
127
|
}
|
|
109
128
|
/** Creates a new StructPrimitive with the given fields */
|
|
110
129
|
declare const Struct: <TFields extends Record<string, AnyPrimitive>>(fields: TFields) => StructPrimitive<TFields, false, false>;
|
|
111
130
|
//#endregion
|
|
112
|
-
export { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
|
|
131
|
+
export { InferStructSnapshot, InferStructState, MakeOptional, MakeOptionalNoDefault, PartialFields, PartialFieldsNoDefault, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
|
|
113
132
|
//# sourceMappingURL=Struct.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Struct.d.mts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAM8L;AAYhJ,KAAzC,gBAKA,CAAe,CAAA,CAAA,GALO,CAKP,SALiB,SAKjB,CAAA,GAAA,EAAA,GAAA,EAAA,IAAA,EAAA,KAAA,CAAA,GAAA,IAAA,GAAA,KAAA;;;;KAAf,eACoC,CAAA,gBADJ,MACI,CAAA,MAAA,EADW,YACX,CAAA,CAAA,GAAA,QAAQ,MAAnC,OAAmC,GAAzB,gBAAyB,CAAR,OAAQ,CAAA,CAAA,CAAA,CAAA,SAAA,IAAA,GAAmB,CAAnB,GAAA,KAAA,EAAzB,CAAA,MAChB,OADgB,CAAA;;;;AACT,KAKV,eAAA,CAAA,gBAAgC,MAAjB,CAAA,MAAA,EAAgC,YAAhC,CAAA,CAAA,GAAA,QAAgC,MACtC,OADsC,GAC5B,gBAD4B,CACX,OADW,CACH,CADG,CAAA,CAAA,SAAA,IAAA,GAAA,KAAA,GACwB,CADxB,EAAf,CAAA,MAE7B,OAF6B,CAAA;;;;;;;AAEtB,KAQH,cARG,CAAA,gBAQ4B,MAR5B,CAAA,MAAA,EAQ2C,YAR3C,CAAA,CAAA,GAAA,iBASI,eADO,CACS,OADT,CAAA,GACoB,aADpB,CACkC,OADlC,CAC0C,CAD1C,CAAA,CAAA,EAAgC,GAAA,iBAEvC,eAFwB,CAER,OAFQ,CAAA,IAEI,aAFJ,CAEkB,OAFlB,CAE0B,CAF1B,CAAA,CAAA,EACR;;;;;;KAQ9B,mBAPc,CAAA,gBAOsB,MAPtB,CAAA,MAAA,EAOqC,YAPrC,CAAA,EAAA,kBAAA,OAAA,EAAA,oBAAA,OAAA,CAAA,GAQjB,UARiB,CAQN,cARM,CAQS,OART,CAAA,EAQmB,SARnB,EAQ8B,WAR9B,CAAA;;;;;AAAwD,KActE,sBAPmB,CAAA,gBAOoB,MAPpB,CAAA,MAAA,EAOmC,YAPnC,CAAA,CAAA,GAOoD,iBAPpD,CAOsE,OAPtE,CAAA;;;;;AACc,KAa1B,gBAb0B,CAAA,gBAaO,MAbP,CAAA,MAAA,EAasB,YAbtB,CAAA,CAAA,GAAA,iBAAW,MAc1B,OAd0B,GAchB,UAdgB,CAcL,OAdK,CAcG,CAdH,CAAA,CAAA,EAA/C;;AAAU;;;AAMkF,KAelF,mBAfkF,CAAA,gBAe9C,MAf8C,CAAA,MAAA,EAe/B,YAf+B,CAAA,CAAA,GAAA,iBAAlB,MAgBrD,OAhBqD,GAgB3C,aAhB2C,CAgB7B,OAhB6B,CAgBrB,CAhBqB,CAAA,CAAA,EAAiB;AAO7F;;;;AAC4C,KAehC,iBAfgC,CAAA,gBAeE,MAfF,CAAA,MAAA,EAeiB,YAfjB,CAAA,CAAA,GAAA,iBAAQ,MAgB7B,OAhB6B,IAgBlB,gBAhBkB,CAgBD,OAhBC,CAgBO,CAhBP,CAAA,CAAA,EAAnB;;AAOjC;;;AACuB,KAeX,YAfW,CAAA,UAeY,YAfZ,CAAA,GAe4B,CAf5B,SAesC,SAftC,CAAA,KAAA,EAAA,EAAA,KAAA,EAAA,EAAA,GAAA,EAAA,KAAA,EAAA,EAAA,KAAA,GAAA,EAAA,KAAA,GAAA,CAAA,GAgBnB,SAhBmB,CAgBT,CAhBS,EAgBN,CAhBM,EAAA,KAAA,EAgBI,CAhBJ,EAgBO,EAhBP,EAgBW,EAhBX,CAAA,GAiBnB,CAjBmB
|
|
1
|
+
{"version":3,"file":"Struct.d.mts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
|
|
@@ -222,13 +222,19 @@ var StructPrimitive = class StructPrimitive {
|
|
|
222
222
|
validators: []
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
|
-
|
|
226
|
-
|
|
225
|
+
partial(options) {
|
|
226
|
+
const stripDefaults = options === null || options === void 0 ? void 0 : options.stripDefaults;
|
|
227
227
|
const partialFields = {};
|
|
228
228
|
for (const key in this._schema.fields) {
|
|
229
229
|
const field = this._schema.fields[key];
|
|
230
|
-
partialFields[key] = this._makeFieldOptional(field);
|
|
230
|
+
partialFields[key] = this._makeFieldOptional(field, stripDefaults);
|
|
231
231
|
}
|
|
232
|
+
if (stripDefaults) return new StructPrimitive({
|
|
233
|
+
required: this._schema.required,
|
|
234
|
+
defaultValue: void 0,
|
|
235
|
+
fields: partialFields,
|
|
236
|
+
validators: []
|
|
237
|
+
});
|
|
232
238
|
return new StructPrimitive({
|
|
233
239
|
required: this._schema.required,
|
|
234
240
|
defaultValue: void 0,
|
|
@@ -236,13 +242,46 @@ var StructPrimitive = class StructPrimitive {
|
|
|
236
242
|
validators: []
|
|
237
243
|
});
|
|
238
244
|
}
|
|
239
|
-
_makeFieldOptional(field) {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
245
|
+
_makeFieldOptional(field, stripDefaults) {
|
|
246
|
+
const maybeStripped = stripDefaults ? this._stripDefaultsRecursively(field) : field;
|
|
247
|
+
const fieldWithSchema = maybeStripped;
|
|
248
|
+
if (fieldWithSchema._schema && typeof fieldWithSchema._schema === "object") {
|
|
249
|
+
const Constructor = maybeStripped.constructor;
|
|
250
|
+
return new Constructor(_objectSpread2(_objectSpread2({}, fieldWithSchema._schema), {}, { required: false }));
|
|
251
|
+
}
|
|
252
|
+
return maybeStripped;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Recursively strips defaults from a primitive and nested child primitives.
|
|
256
|
+
* This is used by partial({ stripDefaults: true }) so omitted fields resolve to undefined.
|
|
257
|
+
*/
|
|
258
|
+
_stripDefaultsRecursively(field) {
|
|
259
|
+
const fieldWithSchema = field;
|
|
260
|
+
if (!fieldWithSchema._schema || typeof fieldWithSchema._schema !== "object") return field;
|
|
261
|
+
const nextSchema = _objectSpread2({}, fieldWithSchema._schema);
|
|
262
|
+
if (nextSchema["fields"] && typeof nextSchema["fields"] === "object" && !Array.isArray(nextSchema["fields"])) {
|
|
263
|
+
const nextFields = {};
|
|
264
|
+
for (const key in nextSchema["fields"]) {
|
|
265
|
+
const nestedField = nextSchema["fields"][key];
|
|
266
|
+
nextFields[key] = this._stripDefaultsRecursively(nestedField);
|
|
267
|
+
}
|
|
268
|
+
nextSchema["fields"] = nextFields;
|
|
269
|
+
}
|
|
270
|
+
if (nextSchema["element"] && typeof nextSchema["element"] === "object") nextSchema["element"] = this._stripDefaultsRecursively(nextSchema["element"]);
|
|
271
|
+
if (Array.isArray(nextSchema["variants"])) nextSchema["variants"] = nextSchema["variants"].map((variant) => this._stripDefaultsRecursively(variant));
|
|
272
|
+
else if (nextSchema["variants"] && typeof nextSchema["variants"] === "object") {
|
|
273
|
+
const nextVariants = {};
|
|
274
|
+
for (const key in nextSchema["variants"]) {
|
|
275
|
+
const nestedVariant = nextSchema["variants"][key];
|
|
276
|
+
nextVariants[key] = this._stripDefaultsRecursively(nestedVariant);
|
|
277
|
+
}
|
|
278
|
+
nextSchema["variants"] = nextVariants;
|
|
244
279
|
}
|
|
245
|
-
|
|
280
|
+
if (nextSchema["root"] && typeof nextSchema["root"] === "object") nextSchema["root"] = this._stripDefaultsRecursively(nextSchema["root"]);
|
|
281
|
+
if ("defaultValue" in nextSchema) nextSchema["defaultValue"] = void 0;
|
|
282
|
+
if ("defaultInput" in nextSchema) nextSchema["defaultInput"] = void 0;
|
|
283
|
+
const Constructor = field.constructor;
|
|
284
|
+
return new Constructor(nextSchema);
|
|
246
285
|
}
|
|
247
286
|
_isRequiredWithoutDefault(field) {
|
|
248
287
|
var _schema;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Struct.mjs","names":["OperationDefinition.make","snapshot: Record<string, unknown>","Operation.fromDefinition","newState: InferStructState<TFields>","initialState: Record<string, unknown>","OperationPath.pathsOverlap","partialFields: Record<string, AnyPrimitive>"],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":["import { Schema } from \"effect\";\nimport * as OperationDefinition from \"../OperationDefinition\";\nimport * as Operation from \"../Operation\";\nimport * as OperationPath from \"../OperationPath\";\nimport * as ProxyEnvironment from \"../ProxyEnvironment\";\nimport * as Transform from \"../Transform\";\nimport type { Primitive, PrimitiveInternal, MaybeUndefined, AnyPrimitive, Validator, InferState, InferProxy, InferSnapshot, NeedsValue, InferUpdateInput, InferSetInput } from \"../Primitive\";\nimport { ValidationError } from \"../Primitive\";\nimport { runValidators, applyDefaults, primitiveAllowsNullValue } from \"./shared\";\n\n// =============================================================================\n// Struct Set Input Types\n// =============================================================================\n\n/**\n * Determines if a field is required for set() operations.\n * A field is required if: TRequired is true AND THasDefault is false\n */\ntype IsRequiredForSet<T> = T extends Primitive<any, any, true, false> ? true : false;\n\n/**\n * Extract keys of fields that are required for set() (required without default).\n */\ntype RequiredSetKeys<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: IsRequiredForSet<TFields[K]> extends true ? K : never;\n}[keyof TFields];\n\n/**\n * Extract keys of fields that are optional for set() (has default OR not required).\n */\ntype OptionalSetKeys<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: IsRequiredForSet<TFields[K]> extends true ? never : K;\n}[keyof TFields];\n\n/**\n * Compute the input type for set() operations on a struct.\n * Required fields (required without default) must be provided.\n * Optional fields (has default or not required) can be omitted.\n * Uses each field's TSetInput type to handle nested structs correctly.\n */\nexport type StructSetInput<TFields extends Record<string, AnyPrimitive>> = \n { readonly [K in RequiredSetKeys<TFields>]: InferSetInput<TFields[K]> } &\n { readonly [K in OptionalSetKeys<TFields>]?: InferSetInput<TFields[K]> };\n\n/**\n * Input type for set() - respects required/default status of the struct.\n * If the struct is required without a default, the value must be provided.\n * The value itself uses StructSetInput which handles field-level required/default logic.\n */\ntype InferStructSetInput<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean, THasDefault extends boolean> = \n NeedsValue<StructSetInput<TFields>, TRequired, THasDefault>;\n\n/**\n * Input type for update() - always partial since update only modifies specified fields.\n * For nested structs, allows recursive partial updates.\n */\ntype InferStructUpdateInput<TFields extends Record<string, AnyPrimitive>> = StructUpdateValue<TFields>;\n\n\n/**\n * Maps a schema definition to its state type.\n * { name: StringPrimitive, age: NumberPrimitive } -> { name: string, age: number }\n */\nexport type InferStructState<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]: InferState<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to its snapshot type.\n * Each field's snapshot type is inferred from the field primitive.\n */\nexport type InferStructSnapshot<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]: InferSnapshot<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to a partial update type.\n * Uses each field's TUpdateInput type, which handles nested updates recursively.\n */\nexport type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]?: InferUpdateInput<TFields[K]>;\n};\n\n/**\n * Transforms a primitive type to make it optional (TRequired = false).\n * Preserves the primitive structure while changing the required flag.\n */\nexport type MakeOptional<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, infer H, infer SI, infer UI>\n ? Primitive<S, P, false, H, SI, UI>\n : T;\n\n/**\n * Maps each field in a struct to its optional version.\n * All fields become optional (TRequired = false).\n */\nexport type PartialFields<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: MakeOptional<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to its proxy type.\n * Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.\n */\nexport type StructProxy<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean = false, THasDefault extends boolean = false> = {\n readonly [K in keyof TFields]: InferProxy<TFields[K]>;\n} & {\n /** Gets the entire struct value */\n get(): MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault>;\n /** Sets the entire struct value (only fields that are required without defaults must be provided) */\n set(value: InferStructSetInput<TFields, TRequired, THasDefault>): void;\n /** Updates only the specified fields (partial update, handles nested structs recursively) */\n update(value: InferStructUpdateInput<TFields>): void;\n /** Returns a readonly snapshot of the struct for rendering */\n toSnapshot(): MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault>;\n};\n\ninterface StructPrimitiveSchema<TFields extends Record<string, AnyPrimitive>> {\n readonly required: boolean;\n readonly defaultValue: InferStructState<TFields> | undefined;\n readonly fields: TFields;\n readonly validators: readonly Validator<InferStructState<TFields>>[];\n}\n\nexport class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean = false, THasDefault extends boolean = false>\n implements Primitive<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>, TRequired, THasDefault, InferStructSetInput<TFields, TRequired, THasDefault>, InferStructUpdateInput<TFields>>\n{\n readonly _tag = \"StructPrimitive\" as const;\n readonly _State!: InferStructState<TFields>;\n readonly _Proxy!: StructProxy<TFields, TRequired, THasDefault>;\n readonly _TRequired!: TRequired;\n readonly _THasDefault!: THasDefault;\n readonly TSetInput!: InferStructSetInput<TFields, TRequired, THasDefault>;\n readonly TUpdateInput!: InferStructUpdateInput<TFields>;\n\n private readonly _schema: StructPrimitiveSchema<TFields>;\n\n private readonly _opDefinitions = {\n set: OperationDefinition.make({\n kind: \"struct.set\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n unset: OperationDefinition.make({\n kind: \"struct.unset\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n };\n\n constructor(schema: StructPrimitiveSchema<TFields>) {\n this._schema = schema;\n }\n\n /** Mark this struct as required */\n required(): StructPrimitive<TFields, true, THasDefault> {\n return new StructPrimitive({\n ...this._schema,\n required: true,\n });\n }\n\n /** Set a default value for this struct */\n default(defaultValue: StructSetInput<TFields>): StructPrimitive<TFields, TRequired, true> {\n // Apply defaults to the provided value\n const merged = applyDefaults(this as AnyPrimitive, defaultValue as Partial<InferStructState<TFields>>) as InferStructState<TFields>;\n return new StructPrimitive({\n ...this._schema,\n defaultValue: merged,\n });\n }\n\n /** Get the fields schema */\n get fields(): TFields {\n return this._schema.fields;\n }\n\n /** Add a custom validation rule (useful for cross-field validation) */\n refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault> {\n return new StructPrimitive({\n ...this._schema,\n validators: [...this._schema.validators, { validate: fn, message }],\n });\n }\n\n /** Extend this struct with additional fields */\n extend<TNewFields extends Record<string, AnyPrimitive>>(\n newFields: TNewFields\n ): StructPrimitive<TFields & TNewFields, TRequired, THasDefault> {\n return new StructPrimitive<TFields & TNewFields, TRequired, THasDefault>({\n required: this._schema.required,\n defaultValue: undefined,\n fields: { ...this._schema.fields, ...newFields } as TFields & TNewFields,\n validators: [],\n });\n }\n\n /** Make all properties of this struct optional (TRequired = false for all fields) */\n partial(): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault> {\n const partialFields: Record<string, AnyPrimitive> = {};\n for (const key in this._schema.fields) {\n const field = this._schema.fields[key]!;\n // Create a new field that is not required (optional)\n partialFields[key] = this._makeFieldOptional(field);\n }\n return new StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>({\n required: this._schema.required,\n defaultValue: undefined,\n fields: partialFields as PartialFields<TFields>,\n validators: [],\n });\n }\n\n private _makeFieldOptional(field: AnyPrimitive): AnyPrimitive {\n // Create a new primitive with required: false\n // We access the _schema property if available, otherwise return as-is\n const fieldAny = field as any;\n if (fieldAny._schema && typeof fieldAny._schema === \"object\") {\n const Constructor = field.constructor as new (schema: any) => AnyPrimitive;\n return new Constructor({\n ...fieldAny._schema,\n required: false,\n });\n }\n return field;\n }\n\n private _isRequiredWithoutDefault(field: AnyPrimitive): boolean {\n const fieldDefault = field._internal.getInitialState();\n return (\n (field as { _schema?: { required?: boolean } })._schema?.required === true &&\n fieldDefault === undefined\n );\n }\n\n readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>> = {\n createProxy: (env: ProxyEnvironment.ProxyEnvironment, operationPath: OperationPath.OperationPath): StructProxy<TFields, TRequired, THasDefault> => {\n const fields = this._schema.fields;\n const defaultValue = this._schema.defaultValue;\n\n // Helper to build a snapshot by calling toSnapshot on each field\n const buildSnapshot = (): InferStructSnapshot<TFields> | undefined => {\n const state = env.getState(operationPath);\n \n // Build snapshot from field proxies (they handle their own defaults)\n const snapshot: Record<string, unknown> = {};\n let hasAnyDefinedField = false;\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n const fieldPath = operationPath.append(key);\n const fieldProxy = fieldPrimitive._internal.createProxy(env, fieldPath);\n const fieldSnapshot = (fieldProxy as { toSnapshot(): unknown }).toSnapshot();\n snapshot[key] = fieldSnapshot;\n if (fieldSnapshot !== undefined) {\n hasAnyDefinedField = true;\n }\n }\n \n // Return undefined only if there's no state, no struct default, and no field snapshots\n if (state === undefined && defaultValue === undefined && !hasAnyDefinedField) {\n return undefined;\n }\n \n return snapshot as InferStructSnapshot<TFields>;\n };\n\n // Create the base object with get/set/update/toSnapshot methods\n const base = {\n get: (): MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferStructState<TFields> | undefined;\n return (state ?? defaultValue) as MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault>;\n },\n set: (value: InferStructSetInput<TFields, TRequired, THasDefault>) => {\n // Apply defaults for missing fields\n const merged = applyDefaults(this as AnyPrimitive, value as Partial<InferStructState<TFields>>) as InferStructState<TFields>;\n env.addOperation(\n Operation.fromDefinition(operationPath, this._opDefinitions.set, merged)\n );\n },\n update: (value: InferStructUpdateInput<TFields>) => {\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n const fieldValue = value[key as keyof TFields];\n const fieldPrimitive = fields[key as keyof TFields];\n if (!fieldPrimitive) continue; // Skip unknown fields\n\n const fieldPath = operationPath.append(key);\n\n const shouldUnset =\n fieldValue === undefined ||\n (fieldValue === null && !primitiveAllowsNullValue(fieldPrimitive));\n if (shouldUnset) {\n if (this._isRequiredWithoutDefault(fieldPrimitive)) {\n throw new ValidationError(`Field \"${key}\" is required and cannot be null or undefined`);\n }\n env.addOperation(\n Operation.fromDefinition(fieldPath, this._opDefinitions.unset, null)\n );\n continue;\n }\n\n const fieldProxy = fieldPrimitive._internal.createProxy(env, fieldPath);\n\n // Check if this is a nested struct and value is a plain object (partial update)\n if (\n fieldPrimitive._tag === \"StructPrimitive\" &&\n typeof fieldValue === \"object\" &&\n fieldValue !== null &&\n !Array.isArray(fieldValue)\n ) {\n // Recursively update nested struct\n (fieldProxy as { update: (v: unknown) => void }).update(fieldValue);\n } else {\n // Set the field value directly\n (fieldProxy as { set: (v: unknown) => void }).set(fieldValue);\n }\n }\n }\n },\n toSnapshot: (): MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault> => {\n const snapshot = buildSnapshot();\n return snapshot as MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault>;\n },\n };\n\n // Use a JavaScript Proxy to intercept field access\n return new globalThis.Proxy(base as StructProxy<TFields, TRequired, THasDefault>, {\n get: (target, prop, _receiver) => {\n // Return base methods (get, set, update, toSnapshot)\n if (prop === \"get\") {\n return target.get;\n }\n if (prop === \"set\") {\n return target.set;\n }\n if (prop === \"update\") {\n return target.update;\n }\n if (prop === \"toSnapshot\") {\n return target.toSnapshot;\n }\n\n // Handle symbol properties (like Symbol.toStringTag)\n if (typeof prop === \"symbol\") {\n return undefined;\n }\n\n // Check if prop is a field in the schema\n if (prop in fields) {\n const fieldPrimitive = fields[prop as keyof TFields]!;\n const fieldPath = operationPath.append(prop as string);\n return fieldPrimitive._internal.createProxy(env, fieldPath);\n }\n\n return undefined;\n },\n has: (_target, prop) => {\n if (prop === \"get\" || prop === \"set\" || prop === \"update\" || prop === \"toSnapshot\") return true;\n if (typeof prop === \"string\" && prop in fields) return true;\n return false;\n },\n });\n },\n\n applyOperation: (\n state: InferStructState<TFields> | undefined,\n operation: Operation.Operation<any, any, any>\n ): InferStructState<TFields> => {\n const path = operation.path;\n const tokens = path.toTokens().filter((t: string) => t !== \"\");\n\n let newState: InferStructState<TFields>;\n\n // If path is empty or root, this is a struct.set operation\n if (tokens.length === 0) {\n if (operation.kind !== \"struct.set\") {\n throw new ValidationError(`StructPrimitive root cannot apply operation of kind: ${operation.kind}`);\n }\n\n const payload = operation.payload;\n if (typeof payload !== \"object\" || payload === null) {\n throw new ValidationError(`StructPrimitive.set requires an object payload`);\n }\n\n newState = payload as InferStructState<TFields>;\n } else {\n // Otherwise, delegate to the appropriate field primitive\n const fieldName = tokens[0] as keyof TFields;\n if (!(fieldName in this._schema.fields)) {\n throw new ValidationError(`Unknown field: ${globalThis.String(fieldName)}`);\n }\n\n const fieldPrimitive = this._schema.fields[fieldName]!;\n // Get the current field state\n const currentState = state ?? ({} as InferStructState<TFields>);\n if (operation.kind === \"struct.unset\" && tokens.length === 1) {\n if (this._isRequiredWithoutDefault(fieldPrimitive)) {\n throw new ValidationError(`Field \"${globalThis.String(fieldName)}\" is required and cannot be removed`);\n }\n const mutableState = { ...currentState } as Record<string, unknown>;\n delete mutableState[globalThis.String(fieldName)];\n newState = mutableState as InferStructState<TFields>;\n } else {\n const remainingPath = path.shift();\n const fieldOperation = {\n ...operation,\n path: remainingPath,\n };\n const currentFieldState = currentState[fieldName] as InferState<typeof fieldPrimitive> | undefined;\n\n // Apply the operation to the field\n const newFieldState = fieldPrimitive._internal.applyOperation(currentFieldState, fieldOperation);\n\n // Build updated state\n newState = {\n ...currentState,\n [fieldName]: newFieldState,\n };\n }\n }\n\n // Run validators on the new state\n runValidators(newState, this._schema.validators);\n\n return newState;\n },\n\n getInitialState: (): InferStructState<TFields> | undefined => {\n if (this._schema.defaultValue !== undefined) {\n return this._schema.defaultValue;\n }\n\n // Build initial state from field defaults\n const fields = this._schema.fields;\n const initialState: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const key in fields) {\n const fieldDefault = fields[key]!._internal.getInitialState();\n if (fieldDefault !== undefined) {\n initialState[key] = fieldDefault;\n hasAnyDefault = true;\n }\n }\n\n return hasAnyDefault ? (initialState as InferStructState<TFields>) : undefined;\n },\n\n transformOperation: (\n clientOp: Operation.Operation<any, any, any>,\n serverOp: Operation.Operation<any, any, any>\n ): Transform.TransformResult => {\n const clientPath = clientOp.path;\n const serverPath = serverOp.path;\n\n // If paths don't overlap at all, no transformation needed\n if (!OperationPath.pathsOverlap(clientPath, serverPath)) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientTokens = clientPath.toTokens().filter((t: string) => t !== \"\");\n const serverTokens = serverPath.toTokens().filter((t: string) => t !== \"\");\n\n // If both are at root level (struct.set operations)\n if (clientTokens.length === 0 && serverTokens.length === 0) {\n // Client wins (last-write-wins)\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If server set entire struct and client is updating a field\n if (serverTokens.length === 0 && serverOp.kind === \"struct.set\") {\n // Client's field operation proceeds - optimistic update\n // Server will validate/reject if needed\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If client set entire struct and server is updating a field\n if (clientTokens.length === 0 && clientOp.kind === \"struct.set\") {\n // Client's struct.set supersedes server's field update\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Both operations target fields\n if (clientTokens.length > 0 && serverTokens.length > 0) {\n const clientField = clientTokens[0] as keyof TFields;\n const serverField = serverTokens[0] as keyof TFields;\n\n // Different fields - no conflict\n if (clientField !== serverField) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Same field - delegate to field primitive\n const fieldPrimitive = this._schema.fields[clientField];\n if (!fieldPrimitive) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientOpForField = {\n ...clientOp,\n path: clientOp.path.shift(),\n };\n const serverOpForField = {\n ...serverOp,\n path: serverOp.path.shift(),\n };\n\n const result = fieldPrimitive._internal.transformOperation(clientOpForField, serverOpForField);\n\n if (result.type === \"transformed\") {\n // Restore the original path\n return {\n type: \"transformed\",\n operation: {\n ...result.operation,\n path: clientOp.path,\n },\n };\n }\n\n return result;\n }\n\n // Default: no transformation needed\n return { type: \"transformed\", operation: clientOp };\n },\n };\n}\n\n/** Creates a new StructPrimitive with the given fields */\nexport const Struct = <TFields extends Record<string, AnyPrimitive>>(\n fields: TFields\n): StructPrimitive<TFields, false, false> =>\n new StructPrimitive({ required: false, defaultValue: undefined, fields, validators: [] });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Struct.mjs","names":["OperationDefinition.make","snapshot: Record<string, unknown>","Operation.fromDefinition","newState: InferStructState<TFields>","initialState: Record<string, unknown>","OperationPath.pathsOverlap","partialFields: Record<string, AnyPrimitive>","nextSchema: Record<string, unknown>","nextFields: Record<string, AnyPrimitive>","nextVariants: Record<string, AnyPrimitive>"],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":["import { Schema } from \"effect\";\nimport * as OperationDefinition from \"../OperationDefinition\";\nimport * as Operation from \"../Operation\";\nimport * as OperationPath from \"../OperationPath\";\nimport * as ProxyEnvironment from \"../ProxyEnvironment\";\nimport * as Transform from \"../Transform\";\nimport type { Primitive, PrimitiveInternal, MaybeUndefined, AnyPrimitive, Validator, InferState, InferProxy, InferSnapshot, NeedsValue, InferUpdateInput, InferSetInput } from \"../Primitive\";\nimport { ValidationError } from \"../Primitive\";\nimport { runValidators, applyDefaults, primitiveAllowsNullValue } from \"./shared\";\n\n// =============================================================================\n// Struct Set Input Types\n// =============================================================================\n\n/**\n * Determines if a field is required for set() operations.\n * A field is required if: TRequired is true AND THasDefault is false\n */\ntype IsRequiredForSet<T> = T extends Primitive<any, any, true, false> ? true : false;\n\n/**\n * Extract keys of fields that are required for set() (required without default).\n */\ntype RequiredSetKeys<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: IsRequiredForSet<TFields[K]> extends true ? K : never;\n}[keyof TFields];\n\n/**\n * Extract keys of fields that are optional for set() (has default OR not required).\n */\ntype OptionalSetKeys<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: IsRequiredForSet<TFields[K]> extends true ? never : K;\n}[keyof TFields];\n\n/**\n * Compute the input type for set() operations on a struct.\n * Required fields (required without default) must be provided.\n * Optional fields (has default or not required) can be omitted.\n * Uses each field's TSetInput type to handle nested structs correctly.\n */\nexport type StructSetInput<TFields extends Record<string, AnyPrimitive>> = \n { readonly [K in RequiredSetKeys<TFields>]: InferSetInput<TFields[K]> } &\n { readonly [K in OptionalSetKeys<TFields>]?: InferSetInput<TFields[K]> };\n\n/**\n * Input type for set() - respects required/default status of the struct.\n * If the struct is required without a default, the value must be provided.\n * The value itself uses StructSetInput which handles field-level required/default logic.\n */\ntype InferStructSetInput<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean, THasDefault extends boolean> = \n NeedsValue<StructSetInput<TFields>, TRequired, THasDefault>;\n\n/**\n * Input type for update() - always partial since update only modifies specified fields.\n * For nested structs, allows recursive partial updates.\n */\ntype InferStructUpdateInput<TFields extends Record<string, AnyPrimitive>> = StructUpdateValue<TFields>;\n\n\n/**\n * Maps a schema definition to its state type.\n * { name: StringPrimitive, age: NumberPrimitive } -> { name: string, age: number }\n */\nexport type InferStructState<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]: InferState<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to its snapshot type.\n * Each field's snapshot type is inferred from the field primitive.\n */\nexport type InferStructSnapshot<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]: InferSnapshot<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to a partial update type.\n * Uses each field's TUpdateInput type, which handles nested updates recursively.\n */\nexport type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = {\n readonly [K in keyof TFields]?: InferUpdateInput<TFields[K]>;\n};\n\n/**\n * Transforms a primitive type to make it optional (TRequired = false).\n * Preserves the primitive structure while changing the required flag.\n */\nexport type MakeOptional<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, infer H, infer SI, infer UI>\n ? Primitive<S, P, false, H, SI, UI>\n : T;\n\n/**\n * Transforms a primitive type to make it optional and strip its default (TRequired = false, THasDefault = false).\n */\nexport type MakeOptionalNoDefault<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, any, infer SI, infer UI>\n ? Primitive<S, P, false, false, SI, UI>\n : T;\n\n/**\n * Maps each field in a struct to its optional version.\n * All fields become optional (TRequired = false).\n */\nexport type PartialFields<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: MakeOptional<TFields[K]>;\n};\n\n/**\n * Maps each field in a struct to its optional version with defaults stripped.\n * All fields become optional (TRequired = false) and lose their defaults (THasDefault = false).\n */\nexport type PartialFieldsNoDefault<TFields extends Record<string, AnyPrimitive>> = {\n [K in keyof TFields]: MakeOptionalNoDefault<TFields[K]>;\n};\n\n/**\n * Maps a schema definition to its proxy type.\n * Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.\n */\nexport type StructProxy<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean = false, THasDefault extends boolean = false> = {\n readonly [K in keyof TFields]: InferProxy<TFields[K]>;\n} & {\n /** Gets the entire struct value */\n get(): MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault>;\n /** Sets the entire struct value (only fields that are required without defaults must be provided) */\n set(value: InferStructSetInput<TFields, TRequired, THasDefault>): void;\n /** Updates only the specified fields (partial update, handles nested structs recursively) */\n update(value: InferStructUpdateInput<TFields>): void;\n /** Returns a readonly snapshot of the struct for rendering */\n toSnapshot(): MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault>;\n};\n\ninterface StructPrimitiveSchema<TFields extends Record<string, AnyPrimitive>> {\n readonly required: boolean;\n readonly defaultValue: InferStructState<TFields> | undefined;\n readonly fields: TFields;\n readonly validators: readonly Validator<InferStructState<TFields>>[];\n}\n\nexport class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TRequired extends boolean = false, THasDefault extends boolean = false>\n implements Primitive<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>, TRequired, THasDefault, InferStructSetInput<TFields, TRequired, THasDefault>, InferStructUpdateInput<TFields>>\n{\n readonly _tag = \"StructPrimitive\" as const;\n readonly _State!: InferStructState<TFields>;\n readonly _Proxy!: StructProxy<TFields, TRequired, THasDefault>;\n readonly _TRequired!: TRequired;\n readonly _THasDefault!: THasDefault;\n readonly TSetInput!: InferStructSetInput<TFields, TRequired, THasDefault>;\n readonly TUpdateInput!: InferStructUpdateInput<TFields>;\n\n private readonly _schema: StructPrimitiveSchema<TFields>;\n\n private readonly _opDefinitions = {\n set: OperationDefinition.make({\n kind: \"struct.set\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n unset: OperationDefinition.make({\n kind: \"struct.unset\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n };\n\n constructor(schema: StructPrimitiveSchema<TFields>) {\n this._schema = schema;\n }\n\n /** Mark this struct as required */\n required(): StructPrimitive<TFields, true, THasDefault> {\n return new StructPrimitive({\n ...this._schema,\n required: true,\n });\n }\n\n /** Set a default value for this struct */\n default(defaultValue: StructSetInput<TFields>): StructPrimitive<TFields, TRequired, true> {\n // Apply defaults to the provided value\n const merged = applyDefaults(this as AnyPrimitive, defaultValue as Partial<InferStructState<TFields>>) as InferStructState<TFields>;\n return new StructPrimitive({\n ...this._schema,\n defaultValue: merged,\n });\n }\n\n /** Get the fields schema */\n get fields(): TFields {\n return this._schema.fields;\n }\n\n /** Add a custom validation rule (useful for cross-field validation) */\n refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault> {\n return new StructPrimitive({\n ...this._schema,\n validators: [...this._schema.validators, { validate: fn, message }],\n });\n }\n\n /** Extend this struct with additional fields */\n extend<TNewFields extends Record<string, AnyPrimitive>>(\n newFields: TNewFields\n ): StructPrimitive<TFields & TNewFields, TRequired, THasDefault> {\n return new StructPrimitive<TFields & TNewFields, TRequired, THasDefault>({\n required: this._schema.required,\n defaultValue: undefined,\n fields: { ...this._schema.fields, ...newFields } as TFields & TNewFields,\n validators: [],\n });\n }\n\n /** Make all properties of this struct optional (TRequired = false for all fields), optionally stripping defaults */\n partial(options: { stripDefaults: true }): StructPrimitive<PartialFieldsNoDefault<TFields>, TRequired, THasDefault>;\n partial(options?: { stripDefaults?: boolean }): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>;\n partial(options?: { stripDefaults?: boolean }): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault> | StructPrimitive<PartialFieldsNoDefault<TFields>, TRequired, THasDefault> {\n const stripDefaults = options?.stripDefaults;\n const partialFields: Record<string, AnyPrimitive> = {};\n for (const key in this._schema.fields) {\n const field = this._schema.fields[key]!;\n partialFields[key] = this._makeFieldOptional(field, stripDefaults);\n }\n if (stripDefaults) {\n return new StructPrimitive<PartialFieldsNoDefault<TFields>, TRequired, THasDefault>({\n required: this._schema.required,\n defaultValue: undefined,\n fields: partialFields as PartialFieldsNoDefault<TFields>,\n validators: [],\n });\n }\n return new StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>({\n required: this._schema.required,\n defaultValue: undefined,\n fields: partialFields as PartialFields<TFields>,\n validators: [],\n });\n }\n\n private _makeFieldOptional(field: AnyPrimitive, stripDefaults?: boolean): AnyPrimitive {\n const maybeStripped = stripDefaults ? this._stripDefaultsRecursively(field) : field;\n\n // Create a new field with required: false, preserving its shape.\n const fieldWithSchema = maybeStripped as { _schema?: Record<string, unknown> };\n if (fieldWithSchema._schema && typeof fieldWithSchema._schema === \"object\") {\n const Constructor = maybeStripped.constructor as new (schema: unknown) => AnyPrimitive;\n return new Constructor({\n ...fieldWithSchema._schema,\n required: false,\n });\n }\n return maybeStripped;\n }\n\n /**\n * Recursively strips defaults from a primitive and nested child primitives.\n * This is used by partial({ stripDefaults: true }) so omitted fields resolve to undefined.\n */\n private _stripDefaultsRecursively(field: AnyPrimitive): AnyPrimitive {\n const fieldWithSchema = field as { _schema?: Record<string, unknown> };\n if (!fieldWithSchema._schema || typeof fieldWithSchema._schema !== \"object\") {\n return field;\n }\n\n const nextSchema: Record<string, unknown> = { ...fieldWithSchema._schema };\n\n // Struct fields\n if (\n nextSchema[\"fields\"] &&\n typeof nextSchema[\"fields\"] === \"object\" &&\n !Array.isArray(nextSchema[\"fields\"])\n ) {\n const nextFields: Record<string, AnyPrimitive> = {};\n for (const key in nextSchema[\"fields\"] as Record<string, AnyPrimitive>) {\n const nestedField = (nextSchema[\"fields\"] as Record<string, AnyPrimitive>)[key]!;\n nextFields[key] = this._stripDefaultsRecursively(nestedField);\n }\n nextSchema[\"fields\"] = nextFields;\n }\n\n // Array element primitive\n if (nextSchema[\"element\"] && typeof nextSchema[\"element\"] === \"object\") {\n nextSchema[\"element\"] = this._stripDefaultsRecursively(nextSchema[\"element\"] as AnyPrimitive);\n }\n\n // Either variants (array) / Union variants (record)\n if (Array.isArray(nextSchema[\"variants\"])) {\n nextSchema[\"variants\"] = (nextSchema[\"variants\"] as readonly AnyPrimitive[]).map((variant) =>\n this._stripDefaultsRecursively(variant)\n );\n } else if (nextSchema[\"variants\"] && typeof nextSchema[\"variants\"] === \"object\") {\n const nextVariants: Record<string, AnyPrimitive> = {};\n for (const key in nextSchema[\"variants\"] as Record<string, AnyPrimitive>) {\n const nestedVariant = (nextSchema[\"variants\"] as Record<string, AnyPrimitive>)[key]!;\n nextVariants[key] = this._stripDefaultsRecursively(nestedVariant);\n }\n nextSchema[\"variants\"] = nextVariants;\n }\n\n // Tree root node primitive\n if (nextSchema[\"root\"] && typeof nextSchema[\"root\"] === \"object\") {\n nextSchema[\"root\"] = this._stripDefaultsRecursively(nextSchema[\"root\"] as AnyPrimitive);\n }\n\n // Clear known default carriers across primitives.\n if (\"defaultValue\" in nextSchema) {\n nextSchema[\"defaultValue\"] = undefined;\n }\n if (\"defaultInput\" in nextSchema) {\n nextSchema[\"defaultInput\"] = undefined;\n }\n\n const Constructor = field.constructor as new (schema: unknown) => AnyPrimitive;\n return new Constructor(nextSchema);\n }\n\n private _isRequiredWithoutDefault(field: AnyPrimitive): boolean {\n const fieldDefault = field._internal.getInitialState();\n return (\n (field as { _schema?: { required?: boolean } })._schema?.required === true &&\n fieldDefault === undefined\n );\n }\n\n readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>> = {\n createProxy: (env: ProxyEnvironment.ProxyEnvironment, operationPath: OperationPath.OperationPath): StructProxy<TFields, TRequired, THasDefault> => {\n const fields = this._schema.fields;\n const defaultValue = this._schema.defaultValue;\n\n // Helper to build a snapshot by calling toSnapshot on each field\n const buildSnapshot = (): InferStructSnapshot<TFields> | undefined => {\n const state = env.getState(operationPath);\n \n // Build snapshot from field proxies (they handle their own defaults)\n const snapshot: Record<string, unknown> = {};\n let hasAnyDefinedField = false;\n \n for (const key in fields) {\n const fieldPrimitive = fields[key]!;\n const fieldPath = operationPath.append(key);\n const fieldProxy = fieldPrimitive._internal.createProxy(env, fieldPath);\n const fieldSnapshot = (fieldProxy as { toSnapshot(): unknown }).toSnapshot();\n snapshot[key] = fieldSnapshot;\n if (fieldSnapshot !== undefined) {\n hasAnyDefinedField = true;\n }\n }\n \n // Return undefined only if there's no state, no struct default, and no field snapshots\n if (state === undefined && defaultValue === undefined && !hasAnyDefinedField) {\n return undefined;\n }\n \n return snapshot as InferStructSnapshot<TFields>;\n };\n\n // Create the base object with get/set/update/toSnapshot methods\n const base = {\n get: (): MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferStructState<TFields> | undefined;\n return (state ?? defaultValue) as MaybeUndefined<InferStructState<TFields>, TRequired, THasDefault>;\n },\n set: (value: InferStructSetInput<TFields, TRequired, THasDefault>) => {\n // Apply defaults for missing fields\n const merged = applyDefaults(this as AnyPrimitive, value as Partial<InferStructState<TFields>>) as InferStructState<TFields>;\n env.addOperation(\n Operation.fromDefinition(operationPath, this._opDefinitions.set, merged)\n );\n },\n update: (value: InferStructUpdateInput<TFields>) => {\n for (const key in value) {\n if (Object.prototype.hasOwnProperty.call(value, key)) {\n const fieldValue = value[key as keyof TFields];\n const fieldPrimitive = fields[key as keyof TFields];\n if (!fieldPrimitive) continue; // Skip unknown fields\n\n const fieldPath = operationPath.append(key);\n\n const shouldUnset =\n fieldValue === undefined ||\n (fieldValue === null && !primitiveAllowsNullValue(fieldPrimitive));\n if (shouldUnset) {\n if (this._isRequiredWithoutDefault(fieldPrimitive)) {\n throw new ValidationError(`Field \"${key}\" is required and cannot be null or undefined`);\n }\n env.addOperation(\n Operation.fromDefinition(fieldPath, this._opDefinitions.unset, null)\n );\n continue;\n }\n\n const fieldProxy = fieldPrimitive._internal.createProxy(env, fieldPath);\n\n // Check if this is a nested struct and value is a plain object (partial update)\n if (\n fieldPrimitive._tag === \"StructPrimitive\" &&\n typeof fieldValue === \"object\" &&\n fieldValue !== null &&\n !Array.isArray(fieldValue)\n ) {\n // Recursively update nested struct\n (fieldProxy as { update: (v: unknown) => void }).update(fieldValue);\n } else {\n // Set the field value directly\n (fieldProxy as { set: (v: unknown) => void }).set(fieldValue);\n }\n }\n }\n },\n toSnapshot: (): MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault> => {\n const snapshot = buildSnapshot();\n return snapshot as MaybeUndefined<InferStructSnapshot<TFields>, TRequired, THasDefault>;\n },\n };\n\n // Use a JavaScript Proxy to intercept field access\n return new globalThis.Proxy(base as StructProxy<TFields, TRequired, THasDefault>, {\n get: (target, prop, _receiver) => {\n // Return base methods (get, set, update, toSnapshot)\n if (prop === \"get\") {\n return target.get;\n }\n if (prop === \"set\") {\n return target.set;\n }\n if (prop === \"update\") {\n return target.update;\n }\n if (prop === \"toSnapshot\") {\n return target.toSnapshot;\n }\n\n // Handle symbol properties (like Symbol.toStringTag)\n if (typeof prop === \"symbol\") {\n return undefined;\n }\n\n // Check if prop is a field in the schema\n if (prop in fields) {\n const fieldPrimitive = fields[prop as keyof TFields]!;\n const fieldPath = operationPath.append(prop as string);\n return fieldPrimitive._internal.createProxy(env, fieldPath);\n }\n\n return undefined;\n },\n has: (_target, prop) => {\n if (prop === \"get\" || prop === \"set\" || prop === \"update\" || prop === \"toSnapshot\") return true;\n if (typeof prop === \"string\" && prop in fields) return true;\n return false;\n },\n });\n },\n\n applyOperation: (\n state: InferStructState<TFields> | undefined,\n operation: Operation.Operation<any, any, any>\n ): InferStructState<TFields> => {\n const path = operation.path;\n const tokens = path.toTokens().filter((t: string) => t !== \"\");\n\n let newState: InferStructState<TFields>;\n\n // If path is empty or root, this is a struct.set operation\n if (tokens.length === 0) {\n if (operation.kind !== \"struct.set\") {\n throw new ValidationError(`StructPrimitive root cannot apply operation of kind: ${operation.kind}`);\n }\n\n const payload = operation.payload;\n if (typeof payload !== \"object\" || payload === null) {\n throw new ValidationError(`StructPrimitive.set requires an object payload`);\n }\n\n newState = payload as InferStructState<TFields>;\n } else {\n // Otherwise, delegate to the appropriate field primitive\n const fieldName = tokens[0] as keyof TFields;\n if (!(fieldName in this._schema.fields)) {\n throw new ValidationError(`Unknown field: ${globalThis.String(fieldName)}`);\n }\n\n const fieldPrimitive = this._schema.fields[fieldName]!;\n // Get the current field state\n const currentState = state ?? ({} as InferStructState<TFields>);\n if (operation.kind === \"struct.unset\" && tokens.length === 1) {\n if (this._isRequiredWithoutDefault(fieldPrimitive)) {\n throw new ValidationError(`Field \"${globalThis.String(fieldName)}\" is required and cannot be removed`);\n }\n const mutableState = { ...currentState } as Record<string, unknown>;\n delete mutableState[globalThis.String(fieldName)];\n newState = mutableState as InferStructState<TFields>;\n } else {\n const remainingPath = path.shift();\n const fieldOperation = {\n ...operation,\n path: remainingPath,\n };\n const currentFieldState = currentState[fieldName] as InferState<typeof fieldPrimitive> | undefined;\n\n // Apply the operation to the field\n const newFieldState = fieldPrimitive._internal.applyOperation(currentFieldState, fieldOperation);\n\n // Build updated state\n newState = {\n ...currentState,\n [fieldName]: newFieldState,\n };\n }\n }\n\n // Run validators on the new state\n runValidators(newState, this._schema.validators);\n\n return newState;\n },\n\n getInitialState: (): InferStructState<TFields> | undefined => {\n if (this._schema.defaultValue !== undefined) {\n return this._schema.defaultValue;\n }\n\n // Build initial state from field defaults\n const fields = this._schema.fields;\n const initialState: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const key in fields) {\n const fieldDefault = fields[key]!._internal.getInitialState();\n if (fieldDefault !== undefined) {\n initialState[key] = fieldDefault;\n hasAnyDefault = true;\n }\n }\n\n return hasAnyDefault ? (initialState as InferStructState<TFields>) : undefined;\n },\n\n transformOperation: (\n clientOp: Operation.Operation<any, any, any>,\n serverOp: Operation.Operation<any, any, any>\n ): Transform.TransformResult => {\n const clientPath = clientOp.path;\n const serverPath = serverOp.path;\n\n // If paths don't overlap at all, no transformation needed\n if (!OperationPath.pathsOverlap(clientPath, serverPath)) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientTokens = clientPath.toTokens().filter((t: string) => t !== \"\");\n const serverTokens = serverPath.toTokens().filter((t: string) => t !== \"\");\n\n // If both are at root level (struct.set operations)\n if (clientTokens.length === 0 && serverTokens.length === 0) {\n // Client wins (last-write-wins)\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If server set entire struct and client is updating a field\n if (serverTokens.length === 0 && serverOp.kind === \"struct.set\") {\n // Client's field operation proceeds - optimistic update\n // Server will validate/reject if needed\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If client set entire struct and server is updating a field\n if (clientTokens.length === 0 && clientOp.kind === \"struct.set\") {\n // Client's struct.set supersedes server's field update\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Both operations target fields\n if (clientTokens.length > 0 && serverTokens.length > 0) {\n const clientField = clientTokens[0] as keyof TFields;\n const serverField = serverTokens[0] as keyof TFields;\n\n // Different fields - no conflict\n if (clientField !== serverField) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Same field - delegate to field primitive\n const fieldPrimitive = this._schema.fields[clientField];\n if (!fieldPrimitive) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientOpForField = {\n ...clientOp,\n path: clientOp.path.shift(),\n };\n const serverOpForField = {\n ...serverOp,\n path: serverOp.path.shift(),\n };\n\n const result = fieldPrimitive._internal.transformOperation(clientOpForField, serverOpForField);\n\n if (result.type === \"transformed\") {\n // Restore the original path\n return {\n type: \"transformed\",\n operation: {\n ...result.operation,\n path: clientOp.path,\n },\n };\n }\n\n return result;\n }\n\n // Default: no transformation needed\n return { type: \"transformed\", operation: clientOp };\n },\n };\n}\n\n/** Creates a new StructPrimitive with the given fields */\nexport const Struct = <TFields extends Record<string, AnyPrimitive>>(\n fields: TFields\n): StructPrimitive<TFields, false, false> =>\n new StructPrimitive({ required: false, defaultValue: undefined, fields, validators: [] });\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Union.mjs","names":["OperationDefinition.make","Operation.fromDefinition","OperationPath.pathsOverlap"],"sources":["../../src/primitives/Union.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\nimport * as OperationDefinition from \"../OperationDefinition\";\nimport * as Operation from \"../Operation\";\nimport * as OperationPath from \"../OperationPath\";\nimport * as ProxyEnvironment from \"../ProxyEnvironment\";\nimport * as Transform from \"../Transform\";\nimport type { Primitive, PrimitiveInternal, MaybeUndefined, AnyPrimitive, InferState, InferProxy, InferSnapshot, InferSetInput } from \"../Primitive\";\nimport { ValidationError } from \"../Primitive\";\nimport { LiteralPrimitive } from \"./Literal\";\nimport { StructPrimitive, InferStructState } from \"./Struct\";\nimport { runValidators, applyDefaults } from \"./shared\";\n\n\n/**\n * Type constraint for union variants - must be struct primitives\n */\nexport type UnionVariants = Record<string, StructPrimitive<any, any, any>>;\n\n/**\n * Infer the union state type from variants\n */\nexport type InferUnionState<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferState<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Infer the union snapshot type from variants\n */\nexport type InferUnionSnapshot<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferSnapshot<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Compute the input type for union.set() operations.\n * Uses each variant's TSetInput type.\n */\nexport type UnionSetInput<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferSetInput<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Proxy for accessing union variants\n */\nexport interface UnionProxy<TVariants extends UnionVariants, _TDiscriminator extends string, TRequired extends boolean = false, THasDefault extends boolean = false> {\n /** Gets the current union value */\n get(): MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault>;\n \n /** Sets the entire union value (applies defaults for variant fields) */\n set(value: UnionSetInput<TVariants>): void;\n \n /** Access a specific variant's proxy (assumes the variant is active) */\n as<K extends keyof TVariants>(variant: K): InferProxy<TVariants[K]>;\n \n /** Pattern match on the variant type */\n match<R>(handlers: {\n [K in keyof TVariants]: (proxy: InferProxy<TVariants[K]>) => R;\n }): R | undefined;\n \n /** Returns a readonly snapshot of the union for rendering */\n toSnapshot(): MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n}\n\ninterface UnionPrimitiveSchema<TVariants extends UnionVariants, TDiscriminator extends string> {\n readonly required: boolean;\n readonly defaultValue: InferUnionState<TVariants> | undefined;\n readonly discriminator: TDiscriminator;\n readonly variants: TVariants;\n}\n\nexport class UnionPrimitive<TVariants extends UnionVariants, TDiscriminator extends string = \"type\", TRequired extends boolean = false, THasDefault extends boolean = false>\n implements Primitive<InferUnionState<TVariants>, UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>, TRequired, THasDefault, UnionSetInput<TVariants>, UnionSetInput<TVariants>>\n{\n readonly _tag = \"UnionPrimitive\" as const;\n readonly _State!: InferUnionState<TVariants>;\n readonly _Proxy!: UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>;\n readonly _TRequired!: TRequired;\n readonly _THasDefault!: THasDefault;\n readonly TSetInput!: UnionSetInput<TVariants>;\n readonly TUpdateInput!: UnionSetInput<TVariants>;\n\n private readonly _schema: UnionPrimitiveSchema<TVariants, TDiscriminator>;\n\n private readonly _opDefinitions = {\n set: OperationDefinition.make({\n kind: \"union.set\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n };\n\n constructor(schema: UnionPrimitiveSchema<TVariants, TDiscriminator>) {\n this._schema = schema;\n }\n\n /** Mark this union as required */\n required(): UnionPrimitive<TVariants, TDiscriminator, true, THasDefault> {\n return new UnionPrimitive({\n ...this._schema,\n required: true,\n });\n }\n\n /** Set a default value for this union */\n default(defaultValue: UnionSetInput<TVariants>): UnionPrimitive<TVariants, TDiscriminator, true, true> {\n // Apply defaults to the variant\n const merged = this._applyVariantDefaults(defaultValue as Partial<InferUnionState<TVariants>>);\n return new UnionPrimitive({\n ...this._schema,\n defaultValue: merged,\n });\n }\n\n /** Get the discriminator field name */\n get discriminator(): TDiscriminator {\n return this._schema.discriminator;\n }\n\n /** Get the variants */\n get variants(): TVariants {\n return this._schema.variants;\n }\n\n /** Find the variant key from a state value */\n private _findVariantKey(state: InferUnionState<TVariants>): keyof TVariants | undefined {\n if (typeof state !== \"object\" || state === null) {\n return undefined;\n }\n const discriminatorValue = (state as Record<string, unknown>)[this._schema.discriminator];\n \n // Find the variant that matches this discriminator value\n for (const key in this._schema.variants) {\n const variant = this._schema.variants[key]!;\n const discriminatorField = variant.fields[this._schema.discriminator];\n if (discriminatorField && discriminatorField._tag === \"LiteralPrimitive\") {\n const literalPrimitive = discriminatorField as LiteralPrimitive<any, any, any>;\n if (literalPrimitive.literal === discriminatorValue) {\n return key;\n }\n }\n }\n return undefined;\n }\n\n /** Apply defaults to a variant value based on the discriminator */\n private _applyVariantDefaults(value: Partial<InferUnionState<TVariants>>): InferUnionState<TVariants> {\n const variantKey = this._findVariantKey(value as InferUnionState<TVariants>);\n if (!variantKey) {\n return value as InferUnionState<TVariants>;\n }\n \n const variantPrimitive = this._schema.variants[variantKey]!;\n return applyDefaults(variantPrimitive as AnyPrimitive, value) as InferUnionState<TVariants>;\n }\n\n readonly _internal: PrimitiveInternal<InferUnionState<TVariants>, UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>> = {\n createProxy: (\n env: ProxyEnvironment.ProxyEnvironment,\n operationPath: OperationPath.OperationPath\n ): UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault> => {\n const variants = this._schema.variants;\n const defaultValue = this._schema.defaultValue;\n\n return {\n get: (): MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n return (state ?? defaultValue) as MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault>;\n },\n set: (value: UnionSetInput<TVariants>) => {\n // Apply defaults for the variant\n const merged = this._applyVariantDefaults(value as Partial<InferUnionState<TVariants>>);\n env.addOperation(\n Operation.fromDefinition(operationPath, this._opDefinitions.set, merged)\n );\n },\n as: <K extends keyof TVariants>(variant: K): InferProxy<TVariants[K]> => {\n const variantPrimitive = variants[variant];\n if (!variantPrimitive) {\n throw new ValidationError(`Unknown variant: ${globalThis.String(variant)}`);\n }\n return variantPrimitive._internal.createProxy(env, operationPath) as InferProxy<TVariants[K]>;\n },\n match: <R,>(handlers: { [K in keyof TVariants]: (proxy: InferProxy<TVariants[K]>) => R }): R | undefined => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n if (!state) return undefined;\n \n const variantKey = this._findVariantKey(state);\n if (!variantKey) return undefined;\n \n const handler = handlers[variantKey];\n if (!handler) return undefined;\n \n const variantProxy = variants[variantKey]!._internal.createProxy(env, operationPath) as InferProxy<TVariants[typeof variantKey]>;\n return handler(variantProxy);\n },\n toSnapshot: (): MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n const effectiveState = state ?? defaultValue;\n if (!effectiveState) {\n return undefined as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n }\n \n const variantKey = this._findVariantKey(effectiveState);\n if (!variantKey) {\n return undefined as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n }\n \n const variantPrimitive = variants[variantKey]!;\n const variantProxy = variantPrimitive._internal.createProxy(env, operationPath);\n return (variantProxy as unknown as { toSnapshot(): InferUnionSnapshot<TVariants> }).toSnapshot() as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n },\n };\n },\n\n applyOperation: (\n state: InferUnionState<TVariants> | undefined,\n operation: Operation.Operation<any, any, any>\n ): InferUnionState<TVariants> => {\n const path = operation.path;\n const tokens = path.toTokens().filter((t: string) => t !== \"\");\n\n // If path is empty, this is a union-level operation\n if (tokens.length === 0) {\n if (operation.kind !== \"union.set\") {\n throw new ValidationError(`UnionPrimitive root cannot apply operation of kind: ${operation.kind}`);\n }\n\n const payload = operation.payload;\n if (typeof payload !== \"object\" || payload === null) {\n throw new ValidationError(`UnionPrimitive.set requires an object payload`);\n }\n\n // Validate that the discriminator field exists and matches a variant\n const discriminatorValue = (payload as Record<string, unknown>)[this._schema.discriminator];\n if (discriminatorValue === undefined) {\n throw new ValidationError(`UnionPrimitive.set requires a \"${this._schema.discriminator}\" discriminator field`);\n }\n\n return payload as InferUnionState<TVariants>;\n }\n\n // Otherwise, delegate to the active variant\n // We need to determine which variant is active based on current state\n if (state === undefined) {\n throw new ValidationError(`Cannot apply nested operation to undefined union state`);\n }\n\n const variantKey = this._findVariantKey(state);\n if (variantKey === undefined) {\n throw new ValidationError(`Cannot determine active variant from state`);\n }\n\n const variantPrimitive = this._schema.variants[variantKey]!;\n const newState = variantPrimitive._internal.applyOperation(\n state as InferState<typeof variantPrimitive>,\n operation\n );\n\n return newState as InferUnionState<TVariants>;\n },\n\n getInitialState: (): InferUnionState<TVariants> | undefined => {\n return this._schema.defaultValue;\n },\n\n transformOperation: (\n clientOp: Operation.Operation<any, any, any>,\n serverOp: Operation.Operation<any, any, any>\n ): Transform.TransformResult => {\n const clientPath = clientOp.path;\n const serverPath = serverOp.path;\n\n // If paths don't overlap at all, no transformation needed\n if (!OperationPath.pathsOverlap(clientPath, serverPath)) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientTokens = clientPath.toTokens().filter((t: string) => t !== \"\");\n const serverTokens = serverPath.toTokens().filter((t: string) => t !== \"\");\n\n // If both are at root level (union.set operations)\n if (clientTokens.length === 0 && serverTokens.length === 0) {\n // Client wins (last-write-wins)\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If server set entire union and client is updating a field\n if (serverTokens.length === 0 && serverOp.kind === \"union.set\") {\n // Client's field operation proceeds - optimistic update\n // Server will validate/reject if needed\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If client set entire union and server is updating a field\n if (clientTokens.length === 0 && clientOp.kind === \"union.set\") {\n // Client's union.set supersedes server's field update\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Both operations target fields within the union\n // Since union variants are struct primitives, delegate to the first variant\n // that matches (they all should have the same field structure for the overlapping field)\n if (clientTokens.length > 0 && serverTokens.length > 0) {\n const clientField = clientTokens[0];\n const serverField = serverTokens[0];\n\n // Different fields - no conflict\n if (clientField !== serverField) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Same field - delegate to a variant (use first variant as they share structure)\n const variantKeys = Object.keys(this._schema.variants);\n if (variantKeys.length === 0) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const firstVariant = this._schema.variants[variantKeys[0]!]!;\n const result = firstVariant._internal.transformOperation(clientOp, serverOp);\n\n return result;\n }\n\n // Default: no transformation needed\n return { type: \"transformed\", operation: clientOp };\n },\n };\n}\n\n/** Options for creating a Union primitive */\nexport interface UnionOptions<TVariants extends UnionVariants, TDiscriminator extends string> {\n /** The field name used to discriminate between variants (defaults to \"type\") */\n readonly discriminator?: TDiscriminator;\n /** The variant struct primitives */\n readonly variants: TVariants;\n}\n\n/** Creates a new UnionPrimitive with the given variants */\nexport function Union<TVariants extends UnionVariants>(\n options: UnionOptions<TVariants, \"type\">\n): UnionPrimitive<TVariants, \"type\", false, false>;\nexport function Union<TVariants extends UnionVariants, TDiscriminator extends string>(\n options: UnionOptions<TVariants, TDiscriminator>\n): UnionPrimitive<TVariants, TDiscriminator, false, false>;\nexport function Union<TVariants extends UnionVariants, TDiscriminator extends string = \"type\">(\n options: UnionOptions<TVariants, TDiscriminator>\n): UnionPrimitive<TVariants, TDiscriminator, false, false> {\n const discriminator = (options.discriminator ?? \"type\") as TDiscriminator;\n return new UnionPrimitive({\n required: false,\n defaultValue: undefined,\n discriminator,\n variants: options.variants,\n });\n}\n\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Union.mjs","names":["OperationDefinition.make","Operation.fromDefinition","OperationPath.pathsOverlap"],"sources":["../../src/primitives/Union.ts"],"sourcesContent":["import { Effect, Schema } from \"effect\";\nimport * as OperationDefinition from \"../OperationDefinition\";\nimport * as Operation from \"../Operation\";\nimport * as OperationPath from \"../OperationPath\";\nimport * as ProxyEnvironment from \"../ProxyEnvironment\";\nimport * as Transform from \"../Transform\";\nimport type { Primitive, PrimitiveInternal, MaybeUndefined, AnyPrimitive, InferState, InferProxy, InferSnapshot, InferSetInput } from \"../Primitive\";\nimport { ValidationError } from \"../Primitive\";\nimport { LiteralPrimitive } from \"./Literal\";\nimport { StructPrimitive, InferStructState } from \"./Struct\";\nimport { runValidators, applyDefaults } from \"./shared\";\n\n\n/**\n * Type constraint for union variants - must be struct primitives\n */\nexport type UnionVariants = Record<string, StructPrimitive<any, any, any>>;\n\n/**\n * Infer the union state type from variants\n */\nexport type InferUnionState<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferState<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Infer the union snapshot type from variants\n */\nexport type InferUnionSnapshot<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferSnapshot<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Compute the input type for union.set() operations.\n * Uses each variant's TSetInput type.\n */\nexport type UnionSetInput<TVariants extends UnionVariants> = {\n [K in keyof TVariants]: InferSetInput<TVariants[K]>;\n}[keyof TVariants];\n\n/**\n * Proxy for accessing union variants\n */\nexport interface UnionProxy<TVariants extends UnionVariants, _TDiscriminator extends string, TRequired extends boolean = false, THasDefault extends boolean = false> {\n /** Gets the current union value */\n get(): MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault>;\n \n /** Sets the entire union value (applies defaults for variant fields) */\n set(value: UnionSetInput<TVariants>): void;\n \n /** Access a specific variant's proxy (assumes the variant is active) */\n as<K extends keyof TVariants>(variant: K): InferProxy<TVariants[K]>;\n \n /** Pattern match on the variant type */\n match<R>(handlers: {\n [K in keyof TVariants]: (proxy: InferProxy<TVariants[K]>) => R;\n }): R | undefined;\n \n /** Returns a readonly snapshot of the union for rendering */\n toSnapshot(): MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n}\n\ninterface UnionPrimitiveSchema<TVariants extends UnionVariants, TDiscriminator extends string> {\n readonly required: boolean;\n readonly defaultValue: InferUnionState<TVariants> | undefined;\n readonly discriminator: TDiscriminator;\n readonly variants: TVariants;\n}\n\nexport class UnionPrimitive<TVariants extends UnionVariants, TDiscriminator extends string = \"type\", TRequired extends boolean = false, THasDefault extends boolean = false>\n implements Primitive<InferUnionState<TVariants>, UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>, TRequired, THasDefault, UnionSetInput<TVariants>, UnionSetInput<TVariants>>\n{\n readonly _tag = \"UnionPrimitive\" as const;\n readonly _State!: InferUnionState<TVariants>;\n readonly _Proxy!: UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>;\n readonly _TRequired!: TRequired;\n readonly _THasDefault!: THasDefault;\n readonly TSetInput!: UnionSetInput<TVariants>;\n readonly TUpdateInput!: UnionSetInput<TVariants>;\n\n private readonly _schema: UnionPrimitiveSchema<TVariants, TDiscriminator>;\n\n private readonly _opDefinitions = {\n set: OperationDefinition.make({\n kind: \"union.set\" as const,\n payload: Schema.Unknown,\n target: Schema.Unknown,\n apply: (payload) => payload,\n deduplicable: true,\n }),\n };\n\n constructor(schema: UnionPrimitiveSchema<TVariants, TDiscriminator>) {\n this._schema = schema;\n }\n\n /** Mark this union as required */\n required(): UnionPrimitive<TVariants, TDiscriminator, true, THasDefault> {\n return new UnionPrimitive({\n ...this._schema,\n required: true,\n });\n }\n\n /** Set a default value for this union */\n default(defaultValue: UnionSetInput<TVariants>): UnionPrimitive<TVariants, TDiscriminator, true, true> {\n // Apply defaults to the variant\n const merged = this._applyVariantDefaults(defaultValue as Partial<InferUnionState<TVariants>>);\n return new UnionPrimitive({\n ...this._schema,\n defaultValue: merged,\n });\n }\n\n /** Get the discriminator field name */\n get discriminator(): TDiscriminator {\n return this._schema.discriminator;\n }\n\n /** Get the variants */\n get variants(): TVariants {\n return this._schema.variants;\n }\n\n /** Find the variant key from a state value */\n private _findVariantKey(state: InferUnionState<TVariants>): keyof TVariants | undefined {\n if (typeof state !== \"object\" || state === null) {\n return undefined;\n }\n const discriminatorValue = (state as Record<string, unknown>)[this._schema.discriminator];\n \n // Find the variant that matches this discriminator value\n for (const key in this._schema.variants) {\n const variant = this._schema.variants[key]!;\n const discriminatorField = variant.fields[this._schema.discriminator];\n if (discriminatorField && discriminatorField._tag === \"LiteralPrimitive\") {\n const literalPrimitive = discriminatorField as LiteralPrimitive<any, any, any>;\n if (literalPrimitive.literal === discriminatorValue) {\n return key;\n }\n }\n }\n return undefined;\n }\n\n /** Apply defaults to a variant value based on the discriminator */\n private _applyVariantDefaults(value: Partial<InferUnionState<TVariants>>): InferUnionState<TVariants> {\n const variantKey = this._findVariantKey(value as InferUnionState<TVariants>);\n if (!variantKey) {\n return value as InferUnionState<TVariants>;\n }\n \n const variantPrimitive = this._schema.variants[variantKey]!;\n return applyDefaults(variantPrimitive as AnyPrimitive, value) as InferUnionState<TVariants>;\n }\n\n readonly _internal: PrimitiveInternal<InferUnionState<TVariants>, UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault>> = {\n createProxy: (\n env: ProxyEnvironment.ProxyEnvironment,\n operationPath: OperationPath.OperationPath\n ): UnionProxy<TVariants, TDiscriminator, TRequired, THasDefault> => {\n const variants = this._schema.variants;\n const defaultValue = this._schema.defaultValue;\n\n return {\n get: (): MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n return (state ?? defaultValue) as MaybeUndefined<InferUnionState<TVariants>, TRequired, THasDefault>;\n },\n set: (value: UnionSetInput<TVariants>) => {\n // Apply defaults for the variant\n const merged = this._applyVariantDefaults(value as Partial<InferUnionState<TVariants>>);\n env.addOperation(\n Operation.fromDefinition(operationPath, this._opDefinitions.set as any, merged)\n );\n },\n as: <K extends keyof TVariants>(variant: K): InferProxy<TVariants[K]> => {\n const variantPrimitive = variants[variant];\n if (!variantPrimitive) {\n throw new ValidationError(`Unknown variant: ${globalThis.String(variant)}`);\n }\n return variantPrimitive._internal.createProxy(env, operationPath) as InferProxy<TVariants[K]>;\n },\n match: <R,>(handlers: { [K in keyof TVariants]: (proxy: InferProxy<TVariants[K]>) => R }): R | undefined => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n if (!state) return undefined;\n \n const variantKey = this._findVariantKey(state);\n if (!variantKey) return undefined;\n \n const handler = handlers[variantKey];\n if (!handler) return undefined;\n \n const variantProxy = variants[variantKey]!._internal.createProxy(env, operationPath) as InferProxy<TVariants[typeof variantKey]>;\n return handler(variantProxy);\n },\n toSnapshot: (): MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault> => {\n const state = env.getState(operationPath) as InferUnionState<TVariants> | undefined;\n const effectiveState = state ?? defaultValue;\n if (!effectiveState) {\n return undefined as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n }\n \n const variantKey = this._findVariantKey(effectiveState);\n if (!variantKey) {\n return undefined as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n }\n \n const variantPrimitive = variants[variantKey]!;\n const variantProxy = variantPrimitive._internal.createProxy(env, operationPath);\n return (variantProxy as unknown as { toSnapshot(): InferUnionSnapshot<TVariants> }).toSnapshot() as MaybeUndefined<InferUnionSnapshot<TVariants>, TRequired, THasDefault>;\n },\n };\n },\n\n applyOperation: (\n state: InferUnionState<TVariants> | undefined,\n operation: Operation.Operation<any, any, any>\n ): InferUnionState<TVariants> => {\n const path = operation.path;\n const tokens = path.toTokens().filter((t: string) => t !== \"\");\n\n // If path is empty, this is a union-level operation\n if (tokens.length === 0) {\n if (operation.kind !== \"union.set\") {\n throw new ValidationError(`UnionPrimitive root cannot apply operation of kind: ${operation.kind}`);\n }\n\n const payload = operation.payload;\n if (typeof payload !== \"object\" || payload === null) {\n throw new ValidationError(`UnionPrimitive.set requires an object payload`);\n }\n\n // Validate that the discriminator field exists and matches a variant\n const discriminatorValue = (payload as Record<string, unknown>)[this._schema.discriminator];\n if (discriminatorValue === undefined) {\n throw new ValidationError(`UnionPrimitive.set requires a \"${this._schema.discriminator}\" discriminator field`);\n }\n\n return payload as InferUnionState<TVariants>;\n }\n\n // Otherwise, delegate to the active variant\n // We need to determine which variant is active based on current state\n if (state === undefined) {\n throw new ValidationError(`Cannot apply nested operation to undefined union state`);\n }\n\n const variantKey = this._findVariantKey(state);\n if (variantKey === undefined) {\n throw new ValidationError(`Cannot determine active variant from state`);\n }\n\n const variantPrimitive = this._schema.variants[variantKey]!;\n const newState = variantPrimitive._internal.applyOperation(\n state as InferState<typeof variantPrimitive>,\n operation\n );\n\n return newState as InferUnionState<TVariants>;\n },\n\n getInitialState: (): InferUnionState<TVariants> | undefined => {\n return this._schema.defaultValue;\n },\n\n transformOperation: (\n clientOp: Operation.Operation<any, any, any>,\n serverOp: Operation.Operation<any, any, any>\n ): Transform.TransformResult => {\n const clientPath = clientOp.path;\n const serverPath = serverOp.path;\n\n // If paths don't overlap at all, no transformation needed\n if (!OperationPath.pathsOverlap(clientPath, serverPath)) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const clientTokens = clientPath.toTokens().filter((t: string) => t !== \"\");\n const serverTokens = serverPath.toTokens().filter((t: string) => t !== \"\");\n\n // If both are at root level (union.set operations)\n if (clientTokens.length === 0 && serverTokens.length === 0) {\n // Client wins (last-write-wins)\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If server set entire union and client is updating a field\n if (serverTokens.length === 0 && serverOp.kind === \"union.set\") {\n // Client's field operation proceeds - optimistic update\n // Server will validate/reject if needed\n return { type: \"transformed\", operation: clientOp };\n }\n\n // If client set entire union and server is updating a field\n if (clientTokens.length === 0 && clientOp.kind === \"union.set\") {\n // Client's union.set supersedes server's field update\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Both operations target fields within the union\n // Since union variants are struct primitives, delegate to the first variant\n // that matches (they all should have the same field structure for the overlapping field)\n if (clientTokens.length > 0 && serverTokens.length > 0) {\n const clientField = clientTokens[0];\n const serverField = serverTokens[0];\n\n // Different fields - no conflict\n if (clientField !== serverField) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n // Same field - delegate to a variant (use first variant as they share structure)\n const variantKeys = Object.keys(this._schema.variants);\n if (variantKeys.length === 0) {\n return { type: \"transformed\", operation: clientOp };\n }\n\n const firstVariant = this._schema.variants[variantKeys[0]!]!;\n const result = firstVariant._internal.transformOperation(clientOp, serverOp);\n\n return result;\n }\n\n // Default: no transformation needed\n return { type: \"transformed\", operation: clientOp };\n },\n };\n}\n\n/** Options for creating a Union primitive */\nexport interface UnionOptions<TVariants extends UnionVariants, TDiscriminator extends string> {\n /** The field name used to discriminate between variants (defaults to \"type\") */\n readonly discriminator?: TDiscriminator;\n /** The variant struct primitives */\n readonly variants: TVariants;\n}\n\n/** Creates a new UnionPrimitive with the given variants */\nexport function Union<TVariants extends UnionVariants>(\n options: UnionOptions<TVariants, \"type\">\n): UnionPrimitive<TVariants, \"type\", false, false>;\nexport function Union<TVariants extends UnionVariants, TDiscriminator extends string>(\n options: UnionOptions<TVariants, TDiscriminator>\n): UnionPrimitive<TVariants, TDiscriminator, false, false>;\nexport function Union<TVariants extends UnionVariants, TDiscriminator extends string = \"type\">(\n options: UnionOptions<TVariants, TDiscriminator>\n): UnionPrimitive<TVariants, TDiscriminator, false, false> {\n const discriminator = (options.discriminator ?? \"type\") as TDiscriminator;\n return new UnionPrimitive({\n required: false,\n defaultValue: undefined,\n discriminator,\n variants: options.variants,\n });\n}\n\n"],"mappings":"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"}
|
|
@@ -15,12 +15,9 @@ var ValidationError = class extends Error {
|
|
|
15
15
|
function runValidators(value, validators) {
|
|
16
16
|
for (const validator of validators) if (!validator.validate(value)) throw new ValidationError(validator.message);
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
* Returns true if a primitive can represent null as a meaningful value.
|
|
20
|
-
* This is used to avoid pruning explicit null values for null-capable scalar unions.
|
|
21
|
-
*/
|
|
18
|
+
const isLiteralPrimitive = (primitive) => primitive._tag === "LiteralPrimitive" && "literal" in primitive;
|
|
22
19
|
function primitiveAllowsNullValue(primitive) {
|
|
23
|
-
if (primitive
|
|
20
|
+
if (isLiteralPrimitive(primitive)) return primitive.literal === null;
|
|
24
21
|
if (primitive._tag === "EitherPrimitive") {
|
|
25
22
|
var _schema;
|
|
26
23
|
const variants = (_schema = primitive._schema) === null || _schema === void 0 ? void 0 : _schema.variants;
|