@voidhash/mimic 0.0.7 → 0.0.9

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @voidhash/mimic@0.0.7 build /home/runner/work/mimic/mimic/packages/mimic
2
+ > @voidhash/mimic@0.0.9 build /home/runner/work/mimic/mimic/packages/mimic
3
3
  > tsdown
4
4
 
5
5
  ℹ tsdown v0.18.2 powered by rolldown v1.0.0-beta.55
@@ -17,7 +17,7 @@
17
17
  ℹ [CJS] dist/utils/tree-helpers.cjs 13.42 kB │ gzip: 3.18 kB
18
18
  ℹ [CJS] dist/primitives/Array.cjs 12.21 kB │ gzip: 2.66 kB
19
19
  ℹ [CJS] dist/client/WebSocketTransport.cjs 10.98 kB │ gzip: 2.71 kB
20
- ℹ [CJS] dist/primitives/Struct.cjs  9.17 kB │ gzip: 2.12 kB
20
+ ℹ [CJS] dist/primitives/Struct.cjs 10.24 kB │ gzip: 2.33 kB
21
21
  ℹ [CJS] dist/primitives/Either.cjs  8.06 kB │ gzip: 2.04 kB
22
22
  ℹ [CJS] dist/client/Rebase.cjs  7.85 kB │ gzip: 1.76 kB
23
23
  ℹ [CJS] dist/primitives/Union.cjs  7.47 kB │ gzip: 1.77 kB
@@ -52,9 +52,9 @@
52
52
  ℹ [CJS] dist/OperationDefinition.cjs  0.22 kB │ gzip: 0.16 kB
53
53
  ℹ [CJS] dist/client/Transport.cjs  0.21 kB │ gzip: 0.16 kB
54
54
  ℹ [CJS] dist/Transform.cjs  0.20 kB │ gzip: 0.16 kB
55
- ℹ [CJS] 44 files, total: 212.62 kB
55
+ ℹ [CJS] 44 files, total: 213.69 kB
56
56
  ℹ [CJS] dist/primitives/Tree.d.cts.map  6.90 kB │ gzip: 2.60 kB
57
- ℹ [CJS] dist/primitives/Struct.d.cts.map  3.85 kB │ gzip: 1.62 kB
57
+ ℹ [CJS] dist/primitives/Struct.d.cts.map  4.62 kB │ gzip: 1.95 kB
58
58
  ℹ [CJS] dist/utils/tree-helpers.d.cts.map  3.61 kB │ gzip: 1.31 kB
59
59
  ℹ [CJS] dist/primitives/Array.d.cts.map  3.27 kB │ gzip: 1.36 kB
60
60
  ℹ [CJS] dist/primitives/Union.d.cts.map  3.16 kB │ gzip: 1.38 kB
@@ -91,15 +91,15 @@
91
91
  ℹ [CJS] dist/primitives/Tree.d.cts 13.50 kB │ gzip: 3.50 kB
92
92
  ℹ [CJS] dist/utils/tree-helpers.d.cts 12.18 kB │ gzip: 2.52 kB
93
93
  ℹ [CJS] dist/client/Transport.d.cts  7.30 kB │ gzip: 1.84 kB
94
+ ℹ [CJS] dist/primitives/Struct.d.cts  6.93 kB │ gzip: 1.84 kB
94
95
  ℹ [CJS] dist/primitives/shared.d.cts  6.89 kB │ gzip: 2.09 kB
95
96
  ℹ [CJS] dist/client/ClientDocument.d.cts  6.07 kB │ gzip: 1.68 kB
96
- ℹ [CJS] dist/primitives/Struct.d.cts  5.96 kB │ gzip: 1.59 kB
97
97
  ℹ [CJS] dist/primitives/Either.d.cts  5.44 kB │ gzip: 1.54 kB
98
98
  ℹ [CJS] dist/primitives/Array.d.cts  5.01 kB │ gzip: 1.44 kB
99
99
  ℹ [CJS] dist/client/Rebase.d.cts  4.88 kB │ gzip: 1.14 kB
100
100
  ℹ [CJS] dist/primitives/Union.d.cts  4.58 kB │ gzip: 1.26 kB
101
101
  ℹ [CJS] dist/primitives/TreeNode.d.cts  4.28 kB │ gzip: 1.29 kB
102
- ℹ [CJS] dist/Primitive.d.cts  3.74 kB │ gzip: 0.80 kB
102
+ ℹ [CJS] dist/Primitive.d.cts  3.79 kB │ gzip: 0.82 kB
103
103
  ℹ [CJS] dist/server/ServerDocument.d.cts  3.58 kB │ gzip: 1.19 kB
104
104
  ℹ [CJS] dist/client/StateMonitor.d.cts  3.33 kB │ gzip: 1.07 kB
105
105
  ℹ [CJS] dist/EffectSchema.d.cts  3.20 kB │ gzip: 0.92 kB
@@ -120,8 +120,8 @@
120
120
  ℹ [CJS] dist/client/WebSocketTransport.d.cts  1.22 kB │ gzip: 0.55 kB
121
121
  ℹ [CJS] dist/Transform.d.cts  0.48 kB │ gzip: 0.26 kB
122
122
  ℹ [CJS] dist/OperationDefinition.d.cts  0.36 kB │ gzip: 0.21 kB
123
- ℹ [CJS] 67 files, total: 179.25 kB
124
- ✔ Build complete in 6277ms
123
+ ℹ [CJS] 67 files, total: 181.04 kB
124
+ ✔ Build complete in 5818ms
125
125
  ℹ [ESM] dist/index.mjs  1.01 kB │ gzip: 0.28 kB
126
126
  ℹ [ESM] dist/client/index.mjs  0.99 kB │ gzip: 0.28 kB
127
127
  ℹ [ESM] dist/server/index.mjs  0.41 kB │ gzip: 0.17 kB
@@ -130,9 +130,9 @@
130
130
  ℹ [ESM] dist/client/ClientDocument.mjs.map 46.96 kB │ gzip: 10.85 kB
131
131
  ℹ [ESM] dist/primitives/Tree.mjs 28.12 kB │ gzip: 4.93 kB
132
132
  ℹ [ESM] dist/primitives/Array.mjs.map 26.02 kB │ gzip: 6.47 kB
133
+ ℹ [ESM] dist/primitives/Struct.mjs.map 25.45 kB │ gzip: 6.50 kB
133
134
  ℹ [ESM] dist/utils/tree-helpers.mjs.map 24.70 kB │ gzip: 5.20 kB
