cogsbox-state 0.5.472 → 0.5.474

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +48 -18
  2. package/dist/CogsState.d.ts +98 -82
  3. package/dist/CogsState.d.ts.map +1 -1
  4. package/dist/CogsState.jsx +1030 -960
  5. package/dist/CogsState.jsx.map +1 -1
  6. package/dist/Components.d.ts.map +1 -1
  7. package/dist/Components.jsx +299 -219
  8. package/dist/Components.jsx.map +1 -1
  9. package/dist/PluginRunner.d.ts +10 -0
  10. package/dist/PluginRunner.d.ts.map +1 -0
  11. package/dist/PluginRunner.jsx +122 -0
  12. package/dist/PluginRunner.jsx.map +1 -0
  13. package/dist/index.d.ts +2 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +33 -26
  16. package/dist/index.js.map +1 -1
  17. package/dist/pluginStore.d.ts +81 -0
  18. package/dist/pluginStore.d.ts.map +1 -0
  19. package/dist/pluginStore.js +52 -0
  20. package/dist/pluginStore.js.map +1 -0
  21. package/dist/plugins.d.ts +1323 -0
  22. package/dist/plugins.d.ts.map +1 -0
  23. package/dist/plugins.js +76 -0
  24. package/dist/plugins.js.map +1 -0
  25. package/dist/store.d.ts +50 -15
  26. package/dist/store.d.ts.map +1 -1
  27. package/dist/store.js +509 -470
  28. package/dist/store.js.map +1 -1
  29. package/dist/utility.d.ts +1 -1
  30. package/dist/utility.d.ts.map +1 -1
  31. package/dist/utility.js +12 -12
  32. package/dist/utility.js.map +1 -1
  33. package/dist/validation.d.ts +7 -0
  34. package/dist/validation.d.ts.map +1 -0
  35. package/dist/validation.js +39 -0
  36. package/dist/validation.js.map +1 -0
  37. package/package.json +13 -3
  38. package/src/CogsState.tsx +657 -457
  39. package/src/Components.tsx +291 -194
  40. package/src/PluginRunner.tsx +203 -0
  41. package/src/index.ts +2 -0
  42. package/src/pluginStore.ts +176 -0
  43. package/src/plugins.ts +544 -0
  44. package/src/store.ts +748 -493
  45. package/src/utility.ts +31 -31
  46. package/src/validation.ts +84 -0
