@colyseus/schema 4.0.20 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/Metadata.d.ts +56 -2
- package/build/Reflection.d.ts +28 -34
- package/build/Schema.d.ts +70 -9
- package/build/annotations.d.ts +64 -17
- package/build/codegen/cli.cjs +84 -67
- package/build/codegen/cli.cjs.map +1 -1
- package/build/decoder/DecodeOperation.d.ts +48 -5
- package/build/decoder/Decoder.d.ts +2 -2
- package/build/decoder/strategy/Callbacks.d.ts +1 -1
- package/build/encoder/ChangeRecorder.d.ts +107 -0
- package/build/encoder/ChangeTree.d.ts +218 -69
- package/build/encoder/EncodeDescriptor.d.ts +63 -0
- package/build/encoder/EncodeOperation.d.ts +25 -2
- package/build/encoder/Encoder.d.ts +59 -3
- package/build/encoder/MapJournal.d.ts +62 -0
- package/build/encoder/RefIdAllocator.d.ts +35 -0
- package/build/encoder/Root.d.ts +94 -13
- package/build/encoder/StateView.d.ts +116 -8
- package/build/encoder/changeTree/inheritedFlags.d.ts +34 -0
- package/build/encoder/changeTree/liveIteration.d.ts +3 -0
- package/build/encoder/changeTree/parentChain.d.ts +24 -0
- package/build/encoder/changeTree/treeAttachment.d.ts +13 -0
- package/build/encoder/streaming.d.ts +73 -0
- package/build/encoder/subscriptions.d.ts +25 -0
- package/build/index.cjs +5258 -1549
- package/build/index.cjs.map +1 -1
- package/build/index.d.ts +7 -3
- package/build/index.js +5258 -1549
- package/build/index.mjs +5249 -1549
- package/build/index.mjs.map +1 -1
- package/build/input/InputDecoder.d.ts +32 -0
- package/build/input/InputEncoder.d.ts +117 -0
- package/build/input/index.cjs +7453 -0
- package/build/input/index.cjs.map +1 -0
- package/build/input/index.d.ts +3 -0
- package/build/input/index.mjs +7450 -0
- package/build/input/index.mjs.map +1 -0
- package/build/types/HelperTypes.d.ts +67 -9
- package/build/types/TypeContext.d.ts +9 -0
- package/build/types/builder.d.ts +192 -0
- package/build/types/custom/ArraySchema.d.ts +25 -4
- package/build/types/custom/CollectionSchema.d.ts +30 -2
- package/build/types/custom/MapSchema.d.ts +52 -3
- package/build/types/custom/SetSchema.d.ts +32 -2
- package/build/types/custom/StreamSchema.d.ts +114 -0
- package/build/types/symbols.d.ts +48 -5
- package/package.json +9 -3
- package/src/Metadata.ts +259 -31
- package/src/Reflection.ts +15 -13
- package/src/Schema.ts +176 -134
- package/src/annotations.ts +365 -252
- package/src/bench_bloat.ts +173 -0
- package/src/bench_decode.ts +221 -0
- package/src/bench_decode_mem.ts +165 -0
- package/src/bench_encode.ts +108 -0
- package/src/bench_init.ts +150 -0
- package/src/bench_static.ts +109 -0
- package/src/bench_stream.ts +295 -0
- package/src/bench_view_cmp.ts +142 -0
- package/src/codegen/languages/csharp.ts +0 -24
- package/src/codegen/parser.ts +83 -61
- package/src/decoder/DecodeOperation.ts +168 -63
- package/src/decoder/Decoder.ts +20 -10
- package/src/decoder/ReferenceTracker.ts +4 -0
- package/src/decoder/strategy/Callbacks.ts +30 -26
- package/src/decoder/strategy/getDecoderStateCallbacks.ts +16 -13
- package/src/encoder/ChangeRecorder.ts +276 -0
- package/src/encoder/ChangeTree.ts +674 -519
- package/src/encoder/EncodeDescriptor.ts +213 -0
- package/src/encoder/EncodeOperation.ts +107 -65
- package/src/encoder/Encoder.ts +630 -119
- package/src/encoder/MapJournal.ts +124 -0
- package/src/encoder/RefIdAllocator.ts +68 -0
- package/src/encoder/Root.ts +247 -120
- package/src/encoder/StateView.ts +592 -121
- package/src/encoder/changeTree/inheritedFlags.ts +217 -0
- package/src/encoder/changeTree/liveIteration.ts +74 -0
- package/src/encoder/changeTree/parentChain.ts +131 -0
- package/src/encoder/changeTree/treeAttachment.ts +171 -0
- package/src/encoder/streaming.ts +232 -0
- package/src/encoder/subscriptions.ts +71 -0
- package/src/index.ts +15 -3
- package/src/input/InputDecoder.ts +57 -0
- package/src/input/InputEncoder.ts +303 -0
- package/src/input/index.ts +3 -0
- package/src/types/HelperTypes.ts +121 -24
- package/src/types/TypeContext.ts +14 -2
- package/src/types/builder.ts +331 -0
- package/src/types/custom/ArraySchema.ts +210 -197
- package/src/types/custom/CollectionSchema.ts +115 -35
- package/src/types/custom/MapSchema.ts +162 -58
- package/src/types/custom/SetSchema.ts +128 -39
- package/src/types/custom/StreamSchema.ts +310 -0
- package/src/types/symbols.ts +93 -6
- package/src/utils.ts +4 -6
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import type { ArraySchema } from "./custom/ArraySchema.js";
|
|
2
|
+
import type { MapSchema } from "./custom/MapSchema.js";
|
|
3
|
+
import type { SetSchema } from "./custom/SetSchema.js";
|
|
4
|
+
import type { CollectionSchema } from "./custom/CollectionSchema.js";
|
|
5
|
+
import type { StreamSchema } from "./custom/StreamSchema.js";
|
|
6
|
+
import type { Schema } from "../Schema.js";
|
|
7
|
+
import type { DefinitionType, RawPrimitiveType } from "../annotations.js";
|
|
8
|
+
import type { InferValueType, Constructor } from "./HelperTypes.js";
|
|
9
|
+
import { $builder } from "./symbols.js";
|
|
10
|
+
import { ARRAY_STREAM_NOT_SUPPORTED } from "../encoder/streaming.js";
|
|
11
|
+
|
|
12
|
+
type CollectionKind = "array" | "map" | "set" | "collection";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal record produced by FieldBuilder#toDefinition() and consumed by schema().
|
|
16
|
+
*/
|
|
17
|
+
export interface BuilderDefinition {
|
|
18
|
+
type: DefinitionType;
|
|
19
|
+
default?: any;
|
|
20
|
+
hasDefault: boolean;
|
|
21
|
+
view?: number; // tag value; undefined = no view
|
|
22
|
+
owned?: boolean;
|
|
23
|
+
unreliable?: boolean;
|
|
24
|
+
transient?: boolean;
|
|
25
|
+
deprecated?: boolean;
|
|
26
|
+
deprecatedThrows?: boolean;
|
|
27
|
+
static?: boolean;
|
|
28
|
+
stream?: boolean;
|
|
29
|
+
optional?: boolean;
|
|
30
|
+
/** Declaration-scope priority callback for `.stream()` fields. */
|
|
31
|
+
streamPriority?: (view: any, element: any) => number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Type-function that infers the instance value for a builder.
|
|
36
|
+
*/
|
|
37
|
+
export type BuilderOf<T> = FieldBuilder<T>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Chainable field builder. Instances are produced by `t.*()` factories.
|
|
41
|
+
*
|
|
42
|
+
* Generics:
|
|
43
|
+
* - `T` is the runtime/JS type of the field (e.g. `number`, `string`,
|
|
44
|
+
* `ArraySchema<Item>`). `.optional()` widens it to `T | undefined`
|
|
45
|
+
* so the inferred instance/toJSON shapes reflect absence.
|
|
46
|
+
* - `HasDefault` is a compile-time flag that the field carries a
|
|
47
|
+
* construction-time default — either an explicit `.default(v)` or an
|
|
48
|
+
* auto-default from a collection factory (`t.array`, `t.map`, …) or a
|
|
49
|
+
* Schema ref whose `initialize` takes zero args.
|
|
50
|
+
* - `IsOptional` is a compile-time brand for `.optional()`. Both
|
|
51
|
+
* `HasDefault` and `IsOptional` make the field omittable in
|
|
52
|
+
* `BuilderInitProps<T>`. A separate brand (rather than reading
|
|
53
|
+
* `undefined extends V`) sidesteps a TypeScript quirk where
|
|
54
|
+
* class-generic-inferred `V` resolves `undefined extends V` as `true`
|
|
55
|
+
* even for non-undefined types.
|
|
56
|
+
*
|
|
57
|
+
* schema() reads the internal configuration via `toDefinition()` and wires
|
|
58
|
+
* up metadata through the existing pipeline.
|
|
59
|
+
*/
|
|
60
|
+
export class FieldBuilder<
|
|
61
|
+
T = unknown,
|
|
62
|
+
HasDefault extends boolean = false,
|
|
63
|
+
IsOptional extends boolean = false,
|
|
64
|
+
> {
|
|
65
|
+
readonly [$builder]: true = true;
|
|
66
|
+
|
|
67
|
+
// Internal configuration. Public so schema() and tests can read it, but not
|
|
68
|
+
// meant to be mutated by users directly.
|
|
69
|
+
_type: DefinitionType;
|
|
70
|
+
_default: any = undefined;
|
|
71
|
+
_hasDefault = false;
|
|
72
|
+
_view: number | undefined = undefined;
|
|
73
|
+
_owned = false;
|
|
74
|
+
_unreliable = false;
|
|
75
|
+
_transient = false;
|
|
76
|
+
_deprecated = false;
|
|
77
|
+
_deprecatedThrows = true;
|
|
78
|
+
_static = false;
|
|
79
|
+
_stream = false;
|
|
80
|
+
_optional = false;
|
|
81
|
+
_streamPriority: ((view: any, element: any) => number) | undefined = undefined;
|
|
82
|
+
|
|
83
|
+
constructor(type: DefinitionType) {
|
|
84
|
+
this._type = type;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Provide a default value for this field. */
|
|
88
|
+
default(value: T): FieldBuilder<T, true, IsOptional> {
|
|
89
|
+
this._default = value;
|
|
90
|
+
this._hasDefault = true;
|
|
91
|
+
return this as unknown as FieldBuilder<T, true, IsOptional>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Tag this field with a view tag (DEFAULT_VIEW_TAG when called without arg). */
|
|
95
|
+
view(tag?: number): this {
|
|
96
|
+
// -1 is DEFAULT_VIEW_TAG; kept numeric here to avoid a circular import.
|
|
97
|
+
this._view = tag ?? -1;
|
|
98
|
+
return this;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Mark this field as owned (encoder-side ownership filtering). */
|
|
102
|
+
owned(): this {
|
|
103
|
+
this._owned = true;
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Mark this field as unreliable — tick patches emit it on the unreliable
|
|
109
|
+
* transport channel. Still persisted to full-sync snapshots unless also
|
|
110
|
+
* tagged with `.transient()`.
|
|
111
|
+
*/
|
|
112
|
+
unreliable(): this {
|
|
113
|
+
this._unreliable = true;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Mark this field as transient — NOT persisted to full-sync snapshots
|
|
119
|
+
* (`encodeAll` / `encodeAllView`). Late-joining clients see the field
|
|
120
|
+
* only after its next mutation is emitted on a tick patch. Orthogonal
|
|
121
|
+
* to `.unreliable()`.
|
|
122
|
+
*/
|
|
123
|
+
transient(): this {
|
|
124
|
+
this._transient = true;
|
|
125
|
+
return this;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Mark this field as static.
|
|
130
|
+
* - Primitive / Schema fields: synchronized once, skips change tracking.
|
|
131
|
+
* - Stream fields (`t.stream(X).static()`): child elements are frozen
|
|
132
|
+
* after add — post-add field mutations on elements become no-ops.
|
|
133
|
+
*/
|
|
134
|
+
static(): this {
|
|
135
|
+
this._static = true;
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Opt a collection field into priority-batched streaming delivery —
|
|
141
|
+
* ADDs drain at most `maxPerTick` per tick per view (or per broadcast
|
|
142
|
+
* tick without a view). Applies to `t.map(X)` / `t.set(X)` /
|
|
143
|
+
* `t.collection(X)`. Redundant on `t.stream(X)` (the factory already
|
|
144
|
+
* sets this flag).
|
|
145
|
+
*
|
|
146
|
+
* **Not supported on `t.array(X)`.** Array positional operations
|
|
147
|
+
* (`splice`, `unshift`, `reverse`) shift every subsequent index —
|
|
148
|
+
* holding some ADDs back for a later tick while indexes mutate
|
|
149
|
+
* underneath would produce a decoder-side state that doesn't match
|
|
150
|
+
* the server. Use `t.stream(X)` (stable monotonic positions) or
|
|
151
|
+
* `t.map(X).stream()` (keys never shift) instead.
|
|
152
|
+
*/
|
|
153
|
+
stream(): this {
|
|
154
|
+
const t = this._type as any;
|
|
155
|
+
if (t && typeof t === "object" && t.array !== undefined) {
|
|
156
|
+
throw new Error(ARRAY_STREAM_NOT_SUPPORTED);
|
|
157
|
+
}
|
|
158
|
+
this._stream = true;
|
|
159
|
+
return this;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Attach a priority callback for per-view `encodeView` delivery. The
|
|
164
|
+
* callback receives the client's StateView and the candidate element;
|
|
165
|
+
* higher return values emit first. Does nothing in broadcast mode
|
|
166
|
+
* (shared `encode()` drains FIFO). Only meaningful on stream fields.
|
|
167
|
+
*
|
|
168
|
+
* ```ts
|
|
169
|
+
* t.stream(Enemy).priority((view, enemy) =>
|
|
170
|
+
* -dist2(view.anchor, enemy)
|
|
171
|
+
* )
|
|
172
|
+
* ```
|
|
173
|
+
*/
|
|
174
|
+
priority<V = any>(fn: (view: any, element: V) => number): this {
|
|
175
|
+
this._streamPriority = fn as (view: any, element: any) => number;
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Mark this field as deprecated. Pass `false` to silence the access error. */
|
|
180
|
+
deprecated(throws = true): this {
|
|
181
|
+
this._deprecated = true;
|
|
182
|
+
this._deprecatedThrows = throws;
|
|
183
|
+
return this;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Mark this field as optional — inferred instance type becomes
|
|
188
|
+
* `T | undefined` and the property becomes omittable in initialization
|
|
189
|
+
* props. Skips the auto-instantiation of collection / Schema-ref
|
|
190
|
+
* defaults, so the field starts as `undefined` at runtime.
|
|
191
|
+
*/
|
|
192
|
+
optional(): FieldBuilder<T | undefined, HasDefault, true> {
|
|
193
|
+
this._optional = true;
|
|
194
|
+
return this as unknown as FieldBuilder<T | undefined, HasDefault, true>;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
toDefinition(): BuilderDefinition {
|
|
198
|
+
return {
|
|
199
|
+
type: this._type,
|
|
200
|
+
default: this._default,
|
|
201
|
+
hasDefault: this._hasDefault,
|
|
202
|
+
view: this._view,
|
|
203
|
+
owned: this._owned,
|
|
204
|
+
unreliable: this._unreliable,
|
|
205
|
+
transient: this._transient,
|
|
206
|
+
deprecated: this._deprecated,
|
|
207
|
+
deprecatedThrows: this._deprecatedThrows,
|
|
208
|
+
static: this._static,
|
|
209
|
+
stream: this._stream,
|
|
210
|
+
optional: this._optional,
|
|
211
|
+
streamPriority: this._streamPriority,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function isBuilder(value: any): value is FieldBuilder<any> {
|
|
217
|
+
return value != null && value[$builder] === true;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// Factory helpers
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
|
|
224
|
+
function primitive<T>(name: RawPrimitiveType): () => FieldBuilder<T> {
|
|
225
|
+
return () => new FieldBuilder<T>(name);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Accepts a Schema class, a primitive string, or another FieldBuilder as a child type.
|
|
229
|
+
export type ChildType =
|
|
230
|
+
| RawPrimitiveType
|
|
231
|
+
| Constructor<Schema>
|
|
232
|
+
| FieldBuilder<any>;
|
|
233
|
+
|
|
234
|
+
function resolveChild(child: ChildType): DefinitionType {
|
|
235
|
+
if (isBuilder(child)) {
|
|
236
|
+
return child._type;
|
|
237
|
+
}
|
|
238
|
+
return child as DefinitionType;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// ---------------------------------------------------------------------------
|
|
242
|
+
// t namespace
|
|
243
|
+
// ---------------------------------------------------------------------------
|
|
244
|
+
|
|
245
|
+
// Overloaded factories for collections. Implementation lives in a single function;
|
|
246
|
+
// overloads narrow the return type for Schema/primitive/builder children.
|
|
247
|
+
// All collection factories tag `HasDefault = true` because schema() auto-
|
|
248
|
+
// instantiates an empty collection when no explicit default is given.
|
|
249
|
+
interface ArrayFactory {
|
|
250
|
+
<C extends Constructor<Schema>>(child: C): FieldBuilder<ArraySchema<InstanceType<C>>, true, false>;
|
|
251
|
+
<P extends RawPrimitiveType>(child: P): FieldBuilder<ArraySchema<InferValueType<P>>, true, false>;
|
|
252
|
+
<V>(child: FieldBuilder<V>): FieldBuilder<ArraySchema<V>, true, false>;
|
|
253
|
+
}
|
|
254
|
+
interface MapFactory {
|
|
255
|
+
<C extends Constructor<Schema>>(child: C): FieldBuilder<MapSchema<InstanceType<C>>, true, false>;
|
|
256
|
+
<P extends RawPrimitiveType>(child: P): FieldBuilder<MapSchema<InferValueType<P>>, true, false>;
|
|
257
|
+
<V>(child: FieldBuilder<V>): FieldBuilder<MapSchema<V>, true, false>;
|
|
258
|
+
}
|
|
259
|
+
interface SetFactory {
|
|
260
|
+
<C extends Constructor<Schema>>(child: C): FieldBuilder<SetSchema<InstanceType<C>>, true, false>;
|
|
261
|
+
<P extends RawPrimitiveType>(child: P): FieldBuilder<SetSchema<InferValueType<P>>, true, false>;
|
|
262
|
+
<V>(child: FieldBuilder<V>): FieldBuilder<SetSchema<V>, true, false>;
|
|
263
|
+
}
|
|
264
|
+
interface CollectionFactory {
|
|
265
|
+
<C extends Constructor<Schema>>(child: C): FieldBuilder<CollectionSchema<InstanceType<C>>, true, false>;
|
|
266
|
+
<P extends RawPrimitiveType>(child: P): FieldBuilder<CollectionSchema<InferValueType<P>>, true, false>;
|
|
267
|
+
<V>(child: FieldBuilder<V>): FieldBuilder<CollectionSchema<V>, true, false>;
|
|
268
|
+
}
|
|
269
|
+
// t.stream(Entity) — priority-batched collection of Schema instances.
|
|
270
|
+
// Element type is restricted to Schema subclasses (no primitives) because
|
|
271
|
+
// priority batching relies on stable refIds, which primitives don't carry.
|
|
272
|
+
interface StreamFactory {
|
|
273
|
+
<C extends Constructor<Schema>>(child: C): FieldBuilder<StreamSchema<InstanceType<C>>, true, false>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const arrayFactory: ArrayFactory = ((child: ChildType) =>
|
|
277
|
+
new FieldBuilder({ array: resolveChild(child) } as DefinitionType)) as ArrayFactory;
|
|
278
|
+
const mapFactory: MapFactory = ((child: ChildType) =>
|
|
279
|
+
new FieldBuilder({ map: resolveChild(child) } as DefinitionType)) as MapFactory;
|
|
280
|
+
const setFactory: SetFactory = ((child: ChildType) =>
|
|
281
|
+
new FieldBuilder({ set: resolveChild(child) } as DefinitionType)) as SetFactory;
|
|
282
|
+
const collectionFactory: CollectionFactory = ((child: ChildType) =>
|
|
283
|
+
new FieldBuilder({ collection: resolveChild(child) } as DefinitionType)) as CollectionFactory;
|
|
284
|
+
const streamFactory: StreamFactory = ((child: ChildType) => {
|
|
285
|
+
const b = new FieldBuilder({ stream: resolveChild(child) } as DefinitionType);
|
|
286
|
+
b._stream = true;
|
|
287
|
+
return b;
|
|
288
|
+
}) as StreamFactory;
|
|
289
|
+
|
|
290
|
+
// Compile-time: does this Schema subclass need arguments at construction?
|
|
291
|
+
// A zero-arg or absent `initialize(...)` means schema() will auto-default the
|
|
292
|
+
// field to `new X()`, so `HasDefault = true`. A non-zero-arg initialize means
|
|
293
|
+
// the user has to provide the ref explicitly.
|
|
294
|
+
type RefHasDefault<C> =
|
|
295
|
+
C extends { prototype: { initialize(...args: infer P): any } }
|
|
296
|
+
? (P extends readonly [] ? true : false)
|
|
297
|
+
: true;
|
|
298
|
+
|
|
299
|
+
interface RefFactory {
|
|
300
|
+
<C extends Constructor<Schema>>(ctor: C): FieldBuilder<InstanceType<C>, RefHasDefault<C>, false>;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const refFactory: RefFactory = (<C extends Constructor<Schema>>(ctor: C) =>
|
|
304
|
+
new FieldBuilder<InstanceType<C>>(ctor as unknown as DefinitionType)) as RefFactory;
|
|
305
|
+
|
|
306
|
+
export const t = Object.freeze({
|
|
307
|
+
// Primitives
|
|
308
|
+
string: primitive<string>("string"),
|
|
309
|
+
number: primitive<number>("number"),
|
|
310
|
+
boolean: primitive<boolean>("boolean"),
|
|
311
|
+
int8: primitive<number>("int8"),
|
|
312
|
+
uint8: primitive<number>("uint8"),
|
|
313
|
+
int16: primitive<number>("int16"),
|
|
314
|
+
uint16: primitive<number>("uint16"),
|
|
315
|
+
int32: primitive<number>("int32"),
|
|
316
|
+
uint32: primitive<number>("uint32"),
|
|
317
|
+
int64: primitive<number>("int64"),
|
|
318
|
+
uint64: primitive<number>("uint64"),
|
|
319
|
+
float32: primitive<number>("float32"),
|
|
320
|
+
float64: primitive<number>("float64"),
|
|
321
|
+
bigint64: primitive<bigint>("bigint64"),
|
|
322
|
+
biguint64: primitive<bigint>("biguint64"),
|
|
323
|
+
|
|
324
|
+
/** Reference to a Schema subtype. `t.array(Item)` usually reads better, but this is available when a plain ref is needed. */
|
|
325
|
+
ref: refFactory,
|
|
326
|
+
array: arrayFactory,
|
|
327
|
+
map: mapFactory,
|
|
328
|
+
set: setFactory,
|
|
329
|
+
collection: collectionFactory,
|
|
330
|
+
stream: streamFactory,
|
|
331
|
+
});
|