134
135
  ℹ [ESM] dist/client/WebSocketTransport.mjs.map 23.44 kB │ gzip: 5.75 kB
135
- ℹ [ESM] dist/primitives/Struct.mjs.map 22.62 kB │ gzip: 5.82 kB
136
136
  ℹ [ESM] dist/client/ClientDocument.mjs 20.03 kB │ gzip: 4.49 kB
137
137
  ℹ [ESM] dist/primitives/Union.mjs.map 18.55 kB │ gzip: 4.63 kB
138
138
  ℹ [ESM] dist/primitives/Either.mjs.map 16.78 kB │ gzip: 4.12 kB
@@ -147,9 +147,9 @@
147
147
  ℹ [ESM] dist/server/ServerDocument.mjs.map 10.44 kB │ gzip: 2.95 kB
148
148
  ℹ [ESM] dist/client/StateMonitor.mjs.map 10.39 kB │ gzip: 3.04 kB
149
149
  ℹ [ESM] dist/primitives/String.mjs.map  9.70 kB │ gzip: 2.70 kB
150
+ ℹ [ESM] dist/primitives/Struct.mjs  9.30 kB │ gzip: 2.31 kB
150
151
  ℹ [ESM] dist/client/Transport.mjs.map  9.09 kB │ gzip: 1.86 kB
151
152
  ℹ [ESM] dist/primitives/Number.mjs.map  8.71 kB │ gzip: 2.41 kB
152
- ℹ [ESM] dist/primitives/Struct.mjs  8.32 kB │ gzip: 2.10 kB
153
153
  ℹ [ESM] dist/client/Rebase.mjs  7.61 kB │ gzip: 1.73 kB
154
154
  ℹ [ESM] dist/primitives/Either.mjs  7.47 kB │ gzip: 2.02 kB
155
155
  ℹ [ESM] dist/primitives/Boolean.mjs.map  7.45 kB │ gzip: 2.13 kB
@@ -160,6 +160,7 @@
160
160
  ℹ [ESM] dist/EffectSchema.mjs  6.47 kB │ gzip: 1.59 kB
161
161
  ℹ [ESM] dist/primitives/TreeNode.mjs.map  6.47 kB │ gzip: 2.05 kB
162
162
  ℹ [ESM] dist/client/errors.mjs.map  5.68 kB │ gzip: 1.37 kB
163
+ ℹ [ESM] dist/primitives/Struct.d.mts.map  4.63 kB │ gzip: 1.96 kB
163
164
  ℹ [ESM] dist/primitives/Lazy.mjs.map  4.59 kB │ gzip: 1.40 kB
164
165
  ℹ [ESM] dist/Presence.mjs.map  4.56 kB │ gzip: 1.30 kB
165
166
  ℹ [ESM] dist/primitives/String.mjs  4.42 kB │ gzip: 1.34 kB
@@ -167,7 +168,6 @@
167
168
  ℹ [ESM] dist/OperationPath.mjs  4.03 kB │ gzip: 1.13 kB
168
169
  ℹ [ESM] dist/Document.mjs  4.00 kB │ gzip: 1.40 kB
169
170
  ℹ [ESM] dist/primitives/Number.mjs  3.99 kB │ gzip: 1.19 kB
170
- ℹ [ESM] dist/primitives/Struct.d.mts.map  3.90 kB │ gzip: 1.66 kB
171
171
  ℹ [ESM] dist/server/errors.mjs.map  3.86 kB │ gzip: 0.96 kB
172
172
  ℹ [ESM] dist/types/index.mjs.map  3.74 kB │ gzip: 0.79 kB
173
173
  ℹ [ESM] dist/utils/tree-helpers.d.mts.map  3.61 kB │ gzip: 1.31 kB
@@ -237,15 +237,15 @@
237
237
  ℹ [ESM] dist/primitives/Tree.d.mts 13.50 kB │ gzip: 3.50 kB
238
238
  ℹ [ESM] dist/utils/tree-helpers.d.mts 12.18 kB │ gzip: 2.52 kB
239
239
  ℹ [ESM] dist/client/Transport.d.mts  7.30 kB │ gzip: 1.84 kB
240
+ ℹ [ESM] dist/primitives/Struct.d.mts  6.96 kB │ gzip: 1.85 kB
240
241
  ℹ [ESM] dist/primitives/shared.d.mts  6.89 kB │ gzip: 2.09 kB
241
242
  ℹ [ESM] dist/client/ClientDocument.d.mts  6.09 kB │ gzip: 1.69 kB
242
- ℹ [ESM] dist/primitives/Struct.d.mts  5.99 kB │ gzip: 1.60 kB
243
243
  ℹ [ESM] dist/primitives/Either.d.mts  5.44 kB │ gzip: 1.54 kB
244
244
  ℹ [ESM] dist/primitives/Array.d.mts  5.04 kB │ gzip: 1.45 kB
245
245
  ℹ [ESM] dist/client/Rebase.d.mts  4.91 kB │ gzip: 1.15 kB
246
246
  ℹ [ESM] dist/primitives/Union.d.mts  4.61 kB │ gzip: 1.27 kB
247
247
  ℹ [ESM] dist/primitives/TreeNode.d.mts  4.31 kB │ gzip: 1.29 kB
248
- ℹ [ESM] dist/Primitive.d.mts  3.74 kB │ gzip: 0.80 kB
248
+ ℹ [ESM] dist/Primitive.d.mts  3.79 kB │ gzip: 0.82 kB
249
249
  ℹ [ESM] dist/server/ServerDocument.d.mts  3.61 kB │ gzip: 1.19 kB
250
250
  ℹ [ESM] dist/client/StateMonitor.d.mts  3.33 kB │ gzip: 1.07 kB
251
251
  ℹ [ESM] dist/EffectSchema.d.mts  3.20 kB │ gzip: 0.92 kB
@@ -266,5 +266,5 @@
266
266
  ℹ [ESM] dist/client/WebSocketTransport.d.mts  1.22 kB │ gzip: 0.55 kB
267
267
  ℹ [ESM] dist/Transform.d.mts  0.48 kB │ gzip: 0.26 kB
268
268
  ℹ [ESM] dist/OperationDefinition.d.mts  0.36 kB │ gzip: 0.22 kB
