abxbus 2.5.4 → 2.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/BaseEvent.d.ts +68 -23
- package/dist/cjs/BaseEvent.js +131 -14
- package/dist/cjs/BaseEvent.js.map +2 -2
- package/dist/cjs/base_event.d.ts +2 -2
- package/dist/cjs/bridge_ipc.d.ts +45 -0
- package/dist/cjs/event_handler.d.ts +1 -0
- package/dist/cjs/events_suck.d.ts +1 -1
- package/dist/cjs/events_suck.js.map +2 -2
- package/dist/cjs/jsonschema.d.ts +6 -0
- package/dist/cjs/jsonschema.js +155 -0
- package/dist/cjs/jsonschema.js.map +7 -0
- package/dist/cjs/middleware_otel_tracing.d.ts +49 -0
- package/dist/cjs/types.d.ts +3 -4
- package/dist/cjs/types.js +8 -15
- package/dist/cjs/types.js.map +2 -2
- package/dist/esm/BaseEvent.js +131 -14
- package/dist/esm/BaseEvent.js.map +2 -2
- package/dist/esm/events_suck.js.map +2 -2
- package/dist/esm/jsonschema.js +135 -0
- package/dist/esm/jsonschema.js.map +7 -0
- package/dist/esm/types.js +7 -14
- package/dist/esm/types.js.map +2 -2
- package/dist/types/BaseEvent.d.ts +68 -23
- package/dist/types/base_event.d.ts +2 -2
- package/dist/types/bridge_ipc.d.ts +45 -0
- package/dist/types/event_handler.d.ts +1 -0
- package/dist/types/events_suck.d.ts +1 -1
- package/dist/types/jsonschema.d.ts +6 -0
- package/dist/types/middleware_otel_tracing.d.ts +49 -0
- package/dist/types/types.d.ts +3 -4
- package/package.json +1 -1
- package/src/BaseEvent.ts +277 -54
- package/src/events_suck.ts +3 -2
- package/src/jsonschema.ts +146 -0
- package/src/types.ts +6 -14
- package/dist/cjs/CoreClient.d.ts +0 -167
- package/dist/cjs/CoreEventBus.d.ts +0 -334
- package/dist/types/CoreClient.d.ts +0 -167
- package/dist/types/CoreEventBus.d.ts +0 -334
package/src/BaseEvent.ts
CHANGED
|
@@ -13,7 +13,8 @@ import {
|
|
|
13
13
|
withResolvers,
|
|
14
14
|
} from './LockManager.js'
|
|
15
15
|
import { _runWithTimeout } from './timing.js'
|
|
16
|
-
import {
|
|
16
|
+
import { toJsonSchema, type JsonSchema } from './jsonschema.js'
|
|
17
|
+
import { isZodSchema, normalizeEventResultType } from './types.js'
|
|
17
18
|
import type { EventHandlerCallable, EventResultType } from './types.js'
|
|
18
19
|
import { monotonicDatetime } from './helpers.js'
|
|
19
20
|
|
|
@@ -103,7 +104,17 @@ export const BaseEventSchema = z
|
|
|
103
104
|
.loose()
|
|
104
105
|
|
|
105
106
|
const KNOWN_BASE_EVENT_FIELDS = new Set(Object.keys(BaseEventSchema.shape))
|
|
106
|
-
|
|
107
|
+
const EVENT_FACTORY_METADATA_FIELDS = new Set([
|
|
108
|
+
'class',
|
|
109
|
+
'fromJSON',
|
|
110
|
+
'prototype',
|
|
111
|
+
'event_schema',
|
|
112
|
+
'model_fields',
|
|
113
|
+
'event_type',
|
|
114
|
+
'event_version',
|
|
115
|
+
'event_result_type',
|
|
116
|
+
])
|
|
117
|
+
type AnyEventSchema = z.ZodObject<z.ZodRawShape>
|
|
107
118
|
|
|
108
119
|
export type BaseEventData = z.infer<typeof BaseEventSchema>
|
|
109
120
|
export type BaseEventJSON = BaseEventData & Record<string, unknown>
|
|
@@ -135,33 +146,105 @@ export type BaseEventInit<TFields extends Record<string, unknown>> = TFields & P
|
|
|
135
146
|
|
|
136
147
|
type BaseEventSchemaShape = typeof BaseEventSchema.shape
|
|
137
148
|
export type EventSchema<TShape extends z.ZodRawShape> = z.ZodObject<BaseEventSchemaShape & TShape>
|
|
138
|
-
type
|
|
149
|
+
type EventPayloadShape<TShape extends z.ZodRawShape> = {
|
|
150
|
+
[K in keyof TShape as K extends BaseEventFieldName ? never : K]: TShape[K]
|
|
151
|
+
}
|
|
152
|
+
type EventPayload<TShape extends z.ZodRawShape> =
|
|
153
|
+
EventPayloadShape<TShape> extends Record<string, never> ? {} : z.infer<z.ZodObject<EventPayloadShape<TShape>>>
|
|
154
|
+
type EventFactoryMetadataFieldName =
|
|
155
|
+
| 'class'
|
|
156
|
+
| 'fromJSON'
|
|
157
|
+
| 'prototype'
|
|
158
|
+
| 'event_schema'
|
|
159
|
+
| 'model_fields'
|
|
160
|
+
| 'event_type'
|
|
161
|
+
| 'event_version'
|
|
162
|
+
| 'event_result_type'
|
|
163
|
+
type StaticDefaultSchema = z.ZodDefault<z.ZodTypeAny> | z.ZodPrefault<z.ZodTypeAny> | z.ZodCatch<z.ZodTypeAny>
|
|
164
|
+
type EventModelFields<TShape extends z.ZodRawShape> = {
|
|
165
|
+
readonly [K in keyof TShape]: TShape[K]
|
|
166
|
+
}
|
|
167
|
+
type StaticEventDefaultValues<TShape extends z.ZodRawShape> = {
|
|
168
|
+
readonly [K in keyof TShape as K extends EventFactoryMetadataFieldName
|
|
169
|
+
? never
|
|
170
|
+
: TShape[K] extends StaticDefaultSchema
|
|
171
|
+
? K
|
|
172
|
+
: never]: z.output<TShape[K]>
|
|
173
|
+
}
|
|
174
|
+
type StaticEventDefaultValuesFromSchema<TSchema extends AnyEventSchema> =
|
|
175
|
+
TSchema extends z.ZodObject<infer TShape> ? StaticEventDefaultValues<TShape> : {}
|
|
176
|
+
type EventModelFieldsFromSchema<TSchema extends AnyEventSchema> =
|
|
177
|
+
TSchema extends z.ZodObject<infer TShape> ? TSchema['shape'] & EventModelFields<TShape> : {}
|
|
178
|
+
type OptionalFactoryArgs<TData> = {} extends TData ? [data?: TData] : [data: TData]
|
|
139
179
|
|
|
140
180
|
type EventInput<TShape extends z.ZodRawShape> = z.input<EventSchema<TShape>>
|
|
141
181
|
export type EventInit<TShape extends z.ZodRawShape> = Omit<EventInput<TShape>, keyof BaseEventFields> & Partial<BaseEventFields>
|
|
142
|
-
type EventPayloadFromSchema<TSchema extends AnyEventSchema> =
|
|
182
|
+
type EventPayloadFromSchema<TSchema extends AnyEventSchema> =
|
|
183
|
+
z.output<TSchema> extends Record<string, unknown> ? Omit<z.output<TSchema>, keyof BaseEventFields> : {}
|
|
143
184
|
type EventInputFromSchema<TSchema extends AnyEventSchema> = z.input<TSchema> extends Record<string, unknown> ? z.input<TSchema> : never
|
|
144
185
|
export type EventInitFromSchema<TSchema extends AnyEventSchema> = Omit<EventInputFromSchema<TSchema>, keyof BaseEventFields> &
|
|
145
186
|
Partial<BaseEventFields>
|
|
146
187
|
|
|
147
188
|
type EventWithResultSchema<TResult> = BaseEvent & { __event_result_type__?: TResult }
|
|
189
|
+
type NormalizedEventResultSchema<TInput> = TInput extends z.ZodTypeAny
|
|
190
|
+
? TInput
|
|
191
|
+
: TInput extends z.core.$ZodType
|
|
192
|
+
? z.ZodType<z.output<TInput>>
|
|
193
|
+
: TInput extends StringConstructor
|
|
194
|
+
? z.ZodString
|
|
195
|
+
: TInput extends NumberConstructor
|
|
196
|
+
? z.ZodNumber
|
|
197
|
+
: TInput extends BooleanConstructor
|
|
198
|
+
? z.ZodBoolean
|
|
199
|
+
: TInput extends ArrayConstructor
|
|
200
|
+
? z.ZodArray<z.ZodUnknown>
|
|
201
|
+
: TInput extends ObjectConstructor
|
|
202
|
+
? z.ZodRecord<z.ZodString, z.ZodUnknown>
|
|
203
|
+
: TInput extends JsonSchema
|
|
204
|
+
? z.ZodTypeAny
|
|
205
|
+
: z.ZodTypeAny
|
|
206
|
+
type ResultTypeSchemaFromShape<TShape> = TShape extends { event_result_type: infer S }
|
|
207
|
+
? NormalizedEventResultSchema<S>
|
|
208
|
+
: z.ZodTypeAny | undefined
|
|
209
|
+
type ResultTypeSchemaFromEventSchema<TSchema> =
|
|
210
|
+
TSchema extends z.ZodObject<infer TShape> ? ResultTypeSchemaFromShape<TShape> : z.ZodTypeAny | undefined
|
|
148
211
|
|
|
149
212
|
type ResultTypeFromEventResultTypeInput<TInput> = TInput extends z.ZodTypeAny
|
|
150
213
|
? z.infer<TInput>
|
|
151
|
-
: TInput extends
|
|
152
|
-
?
|
|
153
|
-
: TInput extends
|
|
154
|
-
?
|
|
155
|
-
: TInput extends
|
|
156
|
-
?
|
|
157
|
-
: TInput extends
|
|
158
|
-
?
|
|
159
|
-
: TInput extends
|
|
160
|
-
?
|
|
161
|
-
:
|
|
214
|
+
: TInput extends z.core.$ZodType
|
|
215
|
+
? z.output<TInput>
|
|
216
|
+
: TInput extends StringConstructor
|
|
217
|
+
? string
|
|
218
|
+
: TInput extends NumberConstructor
|
|
219
|
+
? number
|
|
220
|
+
: TInput extends BooleanConstructor
|
|
221
|
+
? boolean
|
|
222
|
+
: TInput extends ArrayConstructor
|
|
223
|
+
? unknown[]
|
|
224
|
+
: TInput extends ObjectConstructor
|
|
225
|
+
? Record<string, unknown>
|
|
226
|
+
: TInput extends JsonSchema
|
|
227
|
+
? unknown
|
|
228
|
+
: unknown
|
|
162
229
|
|
|
163
230
|
type ResultSchemaFromShape<TShape> = TShape extends { event_result_type: infer S } ? ResultTypeFromEventResultTypeInput<S> : unknown
|
|
164
231
|
type ResultSchemaFromEventSchema<TSchema> = TSchema extends z.ZodObject<infer TShape> ? ResultSchemaFromShape<TShape> : unknown
|
|
232
|
+
type ZodLiteralValue = string | number | bigint | boolean | null | undefined
|
|
233
|
+
type SeenShortcutLiteralPairs = WeakMap<object, WeakSet<object>>
|
|
234
|
+
type ShortcutDefaultModelField<K, TValue> = K extends keyof BaseEventSchemaShape
|
|
235
|
+
? z.ZodDefault<BaseEventSchemaShape[K]>
|
|
236
|
+
: z.ZodDefault<TValue extends ZodLiteralValue ? z.ZodLiteral<TValue> : z.ZodType<TValue>>
|
|
237
|
+
type ShortcutModelFields<TShape> = {
|
|
238
|
+
[K in keyof TShape as K extends 'event_result_type' ? never : K]: TShape[K] extends z.ZodTypeAny
|
|
239
|
+
? TShape[K]
|
|
240
|
+
: ShortcutDefaultModelField<K, TShape[K]>
|
|
241
|
+
} & (TShape extends { event_result_type: infer TResultType } ? { event_result_type: NormalizedEventResultSchema<TResultType> } : {})
|
|
242
|
+
type ShortcutZodModelFields<TShape> = {
|
|
243
|
+
[K in keyof ShortcutModelFields<TShape>]: ShortcutModelFields<TShape>[K] extends z.ZodTypeAny ? ShortcutModelFields<TShape>[K] : never
|
|
244
|
+
}
|
|
245
|
+
type ShortcutStaticDefaultValues<TShape, TModelFields extends z.ZodRawShape> = StaticEventDefaultValues<TModelFields> & {
|
|
246
|
+
readonly [K in keyof TShape as K extends EventFactoryMetadataFieldName ? never : TShape[K] extends z.ZodTypeAny ? never : K]: TShape[K]
|
|
247
|
+
}
|
|
165
248
|
export type EventResultInclude<TEvent extends BaseEvent> = (
|
|
166
249
|
result: EventResult<TEvent>['result'],
|
|
167
250
|
event_result: EventResult<TEvent>
|
|
@@ -188,26 +271,45 @@ type EventResultUpdateOptions<TEvent extends BaseEvent> = {
|
|
|
188
271
|
|
|
189
272
|
const ROOT_EVENTBUS_ID = '00000000-0000-0000-0000-000000000000'
|
|
190
273
|
|
|
191
|
-
export type
|
|
192
|
-
|
|
193
|
-
|
|
274
|
+
export type EventFactoryClass<TShape extends z.ZodRawShape, TResult = unknown> = (new (
|
|
275
|
+
...args: OptionalFactoryArgs<EventInit<TShape>>
|
|
276
|
+
) => EventWithResultSchema<TResult> & EventPayload<TShape>) &
|
|
277
|
+
StaticEventDefaultValues<TShape> & {
|
|
278
|
+
event_schema: EventSchema<TShape>
|
|
279
|
+
model_fields: EventModelFields<TShape>
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export type EventFactory<
|
|
283
|
+
TShape extends z.ZodRawShape,
|
|
284
|
+
TResult = unknown,
|
|
285
|
+
TStaticFields = StaticEventDefaultValues<TShape>,
|
|
286
|
+
> = TStaticFields & {
|
|
287
|
+
(...args: OptionalFactoryArgs<EventInit<TShape>>): EventWithResultSchema<TResult> & EventPayload<TShape>
|
|
288
|
+
new (...args: OptionalFactoryArgs<EventInit<TShape>>): EventWithResultSchema<TResult> & EventPayload<TShape>
|
|
194
289
|
event_schema: EventSchema<TShape>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
290
|
+
model_fields: EventModelFields<TShape>
|
|
291
|
+
class: EventFactoryClass<TShape, TResult>
|
|
292
|
+
event_type: string
|
|
293
|
+
event_version: string
|
|
294
|
+
event_result_type: ResultTypeSchemaFromShape<TShape>
|
|
295
|
+
fromJSON: (data: unknown) => EventWithResultSchema<TResult> & EventPayload<TShape>
|
|
200
296
|
}
|
|
201
297
|
|
|
202
|
-
export type
|
|
203
|
-
|
|
204
|
-
|
|
298
|
+
export type SchemaEventFactoryClass<TSchema extends AnyEventSchema, TResult = unknown> = (new (
|
|
299
|
+
...args: OptionalFactoryArgs<EventInitFromSchema<TSchema>>
|
|
300
|
+
) => EventWithResultSchema<TResult> & EventPayloadFromSchema<TSchema>) &
|
|
301
|
+
StaticEventDefaultValuesFromSchema<TSchema> & { event_schema: TSchema; model_fields: EventModelFieldsFromSchema<TSchema> }
|
|
302
|
+
|
|
303
|
+
export type SchemaEventFactory<TSchema extends AnyEventSchema, TResult = unknown> = StaticEventDefaultValuesFromSchema<TSchema> & {
|
|
304
|
+
(...args: OptionalFactoryArgs<EventInitFromSchema<TSchema>>): EventWithResultSchema<TResult> & EventPayloadFromSchema<TSchema>
|
|
305
|
+
new (...args: OptionalFactoryArgs<EventInitFromSchema<TSchema>>): EventWithResultSchema<TResult> & EventPayloadFromSchema<TSchema>
|
|
205
306
|
event_schema: TSchema
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
307
|
+
model_fields: EventModelFieldsFromSchema<TSchema>
|
|
308
|
+
class: SchemaEventFactoryClass<TSchema, TResult>
|
|
309
|
+
event_type: string
|
|
310
|
+
event_version: string
|
|
311
|
+
event_result_type: ResultTypeSchemaFromEventSchema<TSchema>
|
|
312
|
+
fromJSON: (data: unknown) => EventWithResultSchema<TResult> & EventPayloadFromSchema<TSchema>
|
|
211
313
|
}
|
|
212
314
|
|
|
213
315
|
type ZodShapeFrom<TShape extends Record<string, unknown>> = {
|
|
@@ -247,15 +349,72 @@ function missingBaseFields(event_type: string, user_shape: z.ZodRawShape): z.Zod
|
|
|
247
349
|
return Object.fromEntries(Object.entries(baseEventDefaultShape(event_type)).filter(([key]) => !(key in user_shape))) as z.ZodRawShape
|
|
248
350
|
}
|
|
249
351
|
|
|
250
|
-
|
|
251
|
-
|
|
352
|
+
function isZodLiteralValue(value: unknown): value is ZodLiteralValue {
|
|
353
|
+
return value === null || value === undefined || ['string', 'number', 'bigint', 'boolean'].includes(typeof value)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function isPlainShortcutLiteralObject(value: unknown): value is Record<string, unknown> {
|
|
357
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
358
|
+
return false
|
|
359
|
+
}
|
|
360
|
+
const prototype = Object.getPrototypeOf(value)
|
|
361
|
+
return prototype === Object.prototype || prototype === null
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function alreadyComparedShortcutLiteralPair(left: object, right: object, seen: SeenShortcutLiteralPairs): boolean {
|
|
365
|
+
let right_values = seen.get(left)
|
|
366
|
+
if (right_values?.has(right)) {
|
|
367
|
+
return true
|
|
368
|
+
}
|
|
369
|
+
if (!right_values) {
|
|
370
|
+
right_values = new WeakSet<object>()
|
|
371
|
+
seen.set(left, right_values)
|
|
372
|
+
}
|
|
373
|
+
right_values.add(right)
|
|
374
|
+
return false
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function shortcutLiteralValuesEqual(left: unknown, right: unknown, seen: SeenShortcutLiteralPairs = new WeakMap()): boolean {
|
|
378
|
+
if (Object.is(left, right)) {
|
|
379
|
+
return true
|
|
380
|
+
}
|
|
381
|
+
if (typeof left !== 'object' || left === null || typeof right !== 'object' || right === null) {
|
|
382
|
+
return false
|
|
383
|
+
}
|
|
384
|
+
if (alreadyComparedShortcutLiteralPair(left, right, seen)) {
|
|
385
|
+
return true
|
|
386
|
+
}
|
|
387
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
388
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) {
|
|
389
|
+
return false
|
|
390
|
+
}
|
|
391
|
+
return left.every((item, index) => shortcutLiteralValuesEqual(item, right[index], seen))
|
|
392
|
+
}
|
|
393
|
+
if (!isPlainShortcutLiteralObject(left) || !isPlainShortcutLiteralObject(right)) {
|
|
394
|
+
return false
|
|
395
|
+
}
|
|
396
|
+
const left_keys = Object.keys(left)
|
|
397
|
+
const right_keys = Object.keys(right)
|
|
398
|
+
if (left_keys.length !== right_keys.length) {
|
|
399
|
+
return false
|
|
400
|
+
}
|
|
401
|
+
return left_keys.every((key) =>
|
|
402
|
+
Object.prototype.hasOwnProperty.call(right, key) ? shortcutLiteralValuesEqual(left[key], right[key], seen) : false
|
|
403
|
+
)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function shortcutLiteralSchema<TValue>(value: TValue): z.ZodType<TValue> {
|
|
407
|
+
if (isZodLiteralValue(value)) {
|
|
408
|
+
return z.literal(value) as z.ZodType<TValue>
|
|
409
|
+
}
|
|
410
|
+
return z.custom<TValue>((candidate) => shortcutLiteralValuesEqual(candidate, value), 'Invalid literal value')
|
|
252
411
|
}
|
|
253
412
|
|
|
254
413
|
function shortcutDefaultSchema(base_field_schema: z.ZodTypeAny | undefined, value: unknown): z.ZodTypeAny {
|
|
255
414
|
if (!base_field_schema) {
|
|
256
|
-
return
|
|
415
|
+
return shortcutLiteralSchema(value).default(value)
|
|
257
416
|
}
|
|
258
|
-
return
|
|
417
|
+
return base_field_schema.default(base_field_schema.parse(value))
|
|
259
418
|
}
|
|
260
419
|
|
|
261
420
|
function schemaDefaultsForShortcut(event_type: string, raw_shape: Record<string, unknown>): z.ZodRawShape {
|
|
@@ -281,16 +440,54 @@ function zodFieldsForShortcut(raw_shape: Record<string, unknown>): z.ZodRawShape
|
|
|
281
440
|
return fields
|
|
282
441
|
}
|
|
283
442
|
|
|
443
|
+
function modelFieldsForShortcut(raw_shape: Record<string, unknown>, shortcut_shape: z.ZodRawShape): z.ZodRawShape {
|
|
444
|
+
const event_result_type = normalizeEventResultType(raw_shape.event_result_type)
|
|
445
|
+
return event_result_type ? { ...shortcut_shape, event_result_type } : shortcut_shape
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
function staticEventDefaultsFromModelFields(model_fields: z.ZodRawShape): Record<string, unknown> {
|
|
449
|
+
const fields: Record<string, unknown> = {}
|
|
450
|
+
for (const [key, value] of Object.entries(model_fields)) {
|
|
451
|
+
if (EVENT_FACTORY_METADATA_FIELDS.has(key)) {
|
|
452
|
+
continue
|
|
453
|
+
}
|
|
454
|
+
const parsed = (value as z.ZodTypeAny).safeParse(undefined)
|
|
455
|
+
if (parsed.success && parsed.data !== undefined) {
|
|
456
|
+
fields[key] = parsed.data
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return fields
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
function defineStaticEventFields(target: object, fields: Record<string, unknown>): void {
|
|
463
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
464
|
+
Object.defineProperty(target, key, {
|
|
465
|
+
value,
|
|
466
|
+
writable: false,
|
|
467
|
+
enumerable: true,
|
|
468
|
+
configurable: true,
|
|
469
|
+
})
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
284
473
|
function eventResultTypeFromObjectSchema(schema: z.ZodObject<z.ZodRawShape>): z.ZodTypeAny | undefined {
|
|
285
474
|
const raw_event_result_type = schema.shape.event_result_type
|
|
286
475
|
return raw_event_result_type === undefined ? undefined : normalizeEventResultType(raw_event_result_type)
|
|
287
476
|
}
|
|
288
477
|
|
|
478
|
+
function eventParseSchemaFromEventSchema(schema: z.ZodObject<z.ZodRawShape>): z.ZodObject<z.ZodRawShape> {
|
|
479
|
+
return schema.safeExtend({
|
|
480
|
+
event_result_type: z.unknown().optional(),
|
|
481
|
+
})
|
|
482
|
+
}
|
|
483
|
+
|
|
289
484
|
function buildFullEventSchema(
|
|
290
485
|
event_type: string,
|
|
291
486
|
spec: unknown
|
|
292
487
|
): {
|
|
293
|
-
event_schema:
|
|
488
|
+
event_schema: z.ZodObject<z.ZodRawShape>
|
|
489
|
+
event_parse_schema: z.ZodObject<z.ZodRawShape>
|
|
490
|
+
static_field_defaults: Record<string, unknown>
|
|
294
491
|
event_result_type?: z.ZodTypeAny
|
|
295
492
|
event_version?: string
|
|
296
493
|
} {
|
|
@@ -300,11 +497,12 @@ function buildFullEventSchema(
|
|
|
300
497
|
assertNoUnknownEventPrefixedFields(user_shape, `BaseEvent.extend(${event_type})`)
|
|
301
498
|
assertNoModelPrefixedFields(user_shape, `BaseEvent.extend(${event_type})`)
|
|
302
499
|
const full_schema = spec.safeExtend({
|
|
303
|
-
event_result_type: z.unknown().optional(),
|
|
304
500
|
...missingBaseFields(event_type, user_shape),
|
|
305
501
|
})
|
|
306
502
|
return {
|
|
307
503
|
event_schema: full_schema,
|
|
504
|
+
event_parse_schema: eventParseSchemaFromEventSchema(full_schema),
|
|
505
|
+
static_field_defaults: staticEventDefaultsFromModelFields(full_schema.shape),
|
|
308
506
|
event_result_type: eventResultTypeFromObjectSchema(spec),
|
|
309
507
|
}
|
|
310
508
|
}
|
|
@@ -317,9 +515,12 @@ function buildFullEventSchema(
|
|
|
317
515
|
...schemaDefaultsForShortcut(event_type, raw_shape),
|
|
318
516
|
...zodFieldsForShortcut(raw_shape),
|
|
319
517
|
}
|
|
320
|
-
const
|
|
518
|
+
const model_fields = modelFieldsForShortcut(raw_shape, shortcut_shape)
|
|
519
|
+
const full_schema = z.object(model_fields).safeExtend(missingBaseFields(event_type, model_fields)).loose()
|
|
321
520
|
return {
|
|
322
521
|
event_schema: full_schema,
|
|
522
|
+
event_parse_schema: eventParseSchemaFromEventSchema(full_schema),
|
|
523
|
+
static_field_defaults: staticEventDefaultsFromModelFields(full_schema.shape),
|
|
323
524
|
event_result_type: normalizeEventResultType(raw_shape.event_result_type),
|
|
324
525
|
event_version: typeof raw_shape.event_version === 'string' ? raw_shape.event_version : undefined,
|
|
325
526
|
}
|
|
@@ -365,11 +566,14 @@ export class BaseEvent {
|
|
|
365
566
|
event_handler_concurrency?: EventHandlerConcurrencyMode | null // concurrency mode for the handlers within the event
|
|
366
567
|
event_handler_completion?: EventHandlerCompletionMode | null // completion strategy: 'all' (default) waits for every handler, 'first' returns earliest non-undefined result and cancels the rest
|
|
367
568
|
event_schema?: z.ZodTypeAny
|
|
569
|
+
_event_parse_schema?: z.ZodTypeAny
|
|
368
570
|
|
|
369
571
|
static event_type?: string // class name of the event, e.g. BaseEvent.extend("MyEvent").event_type === "MyEvent"
|
|
370
572
|
static event_version = '0.0.1'
|
|
371
573
|
static event_result_type?: z.ZodTypeAny
|
|
372
574
|
static event_schema: AnyEventSchema = BaseEventSchema // generated Zod schema for local TS event data validation; never sent over the wire
|
|
575
|
+
static model_fields: z.ZodRawShape = BaseEventSchema.shape
|
|
576
|
+
static _event_parse_schema: AnyEventSchema = BaseEventSchema
|
|
373
577
|
|
|
374
578
|
// internal runtime state
|
|
375
579
|
event_bus?: EventBus // bus that dispatched this event, also used by event.emit(child)
|
|
@@ -387,6 +591,7 @@ export class BaseEvent {
|
|
|
387
591
|
event_version?: string
|
|
388
592
|
event_result_type?: z.ZodTypeAny
|
|
389
593
|
event_schema?: AnyEventSchema
|
|
594
|
+
_event_parse_schema?: AnyEventSchema
|
|
390
595
|
}
|
|
391
596
|
const explicit_event_fields = new Set(Object.keys(data ?? {}))
|
|
392
597
|
const merged_data = { ...data } as BaseEventInit<Record<string, unknown>>
|
|
@@ -396,6 +601,7 @@ export class BaseEvent {
|
|
|
396
601
|
const event_result_type = normalizeEventResultType(raw_event_result_type)
|
|
397
602
|
|
|
398
603
|
const event_schema = ctor.event_schema ?? BaseEventSchema
|
|
604
|
+
const event_parse_schema = ctor._event_parse_schema ?? event_schema
|
|
399
605
|
const base_data: Record<string, unknown> = {
|
|
400
606
|
...merged_data,
|
|
401
607
|
event_id: merged_data.event_id ?? uuidv7(),
|
|
@@ -404,12 +610,12 @@ export class BaseEvent {
|
|
|
404
610
|
event_version,
|
|
405
611
|
event_result_type,
|
|
406
612
|
}
|
|
407
|
-
if (
|
|
613
|
+
if (event_parse_schema === BaseEventSchema) {
|
|
408
614
|
base_data.event_timeout ??= null
|
|
409
615
|
base_data.event_blocks_parent_completion ??= false
|
|
410
616
|
}
|
|
411
617
|
|
|
412
|
-
const parsed = decodeEventSchema(
|
|
618
|
+
const parsed = decodeEventSchema(event_parse_schema, base_data) as BaseEventData & Record<string, unknown>
|
|
413
619
|
|
|
414
620
|
Object.assign(this, parsed)
|
|
415
621
|
Object.defineProperty(this, 'event_schema', {
|
|
@@ -418,13 +624,18 @@ export class BaseEvent {
|
|
|
418
624
|
enumerable: false,
|
|
419
625
|
configurable: true,
|
|
420
626
|
})
|
|
627
|
+
Object.defineProperty(this, '_event_parse_schema', {
|
|
628
|
+
value: event_parse_schema,
|
|
629
|
+
writable: true,
|
|
630
|
+
enumerable: false,
|
|
631
|
+
configurable: true,
|
|
632
|
+
})
|
|
421
633
|
Object.defineProperty(this, '_event_fields_set', {
|
|
422
634
|
value: explicit_event_fields,
|
|
423
635
|
writable: true,
|
|
424
636
|
enumerable: false,
|
|
425
637
|
configurable: true,
|
|
426
638
|
})
|
|
427
|
-
|
|
428
639
|
const parsed_path = (parsed as { event_path?: string[] }).event_path
|
|
429
640
|
this.event_path = Array.isArray(parsed_path) ? [...parsed_path] : []
|
|
430
641
|
this.event_created_at = monotonicDatetime(parsed.event_created_at)
|
|
@@ -470,39 +681,48 @@ export class BaseEvent {
|
|
|
470
681
|
event_type: string,
|
|
471
682
|
event_schema: TSchema
|
|
472
683
|
): SchemaEventFactory<TSchema, ResultSchemaFromEventSchema<TSchema>>
|
|
473
|
-
static extend<TShape extends
|
|
474
|
-
static extend<TShape extends Record<string, unknown>>(
|
|
684
|
+
static extend<const TShape extends Record<string, unknown>>(
|
|
475
685
|
event_type: string,
|
|
476
686
|
shape?: TShape
|
|
477
|
-
): EventFactory<
|
|
478
|
-
|
|
687
|
+
): EventFactory<
|
|
688
|
+
ShortcutZodModelFields<TShape>,
|
|
689
|
+
ResultSchemaFromShape<ShortcutZodModelFields<TShape>>,
|
|
690
|
+
ShortcutStaticDefaultValues<TShape, ShortcutZodModelFields<TShape>>
|
|
691
|
+
>
|
|
692
|
+
static extend<TShape extends z.ZodRawShape>(event_type: string, shape?: TShape): EventFactory<TShape, ResultSchemaFromShape<TShape>>
|
|
693
|
+
static extend<const TShape extends Record<string, unknown>>(
|
|
479
694
|
event_type: string,
|
|
480
695
|
shape?: TShape
|
|
481
696
|
): EventFactory<ZodShapeFrom<TShape>, ResultSchemaFromShape<TShape>> | SchemaEventFactory<AnyEventSchema, unknown> {
|
|
482
697
|
const built = buildFullEventSchema(event_type, shape ?? {})
|
|
483
698
|
const full_schema = built.event_schema
|
|
699
|
+
const event_parse_schema = built.event_parse_schema
|
|
700
|
+
const static_field_defaults = built.static_field_defaults
|
|
484
701
|
const event_result_type = built.event_result_type
|
|
485
702
|
const event_version = built.event_version
|
|
486
703
|
|
|
487
704
|
// create a new event class that extends BaseEvent and adds the custom fields
|
|
488
705
|
class ExtendedEvent extends BaseEvent {
|
|
489
706
|
static event_schema = full_schema
|
|
707
|
+
static model_fields = full_schema.shape
|
|
708
|
+
static _event_parse_schema = event_parse_schema
|
|
490
709
|
static event_type = event_type
|
|
491
710
|
static event_version = event_version ?? BaseEvent.event_version
|
|
492
711
|
static event_result_type = event_result_type
|
|
493
712
|
|
|
494
|
-
constructor(data
|
|
713
|
+
constructor(data?: EventInit<ZodShapeFrom<TShape>> | EventInitFromSchema<AnyEventSchema>) {
|
|
495
714
|
super(data as BaseEventInit<Record<string, unknown>>)
|
|
496
715
|
}
|
|
497
716
|
}
|
|
498
717
|
|
|
499
718
|
type FactoryResult = EventWithResultSchema<ResultSchemaFromShape<TShape>> & EventPayload<ZodShapeFrom<TShape>>
|
|
500
719
|
|
|
501
|
-
function EventFactory(data
|
|
720
|
+
function EventFactory(data?: EventInit<ZodShapeFrom<TShape>>): FactoryResult {
|
|
502
721
|
return new ExtendedEvent(data) as FactoryResult
|
|
503
722
|
}
|
|
504
723
|
|
|
505
724
|
EventFactory.event_schema = full_schema as EventSchema<ZodShapeFrom<TShape>>
|
|
725
|
+
EventFactory.model_fields = EventFactory.event_schema.shape as EventModelFields<ZodShapeFrom<TShape>>
|
|
506
726
|
EventFactory.event_type = event_type
|
|
507
727
|
EventFactory.event_version = event_version ?? BaseEvent.event_version
|
|
508
728
|
EventFactory.event_result_type = event_result_type
|
|
@@ -511,6 +731,8 @@ export class BaseEvent {
|
|
|
511
731
|
) => EventWithResultSchema<ResultSchemaFromShape<TShape>> & EventPayload<ZodShapeFrom<TShape>>
|
|
512
732
|
EventFactory.fromJSON = (data: unknown) => ExtendedEvent.fromJSON(data) as FactoryResult
|
|
513
733
|
EventFactory.prototype = ExtendedEvent.prototype
|
|
734
|
+
defineStaticEventFields(ExtendedEvent, static_field_defaults)
|
|
735
|
+
defineStaticEventFields(EventFactory, static_field_defaults)
|
|
514
736
|
EVENT_TYPE_REGISTRY.set(event_type, ExtendedEvent)
|
|
515
737
|
|
|
516
738
|
return EventFactory as unknown as EventFactory<ZodShapeFrom<TShape>, ResultSchemaFromShape<TShape>>
|
|
@@ -518,8 +740,8 @@ export class BaseEvent {
|
|
|
518
740
|
|
|
519
741
|
static fromJSON<T extends typeof BaseEvent>(this: T, data: unknown): InstanceType<T> {
|
|
520
742
|
if (!data || typeof data !== 'object') {
|
|
521
|
-
const
|
|
522
|
-
const parsed = decodeEventSchema(
|
|
743
|
+
const event_parse_schema = this._event_parse_schema ?? this.event_schema ?? BaseEventSchema
|
|
744
|
+
const parsed = decodeEventSchema(event_parse_schema, data)
|
|
523
745
|
return new this(parsed) as InstanceType<T>
|
|
524
746
|
}
|
|
525
747
|
const record = { ...(data as Record<string, unknown>) }
|
|
@@ -536,9 +758,6 @@ export class BaseEvent {
|
|
|
536
758
|
if (this !== BaseEvent && ctor.event_result_type && record.event_result_type !== undefined) {
|
|
537
759
|
delete record.event_result_type
|
|
538
760
|
}
|
|
539
|
-
if (record.event_result_type !== undefined && record.event_result_type !== null) {
|
|
540
|
-
record.event_result_type = normalizeEventResultType(record.event_result_type)
|
|
541
|
-
}
|
|
542
761
|
return new this(record as BaseEventInit<Record<string, unknown>>) as InstanceType<T>
|
|
543
762
|
}
|
|
544
763
|
|
|
@@ -567,8 +786,12 @@ export class BaseEvent {
|
|
|
567
786
|
Array.from(this.event_results.entries()).map(([handler_id, result]) => [handler_id, result.toJSON()])
|
|
568
787
|
)
|
|
569
788
|
|
|
570
|
-
const
|
|
571
|
-
|
|
789
|
+
const event_parse_schema = ((this.constructor as typeof BaseEvent)._event_parse_schema ??
|
|
790
|
+
this._event_parse_schema ??
|
|
791
|
+
(this.constructor as typeof BaseEvent).event_schema ??
|
|
792
|
+
this.event_schema ??
|
|
793
|
+
BaseEventSchema) as AnyEventSchema
|
|
794
|
+
const encoded = encodeEventSchema(event_parse_schema, {
|
|
572
795
|
...record,
|
|
573
796
|
event_id: this.event_id,
|
|
574
797
|
event_type: this.event_type,
|
package/src/events_suck.ts
CHANGED
|
@@ -27,8 +27,9 @@ export type GeneratedEvents<TEvents extends FunctionMap> = {
|
|
|
27
27
|
[K in keyof TEvents]: GeneratedEvent<TEvents[K]>
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
type EventInit<TEventClass extends EventClass<BaseEvent>> =
|
|
31
|
-
|
|
30
|
+
type EventInit<TEventClass extends EventClass<BaseEvent>> = [ConstructorParameters<TEventClass>[0]] extends [undefined]
|
|
31
|
+
? {}
|
|
32
|
+
: NonNullable<ConstructorParameters<TEventClass>[0]>
|
|
32
33
|
|
|
33
34
|
type EventMethodArgs<TEventClass extends EventClass<BaseEvent>> =
|
|
34
35
|
{} extends EventInit<TEventClass>
|