package/src/plugins.ts ADDED
@@ -0,0 +1,544 @@
1
+ import { z } from 'zod';
2
+ import type React from 'react';
3
+ import { StateObject, UpdateTypeDetail } from './CogsState';
4
+ import { getGlobalStore } from './store';
5
+ import { ClientActivityEvent } from './pluginStore';
6
+
7
+ type Prettify<T> = { [K in keyof T]: T[K] } & {};
8
+
9
+ export type KeyedTypes<TMap extends Record<string, any>> = {
10
+ __key: 'keyed';
11
+ map: { [K in keyof TMap]: TMap[K] };
12
+ };
13
+
14
+ export const keyedSchema = <TMap extends Record<string, any>>() =>
15
+ z.object({
16
+ __key: z.literal('keyed'),
17
+ map: z.any(),
18
+ }) as z.ZodType<KeyedTypes<TMap>>;
19
+
20
+ // Helpers: turn a zod object shape into its inferred value shape
21
+ type InferZodObject<T extends Record<string, z.ZodTypeAny>> = {
22
+ [K in keyof T]: z.infer<T[K]>;
23
+ };
24
+ export type InferPerKeyValueMap<
25
+ TMap extends Record<string, Record<string, z.ZodTypeAny>>,
26
+ > = {
27
+ [K in keyof TMap]: InferZodObject<TMap[K]>;
28
+ };
29
+
30
+ // Deconstructed cogs methods (no TState)
31
+ type DeconstructedCogsMethods<TStateSlice = any> = {
32
+ initialiseState: (data: TStateSlice) => void;
33
+ initialiseShadowState: (data: any) => void;
34
+ applyOperation: (patch: any, meta?: { dontUpdate?: boolean }) => void;
35
+ addZodErrors: (errors: any[]) => void;
36
+ getState: () => TStateSlice;
37
+ setOptions: (options: any) => void;
38
+ };
39
+
40
+ export function toDeconstructedMethods(stateHandler: StateObject<any>) {
41
+ return {
42
+ initialiseState: (data: any) => {
43
+ stateHandler.$update(data);
44
+ },
45
+ initialiseShadowState: (data: any) => {
46
+ stateHandler.$initializeAndMergeShadowState(data);
47
+ },
48
+ applyOperation: (patch: any, meta?: { dontUpdate?: boolean }) =>
49
+ stateHandler.$applyOperation(patch, meta),
50
+ addZodErrors: (errors: any[]) => stateHandler.$addZodValidation(errors),
51
+ getState: () => stateHandler.$get(),
52
+ setOptions: (opts: any) => {
53
+ stateHandler.$setOptions(opts);
54
+ },
55
+ };
56
+ }
57
+
58
+ // Simplified: All params use the same TFieldMetaData type
59
+ export type UseHookParams<
60
+ TOptions,
61
+ TPluginMetaData,
62
+ TFieldMetaData,
63
+ TStateSlice = any,
64
+ > = DeconstructedCogsMethods<TStateSlice> & {
65
+ stateKey: string;
66
+
67
+ getPluginMetaData: () => TPluginMetaData | undefined;
68
+ setPluginMetaData: (data: Partial<TPluginMetaData>) => void;
69
+ removePluginMetaData: () => void;
70
+
71
+ getFieldMetaData: (path: string[]) => TFieldMetaData | undefined;
72
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) => void;
73
+ removeFieldMetaData: (path: string[]) => void;
74
+
75
+ options: TOptions;
76
+ pluginName: string;
77
+ isInitialMount: boolean;
78
+ };
79
+
80
+ export type TransformStateParams<
81
+ TOptions,
82
+ THookReturn,
83
+ TPluginMetaData,
84
+ TFieldMetaData,
85
+ TStateSlice = any,
86
+ > = DeconstructedCogsMethods<TStateSlice> & {
87
+ stateKey: string;
88
+
89
+ getPluginMetaData: () => TPluginMetaData | undefined;
90
+ setPluginMetaData: (data: Partial<TPluginMetaData>) => void;
91
+ removePluginMetaData: () => void;
92
+
93
+ getFieldMetaData: (path: string[]) => TFieldMetaData | undefined;
94
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) => void;
95
+ removeFieldMetaData: (path: string[]) => void;
96
+
97
+ options: TOptions;
98
+ hookData?: THookReturn;
99
+ previousState?: TStateSlice;
100
+ isInitialTransform: boolean;
101
+ pluginName: string;
102
+ };
103
+
104
+ export type OnUpdateParams<
105
+ TOptions,
106
+ THookReturn,
107
+ TPluginMetaData,
108
+ TFieldMetaData,
109
+ TStateSlice = any,
110
+ > = DeconstructedCogsMethods<TStateSlice> & {
111
+ stateKey: string;
112
+
113
+ getPluginMetaData: () => TPluginMetaData | undefined;
114
+ setPluginMetaData: (data: Partial<TPluginMetaData>) => void;
115
+ removePluginMetaData: () => void;
116
+
117
+ getFieldMetaData: (path: string[]) => TFieldMetaData | undefined;
118
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) => void;
119
+ removeFieldMetaData: (path: string[]) => void;
120
+
121
+ update: UpdateTypeDetail;
122
+ path?: string[];
123
+
124
+ options: TOptions;
125
+ hookData?: THookReturn;
126
+
127
+ previousValue?: any;
128
+ nextValue?: any;
129
+ updateSource?: 'user' | 'plugin' | 'system';
130
+
131
+ pluginName: string;
132
+ };
133
+ export type OnFormUpdateParams<
134
+ TOptions,
135
+ THookReturn,
136
+ TPluginMetaData,
137
+ TFieldMetaData,
138
+ TStateSlice = any,
139
+ > = DeconstructedCogsMethods<TStateSlice> & {
140
+ stateKey: string;
141
+
142
+ getPluginMetaData: () => TPluginMetaData | undefined;
143
+ setPluginMetaData: (data: Partial<TPluginMetaData>) => void;
144
+ removePluginMetaData: () => void;
145
+
146
+ getFieldMetaData: (path: string[]) => TFieldMetaData | undefined;
147
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) => void;
148
+ removeFieldMetaData: (path: string[]) => void;
149
+
150
+ path: string[];
151
+ event: ClientActivityEvent; // Update this to use the full event type
152
+
153
+ options: TOptions;
154
+ hookData?: THookReturn;
155
+
156
+ formState?: 'pristine' | 'dirty' | 'submitting' | 'submitted';
157
+ pluginName: string;
158
+ };
159
+
160
+ export type FormWrapperParams<
161
+ TOptions,
162
+ THookReturn,
163
+ TPluginMetaData,
164
+ TFieldMetaData,
165
+ TStateSlice = any,
166
+ > = {
167
+ element: React.ReactNode;
168
+ path: string[];
169
+ stateKey: string;
170
+ options: TOptions;
171
+ hookData?: THookReturn;
172
+ fieldType?: string;
173
+ wrapperDepth?: number;
174
+
175
+ // Deconstructed methods
176
+ initialiseState: (data: TStateSlice) => void;
177
+ initialiseShadowState: (data: any) => void;
178
+ applyOperation: (patch: any, meta?: { dontUpdate?: boolean }) => void;
179
+ addZodErrors: (errors: any[]) => void;
180
+ getState: () => TStateSlice;
181
+ setOptions: (options: any) => void;
182
+
183
+ getPluginMetaData: () => TPluginMetaData | undefined;
184
+ setPluginMetaData: (data: Partial<TPluginMetaData>) => void;
185
+ removePluginMetaData: () => void;
186
+
187
+ getFieldMetaData: (path: string[]) => TFieldMetaData | undefined;
188
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) => void;
189
+ removeFieldMetaData: (path: string[]) => void;
190
+
191
+ pluginName: string;
192
+ };
193
+
194
+ // Unified plugin definition
195
+ export type CogsPlugin<
196
+ TName extends string,
197
+ TOptions,
198
+ THookReturn,
199
+ TPluginMetaData,
200
+ TFieldMetaData,
201
+ > = {
202
+ name: TName;
203
+
204
+ useHook?: (
205
+ params: UseHookParams<TOptions, TPluginMetaData, TFieldMetaData, any>
206
+ ) => THookReturn;
207
+
208
+ transformState?: (
209
+ params: TransformStateParams<
210
+ TOptions,
211
+ THookReturn,
212
+ TPluginMetaData,
213
+ TFieldMetaData,
214
+ any
215
+ >
216
+ ) => void;
217
+
218
+ onUpdate?: (
219
+ params: OnUpdateParams<
220
+ TOptions,
221
+ THookReturn,
222
+ TPluginMetaData,
223
+ TFieldMetaData,
224
+ any
225
+ >
226
+ ) => void;
227
+
228
+ onFormUpdate?: (
229
+ params: OnFormUpdateParams<
230
+ TOptions,
231
+ THookReturn,
232
+ TPluginMetaData,
233
+ TFieldMetaData,
234
+ any
235
+ >
236
+ ) => void;
237
+
238
+ formWrapper?: (
239
+ params: FormWrapperParams<
240
+ TOptions,
241
+ THookReturn,
242
+ TPluginMetaData,
243
+ TFieldMetaData,
244
+ any
245
+ >
246
+ ) => React.ReactNode;
247
+ };
248
+
249
+ // Extract plugin options helper
250
+ export type ExtractPluginOptions<
251
+ TPlugins extends readonly CogsPlugin<any, any, any, any, any>[],
252
+ > = {
253
+ [P in TPlugins[number] as P['name']]?: P extends CogsPlugin<
254
+ any,
255
+ infer O,
256
+ any,
257
+ any,
258
+ any
259
+ >
260
+ ? O
261
+ : never;
262
+ };
263
+
264
+ // Metadata helpers
265
+ export function createMetadataContext<TPluginMetaData, TFieldMetaData>(
266
+ stateKey: string,
267
+ pluginName: string
268
+ ) {
269
+ return {
270
+ getPluginMetaData: (): TPluginMetaData | undefined =>
271
+ getGlobalStore
272
+ .getState()
273
+ .getPluginMetaDataMap(stateKey, [])
274
+ ?.get(pluginName) as TPluginMetaData | undefined,
275
+
276
+ setPluginMetaData: (data: Partial<TPluginMetaData>) =>
277
+ getGlobalStore
278
+ .getState()
279
+ .setPluginMetaData(stateKey, [], pluginName, data),
280
+
281
+ removePluginMetaData: () =>
282
+ getGlobalStore.getState().removePluginMetaData(stateKey, [], pluginName),
283
+
284
+ getFieldMetaData: (path: string[]): TFieldMetaData | undefined =>
285
+ getGlobalStore
286
+ .getState()
287
+ .getPluginMetaDataMap(stateKey, path)
288
+ ?.get(pluginName) as TFieldMetaData | undefined,
289
+
290
+ setFieldMetaData: (path: string[], data: Partial<TFieldMetaData>) =>
291
+ getGlobalStore
292
+ .getState()
293
+ .setPluginMetaData(stateKey, path, pluginName, data),
294
+
295
+ removeFieldMetaData: (path: string[]) =>
296
+ getGlobalStore
297
+ .getState()
298
+ .removePluginMetaData(stateKey, path, pluginName),
299
+ };
300
+ }
301
+
302
+ type ZodObjOutput<T extends z.ZodObject<any>> = {
303
+ [K in keyof T['shape']]: z.output<T['shape'][K]>;
304
+ };
305
+ type OutputOf<T extends z.ZodTypeAny> =
306
+ T extends z.ZodObject<any> ? Prettify<ZodObjOutput<T>> : z.output<T>;
307
+
308
+ export function createPluginContext<
309
+ O extends z.ZodTypeAny,
310
+ PM extends z.ZodTypeAny | undefined = undefined,
311
+ FM extends z.ZodTypeAny | undefined = undefined,
312
+ >(schemas: { options: O; pluginMetaData?: PM; fieldMetaData?: FM }) {
313
+ // Crucial: compute from the generic params, not from an object-indexed optional type
314
+ type Options = OutputOf<O>;
315
+ type PluginMetaData = PM extends z.ZodTypeAny ? OutputOf<PM> : unknown;
316
+ type FieldMetaData = FM extends z.ZodTypeAny ? OutputOf<FM> : unknown;
317
+
318
+ function createPlugin<TName extends string>(name: TName) {
319
+ type TransformFn<THookReturn> = (
320
+ params: TransformStateParams<
321
+ Options,
322
+ THookReturn,
323
+ PluginMetaData,
324
+ FieldMetaData
325
+ >
326
+ ) => void;
327
+
328
+ type UpdateFn<THookReturn> = (
329
+ params: OnUpdateParams<
330
+ Options,
331
+ THookReturn,
332
+ PluginMetaData,
333
+ FieldMetaData
334
+ >
335
+ ) => void;
336
+
337
+ type FormUpdateFn<THookReturn> = (
338
+ params: OnFormUpdateParams<
339
+ Options,
340
+ THookReturn,
341
+ PluginMetaData,
342
+ FieldMetaData
343
+ >
344
+ ) => void;
345
+
346
+ type FormWrapperFn<THookReturn> = (
347
+ params: FormWrapperParams<
348
+ Options,
349
+ THookReturn,
350
+ PluginMetaData,
351
+ FieldMetaData
352
+ >
353
+ ) => React.ReactNode;
354
+
355
+ type Plugin<THookReturn> = Prettify<
356
+ CogsPlugin<TName, Options, THookReturn, PluginMetaData, FieldMetaData>
357
+ >;
358
+
359
+ const createPluginObject = <THookReturn = never>(
360
+ hookFn?: (
361
+ params: UseHookParams<Options, PluginMetaData, FieldMetaData>
362
+ ) => THookReturn,
363
+ transformFn?: TransformFn<THookReturn>,
364
+ updateHandler?: UpdateFn<THookReturn>,
365
+ formUpdateHandler?: FormUpdateFn<THookReturn>,
366
+ formWrapper?: FormWrapperFn<THookReturn>
367
+ ): Plugin<THookReturn> => {
368
+ return {
369
+ name,
370
+ useHook: hookFn as any,
371
+ transformState: transformFn as any,
372
+ onUpdate: updateHandler as any,
373
+ onFormUpdate: formUpdateHandler as any,
374
+ formWrapper: formWrapper as any,
375
+ };
376
+ };
377
+
378
+ type BuildRet<
379
+ THookReturn,
380
+ HasTransform extends boolean,
381
+ HasUpdate extends boolean,
382
+ HasFormUpdate extends boolean,
383
+ HasWrapper extends boolean,
384
+ > = Plugin<THookReturn> &
385
+ (HasTransform extends true
386
+ ? {}
387
+ : {
388
+ transformState(
389
+ fn: TransformFn<THookReturn>
390
+ ): BuildRet<
391
+ THookReturn,
392
+ true,
393
+ HasUpdate,
394
+ HasFormUpdate,
395
+ HasWrapper
396
+ >;
397
+ }) &
398
+ (HasUpdate extends true
399
+ ? {}
400
+ : {
401
+ onUpdate(
402
+ fn: UpdateFn<THookReturn>
403
+ ): BuildRet<
404
+ THookReturn,
405
+ HasTransform,
406
+ true,
407
+ HasFormUpdate,
408
+ HasWrapper
409
+ >;
410
+ }) &
411
+ (HasFormUpdate extends true
412
+ ? {}
413
+ : {
414
+ onFormUpdate(
415
+ fn: FormUpdateFn<THookReturn>
416
+ ): BuildRet<THookReturn, HasTransform, HasUpdate, true, HasWrapper>;
417
+ }) &
418
+ (HasWrapper extends true
419
+ ? {}
420
+ : {
421
+ formWrapper(
422
+ fn: FormWrapperFn<THookReturn>
423
+ ): BuildRet<
424
+ THookReturn,
425
+ HasTransform,
426
+ HasUpdate,
427
+ HasFormUpdate,
428
+ true
429
+ >;
430
+ });
431
+
432
+ function createBuilder<
433
+ THookReturn = never,
434
+ HasTransform extends boolean = false,
435
+ HasUpdate extends boolean = false,
436
+ HasFormUpdate extends boolean = false,
437
+ HasWrapper extends boolean = false,
438
+ >(
439
+ hookFn?: (
440
+ params: UseHookParams<Options, PluginMetaData, FieldMetaData>
441
+ ) => THookReturn,
442
+ transformFn?: TransformFn<THookReturn>,
443
+ updateHandler?: UpdateFn<THookReturn>,
444
+ formUpdateHandler?: FormUpdateFn<THookReturn>,
445
+ formWrapper?: FormWrapperFn<THookReturn>
446
+ ): BuildRet<
447
+ THookReturn,
448
+ HasTransform,
449
+ HasUpdate,
450
+ HasFormUpdate,
451
+ HasWrapper
452
+ > {
453
+ const plugin = createPluginObject<THookReturn>(
454
+ hookFn,
455
+ transformFn,
456
+ updateHandler,
457
+ formUpdateHandler,
458
+ formWrapper
459
+ );
460
+
461
+ const methods = {} as Partial<
462
+ BuildRet<
463
+ THookReturn,
464
+ HasTransform,
465
+ HasUpdate,
466
+ HasFormUpdate,
467
+ HasWrapper
468
+ >
469
+ >;
470
+
471
+ if (!transformFn) {
472
+ (methods as any).transformState = (fn: TransformFn<THookReturn>) =>
473
+ createBuilder<
474
+ THookReturn,
475
+ true,
476
+ HasUpdate,
477
+ HasFormUpdate,
478
+ HasWrapper
479
+ >(hookFn, fn, updateHandler, formUpdateHandler, formWrapper);
480
+ }
481
+ if (!updateHandler) {
482
+ (methods as any).onUpdate = (fn: UpdateFn<THookReturn>) =>
483
+ createBuilder<
484
+ THookReturn,
485
+ HasTransform,
486
+ true,
487
+ HasFormUpdate,
488
+ HasWrapper
489
+ >(hookFn, transformFn, fn, formUpdateHandler, formWrapper);
490
+ }
491
+ if (!formUpdateHandler) {
492
+ (methods as any).onFormUpdate = (fn: FormUpdateFn<THookReturn>) =>
493
+ createBuilder<THookReturn, HasTransform, HasUpdate, true, HasWrapper>(
494
+ hookFn,
495
+ transformFn,
496
+ updateHandler,
497
+ fn,
498
+ formWrapper
499
+ );
500
+ }
501
+ if (!formWrapper) {
502
+ (methods as any).formWrapper = (fn: FormWrapperFn<THookReturn>) =>
503
+ createBuilder<
504
+ THookReturn,
505
+ HasTransform,
506
+ HasUpdate,
507
+ HasFormUpdate,
508
+ true
509
+ >(hookFn, transformFn, updateHandler, formUpdateHandler, fn);
510
+ }
511
+
512
+ return Object.assign(plugin, methods) as BuildRet<
513
+ THookReturn,
514
+ HasTransform,
515
+ HasUpdate,
516
+ HasFormUpdate,
517
+ HasWrapper
518
+ >;
519
+ }
520
+
521
+ const start = Object.assign(
522
+ createBuilder<never, false, false, false, false>(),
523
+ {
524
+ useHook<THookReturn>(
525
+ hookFn: (
526
+ params: UseHookParams<Options, PluginMetaData, FieldMetaData>
527
+ ) => THookReturn
528
+ ) {
529
+ return createBuilder<THookReturn, false, false, false, false>(hookFn);
530
+ },
531
+ }
532
+ ) as BuildRet<never, false, false, false, false> & {
533
+ useHook<THookReturn>(
534
+ hookFn: (
535
+ params: UseHookParams<Options, PluginMetaData, FieldMetaData>
536
+ ) => THookReturn
537
+ ): BuildRet<THookReturn, false, false, false, false>;
538
+ };
539
+
540
+ return start;
541
+ }
542
+
543
+ return { createPlugin };
544
+ }