269
- ℹ [ESM] 144 files, total: 839.90 kB
270
- ✔ Build complete in 6315ms
269
+ ℹ [ESM] 144 files, total: 845.46 kB
270
+ ✔ Build complete in 5846ms
@@ -1 +1 @@
1
- {"version":3,"file":"Presence.d.mts","names":[],"sources":["../src/Presence.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UAeiB;;;mBAGE,MAAA,CAAO,OAAO;;EAHhB,SAAA,KAAQ,EAKP,KALO;;;;;AAWR,UAAA,eAAe,CAAA,KAAA,CAEC,CAAA;EAMrB;EAKA,SAAA,MAAW,EAXJ,MAAA,CAAO,MAWA,CAXO,KAWC,CAAA;AASlC;AA8BA;;;AAAwE,KA5C5D,KA4C4D,CAAA,UA5C5C,QA4C4C,CAAA,GAAA,CAAA,CAAA,GA5C3B,CA4C2B,CAAA,OAAA,CAAA;;;AAmBxE;AACqB,KA3DT,WAAA,GAAc,QA2DL,CAAA,GAAA,CAAA;;;;AAcR,UAhEI,aAyEhB,CAAA,QAAA,OAAA,CAAA,CAAA;EARoB;EAAT,SAAA,IAAA,EA/DK,KA+DL;EAET;EAAK,SAAA,MAAA,CAAA,EAAA,MAAA;AAeR;;;;;;;;;;;;;;;;;;;;cApDa,uBAAyB,gBAAgB,WAAS,SAAS;;;;;;;;;;cAmB3D,4BACD,SAAS,0BAElB;;;;;;;;;cAYU,gCACD,SAAS,0BAElB;;;;;;;;cAeU,2BACD,SAAS,kCAEV"}
1
+ {"version":3,"file":"Presence.d.mts","names":[],"sources":["../src/Presence.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UAeiB;;;mBAGE,MAAA,CAAO,OAAO;;EAHhB,SAAA,KAAQ,EAKP,KALO;;;;;AAWR,UAAA,eAAe,CAAA,KAEC,CAAA,CAAA;EAMrB;EAKA,SAAA,MAAW,EAXJ,MAAA,CAAO,MAWA,CAXO,KAWC,CAAA;AASlC;AA8BA;;;AAAwE,KA5C5D,KA4C4D,CAAA,UA5C5C,QA4C4C,CAAA,GAAA,CAAA,CAAA,GA5C3B,CA4C2B,CAAA,OAAA,CAAA;;;AAmBxE;AACqB,KA3DT,WAAA,GAAc,QA2DL,CAAA,GAAA,CAAA;;;;AAcR,UAhEI,aAyEhB,CAAA,QAAA,OAAA,CAAA,CAAA;EARoB;EAAT,SAAA,IAAA,EA/DK,KA+DL;EAET;EAAK,SAAA,MAAA,CAAA,EAAA,MAAA;AAeR;;;;;;;;;;;;;;;;;;;;cApDa,uBAAyB,gBAAgB,WAAS,SAAS;;;;;;;;;;cAmB3D,4BACD,SAAS,0BAElB;;;;;;;;;cAYU,gCACD,SAAS,0BAElB;;;;;;;;cAeU,2BACD,SAAS,kCAEV"}
@@ -1,6 +1,6 @@
1
1
  import { AnyPrimitive, HasDefault, InferProxy, InferSetInput, InferSnapshot, InferState, InferUpdateInput, IsDefined, IsRequired, MaybeUndefined, NeedsValue, Optional, Primitive, PrimitiveInternal, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators } from "./primitives/shared.cjs";
2
2
  import { String, StringPrimitive, StringProxy } from "./primitives/String.cjs";
3
- import { InferStructSnapshot, InferStructState, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue } from "./primitives/Struct.cjs";
3
+ import { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue } from "./primitives/Struct.cjs";
4
4
  import { Boolean, BooleanPrimitive, BooleanProxy } from "./primitives/Boolean.cjs";
5
5
  import { Number, NumberPrimitive, NumberProxy } from "./primitives/Number.cjs";
6
6
  import { Literal, LiteralPrimitive, LiteralProxy, LiteralValue } from "./primitives/Literal.cjs";
@@ -13,7 +13,7 @@ import { InferTreeSetInput, InferTreeSnapshot, Tree, TreeNodeDataSetInput, TreeN
13
13
 
14
14
  //#region src/Primitive.d.ts
15
15
  declare namespace Primitive_d_exports {
16
- export { AnyPrimitive, AnyTreeNodePrimitive, Array, ArrayElementSetInput, ArrayEntry, ArrayEntrySnapshot, ArrayPrimitive, ArrayProxy, ArraySetInput, ArraySnapshot, ArrayState, ArrayUpdateInput, Boolean, BooleanPrimitive, BooleanProxy, Either, EitherMatchHandlers, EitherPrimitive, EitherProxy, HasDefault, InferEitherSnapshot, InferEitherState, InferLazyProxy, InferLazySetInput, InferLazySnapshot, InferLazyState, InferLazyUpdateInput, InferProxy, InferSetInput, InferSnapshot, InferState, InferStructSnapshot, InferStructState, InferTreeNodeChildren, InferTreeNodeDataState, InferTreeNodeType, InferTreeSetInput, InferTreeSnapshot, InferUnionSnapshot, InferUnionState, InferUpdateInput, IsDefined, IsRequired, Lazy, LazyPrimitive, Literal, LiteralPrimitive, LiteralProxy, LiteralValue, MaybeUndefined, NeedsValue, Number, NumberPrimitive, NumberProxy, Optional, Primitive, PrimitiveInternal, ScalarPrimitive, String, StringPrimitive, StringProxy, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue, Tree, TreeNode, TreeNodeChildrenInput, TreeNodeConfig, TreeNodeDataSetInput, TreeNodePrimitive, TreeNodeProxyBase, TreeNodeSelf, TreeNodeSelfType, TreeNodeSetInput, TreeNodeSetInputUnion, TreeNodeSnapshot, TreeNodeState, TreeNodeUpdateValue, TreeOptions, TreePrimitive, TreeProxy, TreeSetInput, TreeState, TreeUpdateInput, TypedNodeProxy, TypedTreeNodeState, Union, UnionOptions, UnionPrimitive, UnionProxy, UnionSetInput, UnionVariants, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators };
16
+ export { AnyPrimitive, AnyTreeNodePrimitive, Array, ArrayElementSetInput, ArrayEntry, ArrayEntrySnapshot, ArrayPrimitive, ArrayProxy, ArraySetInput, ArraySnapshot, ArrayState, ArrayUpdateInput, Boolean, BooleanPrimitive, BooleanProxy, Either, EitherMatchHandlers, EitherPrimitive, EitherProxy, HasDefault, InferEitherSnapshot, InferEitherState, InferLazyProxy, InferLazySetInput, InferLazySnapshot, InferLazyState, InferLazyUpdateInput, InferProxy, InferSetInput, InferSnapshot, InferState, InferStructSnapshot, InferStructState, InferTreeNodeChildren, InferTreeNodeDataState, InferTreeNodeType, InferTreeSetInput, InferTreeSnapshot, InferUnionSnapshot, InferUnionState, InferUpdateInput, IsDefined, IsRequired, Lazy, LazyPrimitive, Literal, LiteralPrimitive, LiteralProxy, LiteralValue, MakeOptional, MaybeUndefined, NeedsValue, Number, NumberPrimitive, NumberProxy, Optional, PartialFields, Primitive, PrimitiveInternal, ScalarPrimitive, String, StringPrimitive, StringProxy, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue, Tree, TreeNode, TreeNodeChildrenInput, TreeNodeConfig, TreeNodeDataSetInput, TreeNodePrimitive, TreeNodeProxyBase, TreeNodeSelf, TreeNodeSelfType, TreeNodeSetInput, TreeNodeSetInputUnion, TreeNodeSnapshot, TreeNodeState, TreeNodeUpdateValue, TreeOptions, TreePrimitive, TreeProxy, TreeSetInput, TreeState, TreeUpdateInput, TypedNodeProxy, TypedTreeNodeState, Union, UnionOptions, UnionPrimitive, UnionProxy, UnionSetInput, UnionVariants, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators };
17
17
  }
18
18
  //#endregion
19
19
  export { Primitive_d_exports };
@@ -1,6 +1,6 @@
1
1
  import { AnyPrimitive, HasDefault, InferProxy, InferSetInput, InferSnapshot, InferState, InferUpdateInput, IsDefined, IsRequired, MaybeUndefined, NeedsValue, Optional, Primitive, PrimitiveInternal, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators } from "./primitives/shared.mjs";
2
2
  import { String, StringPrimitive, StringProxy } from "./primitives/String.mjs";
3
- import { InferStructSnapshot, InferStructState, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue } from "./primitives/Struct.mjs";
3
+ import { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue } from "./primitives/Struct.mjs";
4
4
  import { Boolean, BooleanPrimitive, BooleanProxy } from "./primitives/Boolean.mjs";
5
5
  import { Number, NumberPrimitive, NumberProxy } from "./primitives/Number.mjs";
6
6
  import { Literal, LiteralPrimitive, LiteralProxy, LiteralValue } from "./primitives/Literal.mjs";
@@ -13,7 +13,7 @@ import { InferTreeSetInput, InferTreeSnapshot, Tree, TreeNodeDataSetInput, TreeN
13
13
 
14
14
  //#region src/Primitive.d.ts
15
15
  declare namespace Primitive_d_exports {
16
- export { AnyPrimitive, AnyTreeNodePrimitive, Array, ArrayElementSetInput, ArrayEntry, ArrayEntrySnapshot, ArrayPrimitive, ArrayProxy, ArraySetInput, ArraySnapshot, ArrayState, ArrayUpdateInput, Boolean, BooleanPrimitive, BooleanProxy, Either, EitherMatchHandlers, EitherPrimitive, EitherProxy, HasDefault, InferEitherSnapshot, InferEitherState, InferLazyProxy, InferLazySetInput, InferLazySnapshot, InferLazyState, InferLazyUpdateInput, InferProxy, InferSetInput, InferSnapshot, InferState, InferStructSnapshot, InferStructState, InferTreeNodeChildren, InferTreeNodeDataState, InferTreeNodeType, InferTreeSetInput, InferTreeSnapshot, InferUnionSnapshot, InferUnionState, InferUpdateInput, IsDefined, IsRequired, Lazy, LazyPrimitive, Literal, LiteralPrimitive, LiteralProxy, LiteralValue, MaybeUndefined, NeedsValue, Number, NumberPrimitive, NumberProxy, Optional, Primitive, PrimitiveInternal, ScalarPrimitive, String, StringPrimitive, StringProxy, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue, Tree, TreeNode, TreeNodeChildrenInput, TreeNodeConfig, TreeNodeDataSetInput, TreeNodePrimitive, TreeNodeProxyBase, TreeNodeSelf, TreeNodeSelfType, TreeNodeSetInput, TreeNodeSetInputUnion, TreeNodeSnapshot, TreeNodeState, TreeNodeUpdateValue, TreeOptions, TreePrimitive, TreeProxy, TreeSetInput, TreeState, TreeUpdateInput, TypedNodeProxy, TypedTreeNodeState, Union, UnionOptions, UnionPrimitive, UnionProxy, UnionSetInput, UnionVariants, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators };
16
+ export { AnyPrimitive, AnyTreeNodePrimitive, Array, ArrayElementSetInput, ArrayEntry, ArrayEntrySnapshot, ArrayPrimitive, ArrayProxy, ArraySetInput, ArraySnapshot, ArrayState, ArrayUpdateInput, Boolean, BooleanPrimitive, BooleanProxy, Either, EitherMatchHandlers, EitherPrimitive, EitherProxy, HasDefault, InferEitherSnapshot, InferEitherState, InferLazyProxy, InferLazySetInput, InferLazySnapshot, InferLazyState, InferLazyUpdateInput, InferProxy, InferSetInput, InferSnapshot, InferState, InferStructSnapshot, InferStructState, InferTreeNodeChildren, InferTreeNodeDataState, InferTreeNodeType, InferTreeSetInput, InferTreeSnapshot, InferUnionSnapshot, InferUnionState, InferUpdateInput, IsDefined, IsRequired, Lazy, LazyPrimitive, Literal, LiteralPrimitive, LiteralProxy, LiteralValue, MakeOptional, MaybeUndefined, NeedsValue, Number, NumberPrimitive, NumberProxy, Optional, PartialFields, Primitive, PrimitiveInternal, ScalarPrimitive, String, StringPrimitive, StringProxy, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue, Tree, TreeNode, TreeNodeChildrenInput, TreeNodeConfig, TreeNodeDataSetInput, TreeNodePrimitive, TreeNodeProxyBase, TreeNodeSelf, TreeNodeSelfType, TreeNodeSetInput, TreeNodeSetInputUnion, TreeNodeSnapshot, TreeNodeState, TreeNodeUpdateValue, TreeOptions, TreePrimitive, TreeProxy, TreeSetInput, TreeState, TreeUpdateInput, TypedNodeProxy, TypedTreeNodeState, Union, UnionOptions, UnionPrimitive, UnionProxy, UnionSetInput, UnionVariants, ValidationError, Validator, applyDefaults, isCompatibleOperation, runValidators };
17
17
  }
18
18
  //#endregion
19
19
  export { Primitive_d_exports };
@@ -193,6 +193,37 @@ var StructPrimitive = class StructPrimitive {
193
193
  message
194
194
  }] }));
