tinybase 7.1.0-beta.0 → 7.1.0-beta.2
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/@types/persisters/index.d.ts +3 -3
- package/@types/persisters/with-schemas/index.d.ts +6 -6
- package/@types/schematizers/index.d.ts +41 -0
- package/@types/schematizers/schematizer-typebox/index.d.ts +116 -0
- package/@types/schematizers/schematizer-typebox/with-schemas/index.d.ts +8 -0
- package/@types/schematizers/schematizer-zod/index.d.ts +113 -0
- package/@types/schematizers/schematizer-zod/with-schemas/index.d.ts +7 -0
- package/@types/schematizers/with-schemas/index.d.ts +12 -0
- package/@types/ui-react/index.d.ts +2 -2
- package/@types/ui-react/with-schemas/index.d.ts +4 -4
- package/agents.md +144 -0
- package/index.js +2 -1
- package/mergeable-store/index.js +2 -1
- package/mergeable-store/with-schemas/index.js +2 -1
- package/min/schematizers/index.js +1 -0
- package/min/schematizers/index.js.gz +0 -0
- package/min/schematizers/schematizer-typebox/index.js +1 -0
- package/min/schematizers/schematizer-typebox/index.js.gz +0 -0
- package/min/schematizers/schematizer-typebox/with-schemas/index.js +1 -0
- package/min/schematizers/schematizer-typebox/with-schemas/index.js.gz +0 -0
- package/min/schematizers/schematizer-zod/index.js +1 -0
- package/min/schematizers/schematizer-zod/index.js.gz +0 -0
- package/min/schematizers/schematizer-zod/with-schemas/index.js +1 -0
- package/min/schematizers/schematizer-zod/with-schemas/index.js.gz +0 -0
- package/min/schematizers/with-schemas/index.js +1 -0
- package/min/schematizers/with-schemas/index.js.gz +0 -0
- package/omni/index.js +2 -1
- package/omni/with-schemas/index.js +2 -1
- package/package.json +121 -5
- package/queries/index.js +2 -1
- package/queries/with-schemas/index.js +2 -1
- package/readme.md +13 -13
- package/releases.md +62 -38
- package/schematizers/index.js +1 -0
- package/schematizers/schematizer-typebox/index.js +106 -0
- package/schematizers/schematizer-typebox/with-schemas/index.js +106 -0
- package/schematizers/schematizer-zod/index.js +102 -0
- package/schematizers/schematizer-zod/with-schemas/index.js +102 -0
- package/schematizers/with-schemas/index.js +1 -0
- package/store/index.js +2 -1
- package/store/with-schemas/index.js +2 -1
- package/ui-react-dom/index.js +2 -1
- package/ui-react-dom/with-schemas/index.js +2 -1
- package/ui-react-inspector/index.js +2 -1
- package/ui-react-inspector/with-schemas/index.js +2 -1
- package/with-schemas/index.js +2 -1
|
@@ -232,8 +232,8 @@ export type PersisterListener<Persist extends Persists = Persists.StoreOnly> = (
|
|
|
232
232
|
* @category Listener
|
|
233
233
|
* @since v5.3.0
|
|
234
234
|
*/
|
|
235
|
-
export type StatusListener<
|
|
236
|
-
persister: Persister
|
|
235
|
+
export type StatusListener<Persister extends AnyPersister = AnyPersister> = (
|
|
236
|
+
persister: Persister,
|
|
237
237
|
status: Status,
|
|
238
238
|
) => void;
|
|
239
239
|
|
|
@@ -1465,7 +1465,7 @@ export interface Persister<Persist extends Persists = Persists.StoreOnly> {
|
|
|
1465
1465
|
* @category Listener
|
|
1466
1466
|
* @since v5.3.0
|
|
1467
1467
|
*/
|
|
1468
|
-
addStatusListener(listener: StatusListener<
|
|
1468
|
+
addStatusListener(listener: StatusListener<this>): Id;
|
|
1469
1469
|
|
|
1470
1470
|
/**
|
|
1471
1471
|
* The delListener method removes a listener that was previously added to the
|
|
@@ -283,8 +283,8 @@ export type PersisterListener<
|
|
|
283
283
|
* This has schema-based typing. The following is a simplified representation:
|
|
284
284
|
*
|
|
285
285
|
* ```ts override
|
|
286
|
-
* export type StatusListener<
|
|
287
|
-
* persister: Persister
|
|
286
|
+
* export type StatusListener<Persister extends AnyPersister = AnyPersister> = (
|
|
287
|
+
* persister: Persister,
|
|
288
288
|
* status: Status,
|
|
289
289
|
* ) => void;
|
|
290
290
|
* ```
|
|
@@ -301,8 +301,8 @@ export type PersisterListener<
|
|
|
301
301
|
*/
|
|
302
302
|
export type StatusListener<
|
|
303
303
|
Schemas extends OptionalSchemas,
|
|
304
|
-
|
|
305
|
-
> = (persister: Persister
|
|
304
|
+
Persister extends AnyPersister<Schemas> = AnyPersister<Schemas>,
|
|
305
|
+
> = (persister: Persister, status: Status) => void;
|
|
306
306
|
|
|
307
307
|
/**
|
|
308
308
|
* The PersisterStats type describes the number of times a Persister object has
|
|
@@ -1536,7 +1536,7 @@ export interface Persister<
|
|
|
1536
1536
|
* This has schema-based typing. The following is a simplified representation:
|
|
1537
1537
|
*
|
|
1538
1538
|
* ```ts override
|
|
1539
|
-
* addStatusListener(listener: StatusListener<
|
|
1539
|
+
* addStatusListener(listener: StatusListener<this>): Id;
|
|
1540
1540
|
* ```
|
|
1541
1541
|
*
|
|
1542
1542
|
* The provided listener is a StatusListener function, and will be called with
|
|
@@ -1573,7 +1573,7 @@ export interface Persister<
|
|
|
1573
1573
|
* @category Listener
|
|
1574
1574
|
* @since v5.3.0
|
|
1575
1575
|
*/
|
|
1576
|
-
addStatusListener(listener: StatusListener<Schemas,
|
|
1576
|
+
addStatusListener(listener: StatusListener<Schemas, this>): Id;
|
|
1577
1577
|
|
|
1578
1578
|
/**
|
|
1579
1579
|
* The delListener method removes a listener that was previously added to the
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schematizers module provides utilities for converting schemas from
|
|
3
|
+
* popular validation libraries into TinyBase's schema format.
|
|
4
|
+
*
|
|
5
|
+
* Schematizers perform "best-effort" conversion, extracting basic type
|
|
6
|
+
* information (string, number, boolean) and default values while discarding
|
|
7
|
+
* complex validation rules that TinyBase doesn't support.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
* @module schematizers
|
|
10
|
+
* @since v7.1.0
|
|
11
|
+
*/
|
|
12
|
+
import type {TablesSchema, ValuesSchema} from '../store/index.d.ts';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The Schematizer interface represents a schema converter that can transform
|
|
16
|
+
* external validation library schemas into TinyBase TablesSchema and
|
|
17
|
+
* ValuesSchema formats.
|
|
18
|
+
* @category Schematizer
|
|
19
|
+
* @since v7.1.0
|
|
20
|
+
*/
|
|
21
|
+
export interface Schematizer {
|
|
22
|
+
/**
|
|
23
|
+
* The toTablesSchema method converts a mapping of external schemas into a
|
|
24
|
+
* TinyBase TablesSchema.
|
|
25
|
+
* @param schemas - A mapping of table IDs to external schema objects.
|
|
26
|
+
* @returns A TinyBase TablesSchema.
|
|
27
|
+
* @category Conversion
|
|
28
|
+
* @since v7.1.0
|
|
29
|
+
*/
|
|
30
|
+
toTablesSchema(schemas: any): TablesSchema;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The toValuesSchema method converts a mapping of external schemas into a
|
|
34
|
+
* TinyBase ValuesSchema.
|
|
35
|
+
* @param schemas - A mapping of value IDs to external schema objects.
|
|
36
|
+
* @returns A TinyBase ValuesSchema.
|
|
37
|
+
* @category Conversion
|
|
38
|
+
* @since v7.1.0
|
|
39
|
+
*/
|
|
40
|
+
toValuesSchema(schemas: any): ValuesSchema;
|
|
41
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schematizer-typebox module provides conversion utilities for TypeBox
|
|
3
|
+
* schemas.
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
* @module schematizer-typebox
|
|
6
|
+
* @since v7.1.0
|
|
7
|
+
*/
|
|
8
|
+
import type {TablesSchema, ValuesSchema} from '../../store/index.d.ts';
|
|
9
|
+
import type {Schematizer} from '../index.d.ts';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The TypeBoxSchematizer interface represents a schematizer specifically for
|
|
13
|
+
* converting TypeBox schemas into TinyBase schemas.
|
|
14
|
+
* @category Schematizer
|
|
15
|
+
* @since v7.1.0
|
|
16
|
+
*/
|
|
17
|
+
export interface TypeBoxSchematizer extends Schematizer {
|
|
18
|
+
/**
|
|
19
|
+
* The toTablesSchema method converts a mapping of TypeBox object schemas into a
|
|
20
|
+
* TinyBase TablesSchema.
|
|
21
|
+
*
|
|
22
|
+
* This method extracts basic type information (string, number, boolean),
|
|
23
|
+
* default values, and nullable flags from TypeBox schemas. Complex validation
|
|
24
|
+
* rules like min/max, patterns, formats, and custom validators are ignored.
|
|
25
|
+
* @param schemas - A mapping of table IDs to TypeBox object schemas.
|
|
26
|
+
* @returns A TinyBase TablesSchema.
|
|
27
|
+
* @example
|
|
28
|
+
* This example converts TypeBox schemas to TinyBase format.
|
|
29
|
+
*
|
|
30
|
+
* ```js
|
|
31
|
+
* import {Type} from '@sinclair/typebox';
|
|
32
|
+
* import {createStore} from 'tinybase';
|
|
33
|
+
* import {createTypeBoxSchematizer} from 'tinybase/schematizers/schematizer-typebox';
|
|
34
|
+
*
|
|
35
|
+
* const schematizer = createTypeBoxSchematizer();
|
|
36
|
+
*
|
|
37
|
+
* const tablesSchema = schematizer.toTablesSchema({
|
|
38
|
+
* pets: Type.Object({
|
|
39
|
+
* species: Type.String(),
|
|
40
|
+
* age: Type.Number(),
|
|
41
|
+
* sold: Type.Boolean({default: false}),
|
|
42
|
+
* }),
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* const store = createStore().setTablesSchema(tablesSchema);
|
|
46
|
+
* store.setRow('pets', 'fido', {species: 'dog', age: 3});
|
|
47
|
+
* console.log(store.getRow('pets', 'fido'));
|
|
48
|
+
* // -> {species: 'dog', age: 3, sold: false}
|
|
49
|
+
* ```
|
|
50
|
+
* @category Conversion
|
|
51
|
+
* @since v7.1.0
|
|
52
|
+
*/
|
|
53
|
+
toTablesSchema(schemas: {[tableId: string]: any}): TablesSchema;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The toValuesSchema method converts a mapping of TypeBox schemas into a
|
|
57
|
+
* TinyBase ValuesSchema.
|
|
58
|
+
*
|
|
59
|
+
* This method extracts basic type information (string, number, boolean),
|
|
60
|
+
* default values, and nullable flags from TypeBox schemas.
|
|
61
|
+
* @param schemas - A mapping of value IDs to TypeBox schemas.
|
|
62
|
+
* @returns A TinyBase ValuesSchema.
|
|
63
|
+
* @example
|
|
64
|
+
* This example converts TypeBox schemas to TinyBase ValuesSchema format.
|
|
65
|
+
*
|
|
66
|
+
* ```js
|
|
67
|
+
* import {Type} from '@sinclair/typebox';
|
|
68
|
+
* import {createStore} from 'tinybase';
|
|
69
|
+
* import {createTypeBoxSchematizer} from 'tinybase/schematizers/schematizer-typebox';
|
|
70
|
+
*
|
|
71
|
+
* const schematizer = createTypeBoxSchematizer();
|
|
72
|
+
*
|
|
73
|
+
* const valuesSchema = schematizer.toValuesSchema({
|
|
74
|
+
* theme: Type.String({default: 'light'}),
|
|
75
|
+
* count: Type.Number(),
|
|
76
|
+
* isOpen: Type.Boolean(),
|
|
77
|
+
* });
|
|
78
|
+
*
|
|
79
|
+
* const store = createStore().setValuesSchema(valuesSchema);
|
|
80
|
+
* store.setValue('count', 42);
|
|
81
|
+
* console.log(store.getValues());
|
|
82
|
+
* // -> {theme: 'light', count: 42}
|
|
83
|
+
* ```
|
|
84
|
+
* @category Conversion
|
|
85
|
+
* @since v7.1.0
|
|
86
|
+
*/
|
|
87
|
+
toValuesSchema(schemas: {[valueId: string]: any}): ValuesSchema;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The createTypeBoxSchematizer function creates a TypeBoxSchematizer object
|
|
92
|
+
* that can convert TypeBox schemas into TinyBase schemas.
|
|
93
|
+
*
|
|
94
|
+
* The schematizer is stateless and can be reused for multiple conversions.
|
|
95
|
+
* @returns A new TypeBoxSchematizer instance.
|
|
96
|
+
* @example
|
|
97
|
+
* This example creates a TypeBox schematizer and uses it to convert schemas.
|
|
98
|
+
*
|
|
99
|
+
* ```js
|
|
100
|
+
* import {Type} from '@sinclair/typebox';
|
|
101
|
+
* import {createTypeBoxSchematizer} from 'tinybase/schematizers/schematizer-typebox';
|
|
102
|
+
*
|
|
103
|
+
* const schematizer = createTypeBoxSchematizer();
|
|
104
|
+
*
|
|
105
|
+
* const tablesSchema = schematizer.toTablesSchema({
|
|
106
|
+
* pets: Type.Object({
|
|
107
|
+
* species: Type.String(),
|
|
108
|
+
* }),
|
|
109
|
+
* });
|
|
110
|
+
* console.log(tablesSchema);
|
|
111
|
+
* // -> {pets: {species: {type: 'string'}}}
|
|
112
|
+
* ```
|
|
113
|
+
* @category Creation
|
|
114
|
+
* @since v7.1.0
|
|
115
|
+
*/
|
|
116
|
+
export function createTypeBoxSchematizer(): TypeBoxSchematizer;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schematizer-zod module provides conversion utilities for Zod schemas.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
* @module schematizer-zod
|
|
5
|
+
* @since v7.1.0
|
|
6
|
+
*/
|
|
7
|
+
import type {TablesSchema, ValuesSchema} from '../../store/index.d.ts';
|
|
8
|
+
import type {Schematizer} from '../index.d.ts';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* The ZodSchematizer interface represents a schematizer specifically for
|
|
12
|
+
* converting Zod schemas into TinyBase schemas.
|
|
13
|
+
* @category Schematizer
|
|
14
|
+
* @since v7.1.0
|
|
15
|
+
*/
|
|
16
|
+
export interface ZodSchematizer extends Schematizer {
|
|
17
|
+
/**
|
|
18
|
+
* The toTablesSchema method converts a mapping of Zod object schemas into a
|
|
19
|
+
* TinyBase TablesSchema.
|
|
20
|
+
*
|
|
21
|
+
* This method extracts basic type information (string, number, boolean),
|
|
22
|
+
* default values, and nullable flags from Zod schemas. Complex validation
|
|
23
|
+
* rules like min/max, regex patterns, refinements, and transforms are ignored.
|
|
24
|
+
* @param schemas - A mapping of table IDs to Zod object schemas.
|
|
25
|
+
* @returns A TinyBase TablesSchema.
|
|
26
|
+
* @example
|
|
27
|
+
* This example converts Zod schemas to TinyBase format.
|
|
28
|
+
*
|
|
29
|
+
* ```js
|
|
30
|
+
* import {createStore} from 'tinybase';
|
|
31
|
+
* import {createZodSchematizer} from 'tinybase/schematizers/schematizer-zod';
|
|
32
|
+
* import {z} from 'zod';
|
|
33
|
+
*
|
|
34
|
+
* const schematizer = createZodSchematizer();
|
|
35
|
+
*
|
|
36
|
+
* const tablesSchema = schematizer.toTablesSchema({
|
|
37
|
+
* pets: z.object({
|
|
38
|
+
* species: z.string(),
|
|
39
|
+
* age: z.number(),
|
|
40
|
+
* sold: z.boolean().default(false),
|
|
41
|
+
* }),
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* const store = createStore().setTablesSchema(tablesSchema);
|
|
45
|
+
* store.setRow('pets', 'fido', {species: 'dog', age: 3});
|
|
46
|
+
* console.log(store.getRow('pets', 'fido'));
|
|
47
|
+
* // -> {species: 'dog', age: 3, sold: false}
|
|
48
|
+
* ```
|
|
49
|
+
* @category Conversion
|
|
50
|
+
* @since v7.1.0
|
|
51
|
+
*/
|
|
52
|
+
toTablesSchema(schemas: {[tableId: string]: any}): TablesSchema;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The toValuesSchema method converts a mapping of Zod schemas into a TinyBase
|
|
56
|
+
* ValuesSchema.
|
|
57
|
+
*
|
|
58
|
+
* This method extracts basic type information and default values from Zod
|
|
59
|
+
* schemas.
|
|
60
|
+
* @param schemas - A mapping of value IDs to Zod schemas.
|
|
61
|
+
* @returns A TinyBase ValuesSchema.
|
|
62
|
+
* @example
|
|
63
|
+
* This example converts Zod value schemas.
|
|
64
|
+
*
|
|
65
|
+
* ```js
|
|
66
|
+
* import {createStore} from 'tinybase';
|
|
67
|
+
* import {createZodSchematizer} from 'tinybase/schematizers/schematizer-zod';
|
|
68
|
+
* import {z} from 'zod';
|
|
69
|
+
*
|
|
70
|
+
* const schematizer = createZodSchematizer();
|
|
71
|
+
*
|
|
72
|
+
* const valuesSchema = schematizer.toValuesSchema({
|
|
73
|
+
* theme: z.string().default('light'),
|
|
74
|
+
* count: z.number(),
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* const store = createStore().setValuesSchema(valuesSchema);
|
|
78
|
+
* console.log(store.getValues());
|
|
79
|
+
* // -> {theme: 'light'}
|
|
80
|
+
* ```
|
|
81
|
+
* @category Conversion
|
|
82
|
+
* @since v7.1.0
|
|
83
|
+
*/
|
|
84
|
+
toValuesSchema(schemas: {[valueId: string]: any}): ValuesSchema;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* The createZodSchematizer function creates a ZodSchematizer object that can
|
|
89
|
+
* convert Zod schemas into TinyBase schemas.
|
|
90
|
+
*
|
|
91
|
+
* The schematizer is stateless and can be reused for multiple conversions.
|
|
92
|
+
* @returns A new ZodSchematizer instance.
|
|
93
|
+
* @example
|
|
94
|
+
* This example creates a Zod schematizer and uses it to convert schemas.
|
|
95
|
+
*
|
|
96
|
+
* ```js
|
|
97
|
+
* import {createZodSchematizer} from 'tinybase/schematizers/schematizer-zod';
|
|
98
|
+
* import {z} from 'zod';
|
|
99
|
+
*
|
|
100
|
+
* const schematizer = createZodSchematizer();
|
|
101
|
+
*
|
|
102
|
+
* const tablesSchema = schematizer.toTablesSchema({
|
|
103
|
+
* pets: z.object({
|
|
104
|
+
* species: z.string(),
|
|
105
|
+
* }),
|
|
106
|
+
* });
|
|
107
|
+
* console.log(tablesSchema);
|
|
108
|
+
* // -> {pets: {species: {type: 'string'}}}
|
|
109
|
+
* ```
|
|
110
|
+
* @category Creation
|
|
111
|
+
* @since v7.1.0
|
|
112
|
+
*/
|
|
113
|
+
export function createZodSchematizer(): ZodSchematizer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The schematizers module provides utilities for converting schemas from
|
|
3
|
+
* popular validation libraries into TinyBase's schema format.
|
|
4
|
+
*
|
|
5
|
+
* Schematizers perform "best-effort" conversion, extracting basic type
|
|
6
|
+
* information (string, number, boolean) and default values while discarding
|
|
7
|
+
* complex validation rules that TinyBase doesn't support.
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
* @module schematizers
|
|
10
|
+
* @since v7.1.0
|
|
11
|
+
*/
|
|
12
|
+
export type {Schematizer} from '../index.d.ts';
|
|
@@ -12475,7 +12475,7 @@ export function usePersisterStatus(
|
|
|
12475
12475
|
* @since v5.3.0
|
|
12476
12476
|
*/
|
|
12477
12477
|
export function usePersisterStatusListener(
|
|
12478
|
-
listener: StatusListener
|
|
12478
|
+
listener: StatusListener,
|
|
12479
12479
|
listenerDeps?: React.DependencyList,
|
|
12480
12480
|
persisterOrPersisterId?: PersisterOrPersisterId,
|
|
12481
12481
|
): void;
|
|
@@ -13053,7 +13053,7 @@ export function useSynchronizerStatus(
|
|
|
13053
13053
|
* @since v5.3.0
|
|
13054
13054
|
*/
|
|
13055
13055
|
export function useSynchronizerStatusListener(
|
|
13056
|
-
listener: StatusListener
|
|
13056
|
+
listener: StatusListener,
|
|
13057
13057
|
listenerDeps?: React.DependencyList,
|
|
13058
13058
|
synchronizerOrSynchronizerId?: SynchronizerOrSynchronizerId,
|
|
13059
13059
|
): void;
|
|
@@ -13487,7 +13487,7 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
|
|
|
13487
13487
|
*
|
|
13488
13488
|
* ```ts override
|
|
13489
13489
|
* usePersisterStatusListener(
|
|
13490
|
-
* listener: StatusListener
|
|
13490
|
+
* listener: StatusListener,
|
|
13491
13491
|
* listenerDeps?: React.DependencyList,
|
|
13492
13492
|
* persisterOrPersisterId?: PersisterOrPersisterId,
|
|
13493
13493
|
* ): void;
|
|
@@ -13553,7 +13553,7 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
|
|
|
13553
13553
|
* @since v5.3.0
|
|
13554
13554
|
*/
|
|
13555
13555
|
usePersisterStatusListener: (
|
|
13556
|
-
listener: StatusListener<Schemas
|
|
13556
|
+
listener: StatusListener<Schemas>,
|
|
13557
13557
|
listenerDeps?: React.DependencyList,
|
|
13558
13558
|
persisterOrPersisterId?: PersisterOrPersisterId<Schemas>,
|
|
13559
13559
|
) => void;
|
|
@@ -14039,7 +14039,7 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
|
|
|
14039
14039
|
*
|
|
14040
14040
|
* ```ts override
|
|
14041
14041
|
* useSynchronizerStatusListener(
|
|
14042
|
-
* listener: StatusListener
|
|
14042
|
+
* listener: StatusListener,
|
|
14043
14043
|
* listenerDeps?: React.DependencyList,
|
|
14044
14044
|
* synchronizerOrSynchronizerId?: SynchronizerOrSynchronizerId,
|
|
14045
14045
|
* ): void;
|
|
@@ -14105,7 +14105,7 @@ export type WithSchemas<Schemas extends OptionalSchemas> = {
|
|
|
14105
14105
|
* @since v5.3.0
|
|
14106
14106
|
*/
|
|
14107
14107
|
useSynchronizerStatusListener: (
|
|
14108
|
-
listener: StatusListener<Schemas
|
|
14108
|
+
listener: StatusListener<Schemas>,
|
|
14109
14109
|
listenerDeps?: React.DependencyList,
|
|
14110
14110
|
synchronizerOrSynchronizerId?: SynchronizerOrSynchronizerId<Schemas>,
|
|
14111
14111
|
) => void;
|
package/agents.md
CHANGED
|
@@ -341,3 +341,147 @@ npx vitest run ./test/unit/documentation.test.ts --retry=0
|
|
|
341
341
|
2. **Guide Content**: Edit markdown files in `/site/guides/`
|
|
342
342
|
3. **Release Notes**: Edit `/site/guides/16_releases.md` (not `/releases.md`)
|
|
343
343
|
4. **Always run documentation tests** after changes to verify examples work
|
|
344
|
+
|
|
345
|
+
## Creating New Schematizers
|
|
346
|
+
|
|
347
|
+
Schematizers convert external schema validation libraries (like Zod) to TinyBase
|
|
348
|
+
schemas. Follow this pattern:
|
|
349
|
+
|
|
350
|
+
### Module Structure
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
src/@types/schematizers/schematizer-{library}/
|
|
354
|
+
index.d.ts # Type definitions
|
|
355
|
+
docs.js # Documentation
|
|
356
|
+
with-schemas/
|
|
357
|
+
index.d.ts # Re-exports for schema-aware variants
|
|
358
|
+
src/schematizers/schematizer-{library}/
|
|
359
|
+
index.ts # Implementation
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Factory Pattern
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
export const createZodSchematizer: typeof createZodSchematizerDecl = () => {
|
|
366
|
+
const toTablesSchema = (schemas: {[tableId: string]: any}): TablesSchema => {
|
|
367
|
+
// Best-effort conversion logic
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
const toValuesSchema = (schemas: {[valueId: string]: any}): ValuesSchema => {
|
|
371
|
+
// Best-effort conversion logic
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
return objFreeze({
|
|
375
|
+
toTablesSchema,
|
|
376
|
+
toValuesSchema,
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Conversion Strategy
|
|
382
|
+
|
|
383
|
+
- Extract basic types only: `string`, `number`, `boolean`
|
|
384
|
+
- Handle defaults via schema introspection
|
|
385
|
+
- Support nullable and optional modifiers
|
|
386
|
+
- **Ignore** complex types (arrays, objects, etc.) - they won't appear in output
|
|
387
|
+
- Use recursive unwrapping for wrapper types (e.g., `ZodOptional`, `ZodNullable`,
|
|
388
|
+
`ZodDefault`)
|
|
389
|
+
|
|
390
|
+
### Implementation Idioms
|
|
391
|
+
|
|
392
|
+
- Use `objForEach` for iteration, not `for...in` loops
|
|
393
|
+
- Use `ifNotUndefined` for conditional logic
|
|
394
|
+
- Use `objIsEmpty` to filter out empty table schemas
|
|
395
|
+
- Extract string constants to module-level (e.g., `TYPE`, `DEFAULT`,
|
|
396
|
+
`ALLOW_NULL`)
|
|
397
|
+
- Freeze the returned schematizer object with `objFreeze`
|
|
398
|
+
|
|
399
|
+
### Example Conversion Logic
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
const unwrap = (
|
|
403
|
+
schema: any,
|
|
404
|
+
defaultValue?: any,
|
|
405
|
+
allowNull?: boolean,
|
|
406
|
+
): [any, any, boolean] => {
|
|
407
|
+
const typeName = schema._def?.typeName;
|
|
408
|
+
return typeName === ZOD_OPTIONAL
|
|
409
|
+
? unwrap(schema._def.innerType, defaultValue, allowNull)
|
|
410
|
+
: typeName === ZOD_NULLABLE
|
|
411
|
+
? unwrap(schema._def.innerType, defaultValue, true)
|
|
412
|
+
: typeName === ZOD_DEFAULT
|
|
413
|
+
? unwrap(schema._def.innerType, schema._def.defaultValue(), allowNull)
|
|
414
|
+
: [schema, defaultValue, allowNull ?? false];
|
|
415
|
+
};
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Build Configuration
|
|
419
|
+
|
|
420
|
+
- Add module to `ALL_MODULES` array in `gulpfile.mjs`
|
|
421
|
+
- Add peer dependency to `package.json` (marked as optional)
|
|
422
|
+
- Add as dev dependency for testing
|
|
423
|
+
|
|
424
|
+
### Testing
|
|
425
|
+
|
|
426
|
+
- Create comprehensive test suite in
|
|
427
|
+
`test/unit/schematizers/schematizer-{library}.test.ts`
|
|
428
|
+
- Test basic type conversion, defaults, nullable, optional
|
|
429
|
+
- Test unsupported types are filtered out
|
|
430
|
+
- Test integration with actual TinyBase stores
|
|
431
|
+
- Inline schemas directly in test calls (no intermediate variables unless needed
|
|
432
|
+
multiple times)
|
|
433
|
+
|
|
434
|
+
### Documentation Testing
|
|
435
|
+
|
|
436
|
+
Add library import to `test/unit/documentation.test.ts`:
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
import * as z from 'zod';
|
|
440
|
+
import * as TinyBaseSchematizersZod from 'tinybase/schematizers/schematizer-zod';
|
|
441
|
+
|
|
442
|
+
(globalThis as any).modules = {
|
|
443
|
+
...
|
|
444
|
+
'tinybase/schematizers/schematizer-zod': TinyBaseSchematizersZod,
|
|
445
|
+
zod: z,
|
|
446
|
+
};
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Guide Writing Best Practices
|
|
450
|
+
|
|
451
|
+
### Examples Run Sequentially
|
|
452
|
+
|
|
453
|
+
All code examples in a guide file are concatenated and executed as a test:
|
|
454
|
+
|
|
455
|
+
- Use unique variable names (`store`, `store2`, `store3`) to avoid redeclaration
|
|
456
|
+
- First example includes all imports, later examples reuse them
|
|
457
|
+
- Clean up between examples if needed (`store.delTables()`)
|
|
458
|
+
|
|
459
|
+
### Inline Simple Values
|
|
460
|
+
|
|
461
|
+
- Prefer inline schemas/data in method calls over intermediate variables
|
|
462
|
+
- Only extract to variables when used multiple times
|
|
463
|
+
- Keeps examples concise and focused
|
|
464
|
+
|
|
465
|
+
### Guide Chains
|
|
466
|
+
|
|
467
|
+
- Each guide's summary should link to the next guide in sequence
|
|
468
|
+
- Pattern: "For that we proceed to the [Next Topic] guide."
|
|
469
|
+
- Creates a natural learning path
|
|
470
|
+
|
|
471
|
+
## Release Notes Updates
|
|
472
|
+
|
|
473
|
+
When adding a new feature:
|
|
474
|
+
|
|
475
|
+
1. **Update `/site/guides/16_releases.md`** (NOT `/releases.md`):
|
|
476
|
+
- Add new version section at the top
|
|
477
|
+
- Include working code example that will be tested
|
|
478
|
+
- Link to relevant guide if applicable
|
|
479
|
+
- Use past releases as template for structure
|
|
480
|
+
|
|
481
|
+
2. **Update `/site/home/index.md`**:
|
|
482
|
+
- Update the "NEW!" link to point to new version:
|
|
483
|
+
`<a href='/guides/releases/#v7-1'>`
|
|
484
|
+
- Update the tagline:
|
|
485
|
+
`<span id="one-with">"The one with Schematizers!"</span>`
|
|
486
|
+
|
|
487
|
+
3. **Generated files update automatically** during build process
|
package/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const FUNCTION = getTypeOf(getTypeOf);
|
|
|
7
7
|
const TYPE = 'type';
|
|
8
8
|
const DEFAULT = 'default';
|
|
9
9
|
const ALLOW_NULL = 'allowNull';
|
|
10
|
+
const NULL = 'null';
|
|
10
11
|
const SUM = 'sum';
|
|
11
12
|
const AVG = 'avg';
|
|
12
13
|
const MIN = 'min';
|
|
@@ -94,7 +95,7 @@ const arrayShift = (array) => array.shift();
|
|
|
94
95
|
|
|
95
96
|
const getCellOrValueType = (cellOrValue) => {
|
|
96
97
|
if (isNull(cellOrValue)) {
|
|
97
|
-
return
|
|
98
|
+
return NULL;
|
|
98
99
|
}
|
|
99
100
|
const type = getTypeOf(cellOrValue);
|
|
100
101
|
return isTypeStringOrBoolean(type) ||
|
package/mergeable-store/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const FUNCTION = getTypeOf(getTypeOf);
|
|
|
7
7
|
const TYPE = 'type';
|
|
8
8
|
const DEFAULT = 'default';
|
|
9
9
|
const ALLOW_NULL = 'allowNull';
|
|
10
|
+
const NULL = 'null';
|
|
10
11
|
const LISTENER = 'Listener';
|
|
11
12
|
const SET = 'set';
|
|
12
13
|
const ADD = 'add';
|
|
@@ -63,7 +64,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
63
64
|
|
|
64
65
|
const getCellOrValueType = (cellOrValue) => {
|
|
65
66
|
if (isNull(cellOrValue)) {
|
|
66
|
-
return
|
|
67
|
+
return NULL;
|
|
67
68
|
}
|
|
68
69
|
const type = getTypeOf(cellOrValue);
|
|
69
70
|
return isTypeStringOrBoolean(type) ||
|
|
@@ -7,6 +7,7 @@ const FUNCTION = getTypeOf(getTypeOf);
|
|
|
7
7
|
const TYPE = 'type';
|
|
8
8
|
const DEFAULT = 'default';
|
|
9
9
|
const ALLOW_NULL = 'allowNull';
|
|
10
|
+
const NULL = 'null';
|
|
10
11
|
const LISTENER = 'Listener';
|
|
11
12
|
const SET = 'set';
|
|
12
13
|
const ADD = 'add';
|
|
@@ -63,7 +64,7 @@ const tryCatch = async (action, then1, then2) => {
|
|
|
63
64
|
|
|
64
65
|
const getCellOrValueType = (cellOrValue) => {
|
|
65
66
|
if (isNull(cellOrValue)) {
|
|
66
|
-
return
|
|
67
|
+
return NULL;
|
|
67
68
|
}
|
|
68
69
|
const type = getTypeOf(cellOrValue);
|
|
69
70
|
return isTypeStringOrBoolean(type) ||
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=t=>typeof t,e=t(""),r=t(!0),n=t(0),o="type",s="default",c="null",l=t=>(e,r,n)=>t(e)?n?.():r(e),u=t=>null==t,f=l(u),p=l(t=>void 0===t),a=Object,y=t=>a.getPrototypeOf(t),i=a.entries,h=a.keys,m=a.freeze,d=(t=[])=>a.fromEntries(t),O=(t,e)=>((t,e)=>t.forEach(e))(i(t),([t,r])=>e(r,t)),b="anyOf",g=(t,e,r)=>{if(t?.[b]){const r=t[b],n=r.some(t=>t?.type===c),o=r.find(t=>t?.type!==c);if(n&&o)return g(o,e??t?.[s],!0)}return[t,e??t?.[s],r??!1]},v=()=>{const t=t=>{const[c,l,u]=g(t),f=c?.type;if(f!==e&&f!==n&&f!==r)return;const a={[o]:f};return p(l,t=>{a[s]=t}),u&&(a.allowNull=!0),a};return m({toTablesSchema:e=>{const r=d();return O(e,(e,n)=>{const o=d();var s;p(e?.properties,e=>O(e,(e,r)=>p(t(e),t=>{o[r]=t}))),(t=>!u(t)&&f(y(t),t=>t==a.prototype||u(y(t)),()=>!0))(s=o)&&0==(t=>h(t).length)(s)||(r[n]=o)}),r},toValuesSchema:e=>{const r=d();return O(e,(e,n)=>p(t(e),t=>{r[n]=t})),r}})};export{v as createTypeBoxSchematizer};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t=t=>typeof t,e=t(""),r=t(!0),n=t(0),o="type",s="default",c="null",l=t=>(e,r,n)=>t(e)?n?.():r(e),u=t=>null==t,f=l(u),p=l(t=>void 0===t),a=Object,y=t=>a.getPrototypeOf(t),i=a.entries,h=a.keys,m=a.freeze,d=(t=[])=>a.fromEntries(t),O=(t,e)=>((t,e)=>t.forEach(e))(i(t),([t,r])=>e(r,t)),b="anyOf",g=(t,e,r)=>{if(t?.[b]){const r=t[b],n=r.some(t=>t?.type===c),o=r.find(t=>t?.type!==c);if(n&&o)return g(o,e??t?.[s],!0)}return[t,e??t?.[s],r??!1]},v=()=>{const t=t=>{const[c,l,u]=g(t),f=c?.type;if(f!==e&&f!==n&&f!==r)return;const a={[o]:f};return p(l,t=>{a[s]=t}),u&&(a.allowNull=!0),a};return m({toTablesSchema:e=>{const r=d();return O(e,(e,n)=>{const o=d();var s;p(e?.properties,e=>O(e,(e,r)=>p(t(e),t=>{o[r]=t}))),(t=>!u(t)&&f(y(t),t=>t==a.prototype||u(y(t)),()=>!0))(s=o)&&0==(t=>h(t).length)(s)||(r[n]=o)}),r},toValuesSchema:e=>{const r=d();return O(e,(e,n)=>p(t(e),t=>{r[n]=t})),r}})};export{v as createTypeBoxSchematizer};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=e=>typeof e,t=e(""),n=e(!0),r=e(0),o="type",l="default",f=e=>(t,n,r)=>e(t)?r?.():n(t),s=e=>null==e,a=f(s),p=f(e=>void 0===e),u=Object,c=e=>u.getPrototypeOf(e),y=u.entries,d=u.keys,i=u.freeze,h=(e=[])=>u.fromEntries(e),T=(e,t)=>((e,t)=>e.forEach(t))(y(e),([e,n])=>t(n,e)),b=(e,t,n)=>{const r=e?.def?.type;return"optional"===r?b(e.def.innerType,t,n):"nullable"===r?b(e.def.innerType,t,!0):r===l?b(e.def.innerType,e.def.defaultValue,n):[e,t,n??!1]},m=()=>{const e=e=>{const[f,s,a]=b(e),u=f?.type;if(u!==t&&u!==r&&u!==n)return;const c={[o]:u};return p(s,e=>{c[l]=e}),a&&(c.allowNull=!0),c};return i({toTablesSchema:t=>{const n=h();return T(t,(t,r)=>{const o=h();var l;p(t?.def?.shape,t=>T(t,(t,n)=>p(e(t),e=>{o[n]=e}))),(e=>!s(e)&&a(c(e),e=>e==u.prototype||s(c(e)),()=>!0))(l=o)&&0==(e=>d(e).length)(l)||(n[r]=o)}),n},toValuesSchema:t=>{const n=h();return T(t,(t,r)=>p(e(t),e=>{n[r]=e})),n}})};export{m as createZodSchematizer};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=e=>typeof e,t=e(""),n=e(!0),r=e(0),o="type",l="default",f=e=>(t,n,r)=>e(t)?r?.():n(t),s=e=>null==e,a=f(s),p=f(e=>void 0===e),u=Object,c=e=>u.getPrototypeOf(e),y=u.entries,d=u.keys,i=u.freeze,h=(e=[])=>u.fromEntries(e),T=(e,t)=>((e,t)=>e.forEach(t))(y(e),([e,n])=>t(n,e)),b=(e,t,n)=>{const r=e?.def?.type;return"optional"===r?b(e.def.innerType,t,n):"nullable"===r?b(e.def.innerType,t,!0):r===l?b(e.def.innerType,e.def.defaultValue,n):[e,t,n??!1]},m=()=>{const e=e=>{const[f,s,a]=b(e),u=f?.type;if(u!==t&&u!==r&&u!==n)return;const c={[o]:u};return p(s,e=>{c[l]=e}),a&&(c.allowNull=!0),c};return i({toTablesSchema:t=>{const n=h();return T(t,(t,r)=>{const o=h();var l;p(t?.def?.shape,t=>T(t,(t,n)=>p(e(t),e=>{o[n]=e}))),(e=>!s(e)&&a(c(e),e=>e==u.prototype||s(c(e)),()=>!0))(l=o)&&0==(e=>d(e).length)(l)||(n[r]=o)}),n},toValuesSchema:t=>{const n=h();return T(t,(t,r)=>p(e(t),e=>{n[r]=e})),n}})};export{m as createZodSchematizer};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
Binary file
|