195
195
  }
196
+ /** Extend this struct with additional fields */
197
+ extend(newFields) {
198
+ return new StructPrimitive({
199
+ required: this._schema.required,
200
+ defaultValue: void 0,
201
+ fields: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, this._schema.fields), newFields),
202
+ validators: []
203
+ });
204
+ }
205
+ /** Make all properties of this struct optional (TRequired = false for all fields) */
206
+ partial() {
207
+ const partialFields = {};
208
+ for (const key in this._schema.fields) {
209
+ const field = this._schema.fields[key];
210
+ partialFields[key] = this._makeFieldOptional(field);
211
+ }
212
+ return new StructPrimitive({
213
+ required: this._schema.required,
214
+ defaultValue: void 0,
215
+ fields: partialFields,
216
+ validators: []
217
+ });
218
+ }
219
+ _makeFieldOptional(field) {
220
+ const fieldAny = field;
221
+ if (fieldAny._schema && typeof fieldAny._schema === "object") {
222
+ const Constructor = field.constructor;
223
+ return new Constructor(require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, fieldAny._schema), {}, { required: false }));
224
+ }
225
+ return field;
226
+ }
196
227
  };
197
228
  /** Creates a new StructPrimitive with the given fields */
198
229
  const Struct = (fields) => new StructPrimitive({
@@ -48,6 +48,16 @@ type InferStructSnapshot<TFields extends Record<string, AnyPrimitive>> = { reado
48
48
  * Uses each field's TUpdateInput type, which handles nested updates recursively.
49
49
  */
50
50
  type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = { readonly [K in keyof TFields]?: InferUpdateInput<TFields[K]> };
51
+ /**
52
+ * Transforms a primitive type to make it optional (TRequired = false).
53
+ * Preserves the primitive structure while changing the required flag.
54
+ */
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
+ * Maps each field in a struct to its optional version.
58
+ * All fields become optional (TRequired = false).
59
+ */
60
+ type PartialFields<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptional<TFields[K]> };
51
61
  /**
52
62
  * Maps a schema definition to its proxy type.
53
63
  * Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.
@@ -87,10 +97,15 @@ declare class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TReq
87
97
  get fields(): TFields;
88
98
  /** Add a custom validation rule (useful for cross-field validation) */
89
99
  refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault>;
100
+ /** Extend this struct with additional fields */
101
+ 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(): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>;
104
+ private _makeFieldOptional;
90
105
  readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>>;
91
106
  }
92
107
  /** Creates a new StructPrimitive with the given fields */
93
108
  declare const Struct: <TFields extends Record<string, AnyPrimitive>>(fields: TFields) => StructPrimitive<TFields, false, false>;
94
109
  //#endregion
95
- export { InferStructSnapshot, InferStructState, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
110
+ export { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
96
111
  //# sourceMappingURL=Struct.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Struct.d.cts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"Struct.d.cts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
@@ -49,6 +49,16 @@ type InferStructSnapshot<TFields extends Record<string, AnyPrimitive>> = { reado
49
49
  * Uses each field's TUpdateInput type, which handles nested updates recursively.
50
50
  */
51
51
  type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = { readonly [K in keyof TFields]?: InferUpdateInput<TFields[K]> };
52
+ /**
53
+ * Transforms a primitive type to make it optional (TRequired = false).
54
+ * Preserves the primitive structure while changing the required flag.
55
+ */
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
+ * Maps each field in a struct to its optional version.
59
+ * All fields become optional (TRequired = false).
60
+ */
61
+ type PartialFields<TFields extends Record<string, AnyPrimitive>> = { [K in keyof TFields]: MakeOptional<TFields[K]> };
52
62
  /**
53
63
  * Maps a schema definition to its proxy type.
54
64
  * Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.
@@ -88,10 +98,15 @@ declare class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TReq
88
98
  get fields(): TFields;
89
99
  /** Add a custom validation rule (useful for cross-field validation) */
90
100
  refine(fn: (value: InferStructState<TFields>) => boolean, message: string): StructPrimitive<TFields, TRequired, THasDefault>;
101
+ /** Extend this struct with additional fields */
102
+ 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(): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>;
105
+ private _makeFieldOptional;
91
106
  readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>>;
92
107
  }
93
108
  /** Creates a new StructPrimitive with the given fields */
94
109
  declare const Struct: <TFields extends Record<string, AnyPrimitive>>(fields: TFields) => StructPrimitive<TFields, false, false>;
95
110
  //#endregion
96
- export { InferStructSnapshot, InferStructState, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
111
+ export { InferStructSnapshot, InferStructState, MakeOptional, PartialFields, Struct, StructPrimitive, StructProxy, StructSetInput, StructUpdateValue };
97
112
  //# sourceMappingURL=Struct.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Struct.d.mts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"Struct.d.mts","names":[],"sources":["../../src/primitives/Struct.ts"],"sourcesContent":[],"mappings":"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"}
@@ -192,6 +192,37 @@ var StructPrimitive = class StructPrimitive {
192
192
  message
193
193
  }] }));
194
194
  }
195
+ /** Extend this struct with additional fields */
196
+ extend(newFields) {
197
+ return new StructPrimitive({
198
+ required: this._schema.required,
199
+ defaultValue: void 0,
200
+ fields: _objectSpread2(_objectSpread2({}, this._schema.fields), newFields),
201
+ validators: []
202
+ });
203
+ }
204
+ /** Make all properties of this struct optional (TRequired = false for all fields) */
205
+ partial() {
206
+ const partialFields = {};
207
+ for (const key in this._schema.fields) {
208
+ const field = this._schema.fields[key];
209
+ partialFields[key] = this._makeFieldOptional(field);
210
+ }
211
+ return new StructPrimitive({
212
+ required: this._schema.required,
213
+ defaultValue: void 0,
214
+ fields: partialFields,
215
+ validators: []
216
+ });
217
+ }
218
+ _makeFieldOptional(field) {
219
+ const fieldAny = field;
220
+ if (fieldAny._schema && typeof fieldAny._schema === "object") {
221
+ const Constructor = field.constructor;
222
+ return new Constructor(_objectSpread2(_objectSpread2({}, fieldAny._schema), {}, { required: false }));
223
+ }
224
+ return field;
225
+ }
195
226
  };
196
227
  /** Creates a new StructPrimitive with the given fields */
197
228
  const Struct = (fields) => new StructPrimitive({
@@ -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"],"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 } 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 * 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 }),\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 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 if (fieldValue === undefined) continue; // Skip undefined values\n\n const fieldPrimitive = fields[key as keyof TFields];\n if (!fieldPrimitive) continue; // Skip unknown fields\n\n const fieldPath = operationPath.append(key);\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 const remainingPath = path.shift();\n const fieldOperation = {\n ...operation,\n path: remainingPath,\n };\n\n // Get the current field state\n const currentState = state ?? ({} as InferStructState<TFields>);\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 // 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\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>"],"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 } 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 }),\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 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 if (fieldValue === undefined) continue; // Skip undefined values\n\n const fieldPrimitive = fields[key as keyof TFields];\n if (!fieldPrimitive) continue; // Skip unknown fields\n\n const fieldPath = operationPath.append(key);\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 const remainingPath = path.shift();\n const fieldOperation = {\n ...operation,\n path: remainingPath,\n };\n\n // Get the current field state\n const currentState = state ?? ({} as InferStructState<TFields>);\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 // 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\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voidhash/mimic",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,7 +31,7 @@
31
31
  "typescript": "5.8.3",
32
32
  "vite-tsconfig-paths": "^5.1.4",
33
33
  "vitest": "^3.2.4",
34
- "@voidhash/tsconfig": "0.0.7"
34
+ "@voidhash/tsconfig": "0.0.9"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "effect": "^3.19.12"
@@ -81,6 +81,22 @@ export type StructUpdateValue<TFields extends Record<string, AnyPrimitive>> = {
81
81
  readonly [K in keyof TFields]?: InferUpdateInput<TFields[K]>;
82
82
  };
83
83
 
84
+ /**
85
+ * Transforms a primitive type to make it optional (TRequired = false).
86
+ * Preserves the primitive structure while changing the required flag.
87
+ */
88
+ export type MakeOptional<T extends AnyPrimitive> = T extends Primitive<infer S, infer P, any, infer H, infer SI, infer UI>
89
+ ? Primitive<S, P, false, H, SI, UI>
90
+ : T;
91
+
92
+ /**
93
+ * Maps each field in a struct to its optional version.
94
+ * All fields become optional (TRequired = false).
95
+ */
96
+ export type PartialFields<TFields extends Record<string, AnyPrimitive>> = {
97
+ [K in keyof TFields]: MakeOptional<TFields[K]>;
98
+ };
99
+
84
100
  /**
85
101
  * Maps a schema definition to its proxy type.
86
102
  * Provides nested field access + get()/set()/toSnapshot() methods for the whole struct.
@@ -162,6 +178,48 @@ export class StructPrimitive<TFields extends Record<string, AnyPrimitive>, TRequ
162
178
  });
163
179
  }
164
180
 
181
+ /** Extend this struct with additional fields */
182
+ extend<TNewFields extends Record<string, AnyPrimitive>>(
183
+ newFields: TNewFields
184
+ ): StructPrimitive<TFields & TNewFields, TRequired, THasDefault> {
185
+ return new StructPrimitive<TFields & TNewFields, TRequired, THasDefault>({
186
+ required: this._schema.required,
187
+ defaultValue: undefined,
188
+ fields: { ...this._schema.fields, ...newFields } as TFields & TNewFields,
189
+ validators: [],
190
+ });
191
+ }
192
+
193
+ /** Make all properties of this struct optional (TRequired = false for all fields) */
194
+ partial(): StructPrimitive<PartialFields<TFields>, TRequired, THasDefault> {
195
+ const partialFields: Record<string, AnyPrimitive> = {};
196
+ for (const key in this._schema.fields) {
197
+ const field = this._schema.fields[key]!;
198
+ // Create a new field that is not required (optional)
199
+ partialFields[key] = this._makeFieldOptional(field);
200
+ }
201
+ return new StructPrimitive<PartialFields<TFields>, TRequired, THasDefault>({
202
+ required: this._schema.required,
203
+ defaultValue: undefined,
204
+ fields: partialFields as PartialFields<TFields>,
205
+ validators: [],
206
+ });
207
+ }
208
+
209
+ private _makeFieldOptional(field: AnyPrimitive): AnyPrimitive {
210
+ // Create a new primitive with required: false
211
+ // We access the _schema property if available, otherwise return as-is
212
+ const fieldAny = field as any;
213
+ if (fieldAny._schema && typeof fieldAny._schema === "object") {
214
+ const Constructor = field.constructor as new (schema: any) => AnyPrimitive;
215
+ return new Constructor({
216
+ ...fieldAny._schema,
217
+ required: false,
218
+ });
219
+ }
220
+ return field;
221
+ }
222
+
165
223
  readonly _internal: PrimitiveInternal<InferStructState<TFields>, StructProxy<TFields, TRequired, THasDefault>> = {
166
224
  createProxy: (env: ProxyEnvironment.ProxyEnvironment, operationPath: OperationPath.OperationPath): StructProxy<TFields, TRequired, THasDefault> => {
167
225
  const fields = this._schema.fields;
@@ -554,6 +554,352 @@ describe("StructPrimitive", () => {
554
554
  expect(operations[0]!.path.toTokens()).toEqual(["users", "0", "name"]);
555
555
  });
556
556
  });
557
+ describe("extend", () => {
558
+ it("extends struct with additional fields", () => {
559
+ const basePrimitive = Primitive.Struct({
560
+ name: Primitive.String().required(),
561
+ });
562
+
563
+ const extendedPrimitive = basePrimitive.extend({
564
+ email: Primitive.String().required(),
565
+ age: Primitive.Number(),
566
+ });
567
+
568
+ // Verify fields exist
569
+ expect(extendedPrimitive.fields).toHaveProperty("name");
570
+ expect(extendedPrimitive.fields).toHaveProperty("email");
571
+ expect(extendedPrimitive.fields).toHaveProperty("age");
572
+ });
573
+
574
+ it("extended struct generates correct operations", () => {
575
+ const operations: Operation.Operation<any, any, any>[] = [];
576
+ const env = ProxyEnvironment.make((op) => {
577
+ operations.push(op);
578
+ });
579
+
580
+ const basePrimitive = Primitive.Struct({
581
+ name: Primitive.String(),
582
+ });
583
+
584
+ const extendedPrimitive = basePrimitive.extend({
585
+ email: Primitive.String(),
586
+ });
587
+
588
+ const proxy = extendedPrimitive._internal.createProxy(env, OperationPath.make(""));
589
+
590
+ proxy.name.set("John");
591
+ proxy.email.set("john@example.com");
592
+
593
+ expect(operations).toHaveLength(2);
594
+ expect(operations[0]!.kind).toBe("string.set");
595
+ expect(operations[0]!.payload).toBe("John");
596
+ expect(operations[0]!.path.toTokens()).toEqual(["name"]);
597
+ expect(operations[1]!.kind).toBe("string.set");
598
+ expect(operations[1]!.payload).toBe("john@example.com");
599
+ expect(operations[1]!.path.toTokens()).toEqual(["email"]);
600
+ });
601
+
602
+ it("extended struct set() works with all fields", () => {
603
+ const operations: Operation.Operation<any, any, any>[] = [];
604
+ const env = ProxyEnvironment.make((op) => {
605
+ operations.push(op);
606
+ });
607
+
608
+ const basePrimitive = Primitive.Struct({
609
+ name: Primitive.String(),
610
+ });
611
+
612
+ const extendedPrimitive = basePrimitive.extend({
613
+ email: Primitive.String(),
614
+ });
615
+
616
+ const proxy = extendedPrimitive._internal.createProxy(env, OperationPath.make(""));
617
+
618
+ proxy.set({ name: "John", email: "john@example.com" });
619
+
620
+ expect(operations).toHaveLength(1);
621
+ expect(operations[0]!.kind).toBe("struct.set");
622
+ expect(operations[0]!.payload).toEqual({ name: "John", email: "john@example.com" });
623
+ });
624
+
625
+ it("extended struct preserves required status", () => {
626
+ const basePrimitive = Primitive.Struct({
627
+ name: Primitive.String(),
628
+ }).required();
629
+
630
+ const extendedPrimitive = basePrimitive.extend({
631
+ email: Primitive.String(),
632
+ });
633
+
634
+ // The extended struct should still be required - verify via type system
635
+ // Compile-time check: if the type doesn't match, this would be a type error
636
+ type ExtendedTRequired = typeof extendedPrimitive._TRequired;
637
+ const _typeCheck: ExtendedTRequired = true as const;
638
+ expect(_typeCheck).toBe(true);
639
+ });
640
+
641
+ it("extended struct applyOperation works for both base and new fields", () => {
642
+ const basePrimitive = Primitive.Struct({
643
+ name: Primitive.String(),
644
+ });
645
+
646
+ const extendedPrimitive = basePrimitive.extend({
647
+ email: Primitive.String(),
648
+ });
649
+
650
+ const nameOperation: Operation.Operation<any, any, any> = {
651
+ kind: "string.set",
652
+ path: OperationPath.make("name"),
653
+ payload: "John",
654
+ };
655
+
656
+ const emailOperation: Operation.Operation<any, any, any> = {
657
+ kind: "string.set",
658
+ path: OperationPath.make("email"),
659
+ payload: "john@example.com",
660
+ };
661
+
662
+ let state = extendedPrimitive._internal.applyOperation(undefined, nameOperation);
663
+ state = extendedPrimitive._internal.applyOperation(state, emailOperation);
664
+
665
+ expect(state).toEqual({ name: "John", email: "john@example.com" });
666
+ });
667
+
668
+ it("can chain multiple extend calls", () => {
669
+ const basePrimitive = Primitive.Struct({
670
+ id: Primitive.String(),
671
+ });
672
+
673
+ const extendedOnce = basePrimitive.extend({
674
+ name: Primitive.String(),
675
+ });
676
+
677
+ const extendedTwice = extendedOnce.extend({
678
+ email: Primitive.String(),
679
+ });
680
+
681
+ expect(extendedTwice.fields).toHaveProperty("id");
682
+ expect(extendedTwice.fields).toHaveProperty("name");
683
+ expect(extendedTwice.fields).toHaveProperty("email");
684
+ });
685
+
686
+ it("extend with nested struct works correctly", () => {
687
+ const operations: Operation.Operation<any, any, any>[] = [];
688
+ const env = ProxyEnvironment.make((op) => {
689
+ operations.push(op);
690
+ });
691
+
692
+ const basePrimitive = Primitive.Struct({
693
+ name: Primitive.String(),
694
+ });
695
+
696
+ const addressPrimitive = Primitive.Struct({
697
+ city: Primitive.String(),
698
+ zip: Primitive.String(),
699
+ });
700
+
701
+ const extendedPrimitive = basePrimitive.extend({
702
+ address: addressPrimitive,
703
+ });
704
+
705
+ const proxy = extendedPrimitive._internal.createProxy(env, OperationPath.make(""));
706
+
707
+ proxy.address.city.set("New York");
708
+
709
+ expect(operations).toHaveLength(1);
710
+ expect(operations[0]!.kind).toBe("string.set");
711
+ expect(operations[0]!.payload).toBe("New York");
712
+ expect(operations[0]!.path.toTokens()).toEqual(["address", "city"]);
713
+ });
714
+ });
715
+
716
+ describe("partial", () => {
717
+ it("makes all fields optional", () => {
718
+ const structPrimitive = Primitive.Struct({
719
+ name: Primitive.String().required(),
720
+ email: Primitive.String().required(),
721
+ age: Primitive.Number().required(),
722
+ });
723
+
724
+ const partialPrimitive = structPrimitive.partial();
725
+
726
+ // All fields should now be optional (not required)
727
+ expect(partialPrimitive.fields).toHaveProperty("name");
728
+ expect(partialPrimitive.fields).toHaveProperty("email");
729
+ expect(partialPrimitive.fields).toHaveProperty("age");
730
+ });
731
+
732
+ it("partial struct allows empty set()", () => {
733
+ const operations: Operation.Operation<any, any, any>[] = [];
734
+ const env = ProxyEnvironment.make((op) => {
735
+ operations.push(op);
736
+ });
737
+
738
+ const structPrimitive = Primitive.Struct({
739
+ name: Primitive.String().required(),
740
+ email: Primitive.String().required(),
741
+ });
742
+
743
+ const partialPrimitive = structPrimitive.partial();
744
+
745
+ const proxy = partialPrimitive._internal.createProxy(env, OperationPath.make(""));
746
+
747
+ // This should work without providing any fields since all are optional
748
+ proxy.set({});
749
+
750
+ expect(operations).toHaveLength(1);
751
+ expect(operations[0]!.kind).toBe("struct.set");
752
+ });
753
+
754
+ it("partial struct allows partial set()", () => {
755
+ const operations: Operation.Operation<any, any, any>[] = [];
756
+ const env = ProxyEnvironment.make((op) => {
757
+ operations.push(op);
758
+ });
759
+
760
+ const structPrimitive = Primitive.Struct({
761
+ name: Primitive.String().required(),
762
+ email: Primitive.String().required(),
763
+ age: Primitive.Number().required(),
764
+ });
765
+
766
+ const partialPrimitive = structPrimitive.partial();
767
+
768
+ const proxy = partialPrimitive._internal.createProxy(env, OperationPath.make(""));
769
+
770
+ // Only provide some fields
771
+ proxy.set({ name: "John" });
772
+
773
+ expect(operations).toHaveLength(1);
774
+ expect(operations[0]!.kind).toBe("struct.set");
775
+ expect(operations[0]!.payload).toHaveProperty("name", "John");
776
+ });
777
+
778
+ it("partial struct field access still works", () => {
779
+ const operations: Operation.Operation<any, any, any>[] = [];
780
+ const env = ProxyEnvironment.make((op) => {
781
+ operations.push(op);
782
+ });
783
+
784
+ const structPrimitive = Primitive.Struct({
785
+ name: Primitive.String().required(),
786
+ email: Primitive.String().required(),
787
+ });
788
+
789
+ const partialPrimitive = structPrimitive.partial();
790
+
791
+ const proxy = partialPrimitive._internal.createProxy(env, OperationPath.make(""));
792
+
793
+ proxy.name.set("John");
794
+
795
+ expect(operations).toHaveLength(1);
796
+ expect(operations[0]!.kind).toBe("string.set");
797
+ expect(operations[0]!.payload).toBe("John");
798
+ expect(operations[0]!.path.toTokens()).toEqual(["name"]);
799
+ });
800
+
801
+ it("partial struct preserves required/default status of struct itself", () => {
802
+ const structPrimitive = Primitive.Struct({
803
+ name: Primitive.String().required(),
804
+ }).required();
805
+
806
+ const partialPrimitive = structPrimitive.partial();
807
+ // The struct itself should still be required - verify via type system
808
+ // Compile-time check: if the type doesn't match, this would be a type error
809
+ type PartialTRequired = typeof partialPrimitive._TRequired;
810
+ const _typeCheck: PartialTRequired = true as const;
811
+ expect(_typeCheck).toBe(true);
812
+ });
813
+
814
+ it("partial struct applyOperation works correctly", () => {
815
+ const structPrimitive = Primitive.Struct({
816
+ name: Primitive.String().required(),
817
+ email: Primitive.String().required(),
818
+ });
819
+
820
+ const partialPrimitive = structPrimitive.partial();
821
+
822
+ const operation: Operation.Operation<any, any, any> = {
823
+ kind: "string.set",
824
+ path: OperationPath.make("name"),
825
+ payload: "John",
826
+ };
827
+
828
+ const result = partialPrimitive._internal.applyOperation(undefined, operation);
829
+
830
+ expect(result).toEqual({ name: "John" });
831
+ });
832
+
833
+ it("partial can be combined with extend", () => {
834
+ const basePrimitive = Primitive.Struct({
835
+ id: Primitive.String().required(),
836
+ name: Primitive.String().required(),
837
+ });
838
+
839
+ // First extend, then partial
840
+ const extendedPartial = basePrimitive
841
+ .extend({
842
+ email: Primitive.String().required(),
843
+ })
844
+ .partial();
845
+
846
+ expect(extendedPartial.fields).toHaveProperty("id");
847
+ expect(extendedPartial.fields).toHaveProperty("name");
848
+ expect(extendedPartial.fields).toHaveProperty("email");
849
+ });
850
+
851
+ it("partial works with nested structs", () => {
852
+ const addressPrimitive = Primitive.Struct({
853
+ city: Primitive.String().required(),
854
+ zip: Primitive.String().required(),
855
+ });
856
+
857
+ const personPrimitive = Primitive.Struct({
858
+ name: Primitive.String().required(),
859
+ address: addressPrimitive.required(),
860
+ });
861
+
862
+ const partialPrimitive = personPrimitive.partial();
863
+
864
+ const operations: Operation.Operation<any, any, any>[] = [];
865
+ const env = ProxyEnvironment.make((op) => {
866
+ operations.push(op);
867
+ });
868
+
869
+ const proxy = partialPrimitive._internal.createProxy(env, OperationPath.make(""));
870
+
871
+ // Nested struct access should still work
872
+ proxy.address.city.set("New York");
873
+
874
+ expect(operations).toHaveLength(1);
875
+ expect(operations[0]!.kind).toBe("string.set");
876
+ expect(operations[0]!.payload).toBe("New York");
877
+ expect(operations[0]!.path.toTokens()).toEqual(["address", "city"]);
878
+ });
879
+
880
+ it("partial struct update() works correctly", () => {
881
+ const operations: Operation.Operation<any, any, any>[] = [];
882
+ const env = ProxyEnvironment.make((op) => {
883
+ operations.push(op);
884
+ });
885
+
886
+ const structPrimitive = Primitive.Struct({
887
+ name: Primitive.String().required(),
888
+ email: Primitive.String().required(),
889
+ age: Primitive.Number().required(),
890
+ });
891
+
892
+ const partialPrimitive = structPrimitive.partial();
893
+
894
+ const proxy = partialPrimitive._internal.createProxy(env, OperationPath.make(""));
895
+
896
+ proxy.update({ name: "Jane" });
897
+
898
+ expect(operations).toHaveLength(1);
899
+ expect(operations[0]!.kind).toBe("string.set");
900
+ expect(operations[0]!.payload).toBe("Jane");
901
+ });
902
+ });
557
903
  });
558
904
 
559
905
  // =============================================================================