tinybase 2.1.1 → 2.2.0-beta.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.
Files changed (114) hide show
  1. package/bin/cli.js +2 -0
  2. package/lib/checkpoints.d.ts +0 -2
  3. package/lib/checkpoints.js +1 -1
  4. package/lib/checkpoints.js.gz +0 -0
  5. package/lib/debug/checkpoints.d.ts +0 -2
  6. package/lib/debug/checkpoints.js +4 -2
  7. package/lib/debug/indexes.d.ts +0 -2
  8. package/lib/debug/indexes.js +2 -1
  9. package/lib/debug/metrics.d.ts +0 -2
  10. package/lib/debug/metrics.js +2 -1
  11. package/lib/debug/queries.d.ts +0 -2
  12. package/lib/debug/queries.js +4 -3
  13. package/lib/debug/relationships.d.ts +0 -2
  14. package/lib/debug/relationships.js +2 -1
  15. package/lib/debug/store.d.ts +1 -1
  16. package/lib/debug/store.js +15 -17
  17. package/lib/debug/tinybase.js +18 -19
  18. package/lib/debug/tools.d.ts +440 -0
  19. package/lib/debug/tools.js +1012 -0
  20. package/lib/es6/checkpoints.d.ts +0 -2
  21. package/lib/es6/checkpoints.js +1 -1
  22. package/lib/es6/checkpoints.js.gz +0 -0
  23. package/lib/es6/indexes.d.ts +0 -2
  24. package/lib/es6/indexes.js +1 -1
  25. package/lib/es6/indexes.js.gz +0 -0
  26. package/lib/es6/metrics.d.ts +0 -2
  27. package/lib/es6/metrics.js +1 -1
  28. package/lib/es6/metrics.js.gz +0 -0
  29. package/lib/es6/queries.d.ts +0 -2
  30. package/lib/es6/queries.js +1 -1
  31. package/lib/es6/queries.js.gz +0 -0
  32. package/lib/es6/relationships.d.ts +0 -2
  33. package/lib/es6/relationships.js +1 -1
  34. package/lib/es6/relationships.js.gz +0 -0
  35. package/lib/es6/store.d.ts +1 -1
  36. package/lib/es6/store.js +1 -1
  37. package/lib/es6/store.js.gz +0 -0
  38. package/lib/es6/tinybase.js +1 -1
  39. package/lib/es6/tinybase.js.gz +0 -0
  40. package/lib/es6/tools.d.ts +440 -0
  41. package/lib/es6/tools.js +1 -0
  42. package/lib/es6/tools.js.gz +0 -0
  43. package/lib/es6/ui-react.js +1 -1
  44. package/lib/es6/ui-react.js.gz +0 -0
  45. package/lib/indexes.d.ts +0 -2
  46. package/lib/indexes.js +1 -1
  47. package/lib/indexes.js.gz +0 -0
  48. package/lib/metrics.d.ts +0 -2
  49. package/lib/metrics.js +1 -1
  50. package/lib/metrics.js.gz +0 -0
  51. package/lib/queries.d.ts +0 -2
  52. package/lib/queries.js +1 -1
  53. package/lib/queries.js.gz +0 -0
  54. package/lib/relationships.d.ts +0 -2
  55. package/lib/relationships.js +1 -1
  56. package/lib/relationships.js.gz +0 -0
  57. package/lib/store.d.ts +1 -1
  58. package/lib/store.js +1 -1
  59. package/lib/store.js.gz +0 -0
  60. package/lib/tinybase.js +1 -1
  61. package/lib/tinybase.js.gz +0 -0
  62. package/lib/tools.d.ts +440 -0
  63. package/lib/tools.js +1 -0
  64. package/lib/tools.js.gz +0 -0
  65. package/lib/umd/checkpoints.d.ts +0 -2
  66. package/lib/umd/checkpoints.js +1 -1
  67. package/lib/umd/checkpoints.js.gz +0 -0
  68. package/lib/umd/indexes.d.ts +0 -2
  69. package/lib/umd/indexes.js +1 -1
  70. package/lib/umd/indexes.js.gz +0 -0
  71. package/lib/umd/metrics.d.ts +0 -2
  72. package/lib/umd/metrics.js +1 -1
  73. package/lib/umd/metrics.js.gz +0 -0
  74. package/lib/umd/queries.d.ts +0 -2
  75. package/lib/umd/queries.js +1 -1
  76. package/lib/umd/queries.js.gz +0 -0
  77. package/lib/umd/relationships.d.ts +0 -2
  78. package/lib/umd/relationships.js +1 -1
  79. package/lib/umd/relationships.js.gz +0 -0
  80. package/lib/umd/store.d.ts +1 -1
  81. package/lib/umd/store.js +1 -1
  82. package/lib/umd/store.js.gz +0 -0
  83. package/lib/umd/tinybase.js +1 -1
  84. package/lib/umd/tinybase.js.gz +0 -0
  85. package/lib/umd/tools.d.ts +440 -0
  86. package/lib/umd/tools.js +1 -0
  87. package/lib/umd/tools.js.gz +0 -0
  88. package/lib/umd-es6/checkpoints.d.ts +0 -2
  89. package/lib/umd-es6/checkpoints.js +1 -1
  90. package/lib/umd-es6/checkpoints.js.gz +0 -0
  91. package/lib/umd-es6/indexes.d.ts +0 -2
  92. package/lib/umd-es6/indexes.js +1 -1
  93. package/lib/umd-es6/indexes.js.gz +0 -0
  94. package/lib/umd-es6/metrics.d.ts +0 -2
  95. package/lib/umd-es6/metrics.js +1 -1
  96. package/lib/umd-es6/metrics.js.gz +0 -0
  97. package/lib/umd-es6/queries.d.ts +0 -2
  98. package/lib/umd-es6/queries.js +1 -1
  99. package/lib/umd-es6/queries.js.gz +0 -0
  100. package/lib/umd-es6/relationships.d.ts +0 -2
  101. package/lib/umd-es6/relationships.js +1 -1
  102. package/lib/umd-es6/relationships.js.gz +0 -0
  103. package/lib/umd-es6/store.d.ts +1 -1
  104. package/lib/umd-es6/store.js +1 -1
  105. package/lib/umd-es6/store.js.gz +0 -0
  106. package/lib/umd-es6/tinybase.js +1 -1
  107. package/lib/umd-es6/tinybase.js.gz +0 -0
  108. package/lib/umd-es6/tools.d.ts +440 -0
  109. package/lib/umd-es6/tools.js +1 -0
  110. package/lib/umd-es6/tools.js.gz +0 -0
  111. package/lib/umd-es6/ui-react.js +1 -1
  112. package/lib/umd-es6/ui-react.js.gz +0 -0
  113. package/package.json +27 -17
  114. package/readme.md +31 -12
@@ -0,0 +1,1012 @@
1
+ const getTypeOf = (thing) => typeof thing;
2
+ const EMPTY_STRING = '';
3
+ const STRING = getTypeOf(EMPTY_STRING);
4
+ const BOOLEAN = getTypeOf(true);
5
+ const NUMBER = getTypeOf(0);
6
+ const TYPE = 'type';
7
+ const DEFAULT = 'default';
8
+
9
+ const arrayEvery = (array, cb) => array.every(cb);
10
+ const arraySort = (array, sorter) => array.sort(sorter);
11
+ const arrayForEach = (array, cb) => array.forEach(cb);
12
+ const arrayMap = (array, cb) => array.map(cb);
13
+ const arrayLength = (array) => array.length;
14
+ const arrayIsEmpty = (array) => arrayLength(array) == 0;
15
+ const arrayPush = (array, ...values) => array.push(...values);
16
+ const arrayPop = (array) => array.pop();
17
+ const arrayUnshift = (array, ...values) => array.unshift(...values);
18
+ const arrayShift = (array) => array.shift();
19
+
20
+ const jsonParse = JSON.parse;
21
+ const isFiniteNumber = isFinite;
22
+ const isUndefined = (thing) => thing == void 0;
23
+ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
24
+ const isString = (thing) => getTypeOf(thing) == STRING;
25
+ const isArray = (thing) => Array.isArray(thing);
26
+
27
+ const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
28
+ const collValues = (coll) => [...(coll?.values() ?? [])];
29
+ const collForEach = (coll, cb) => coll?.forEach(cb);
30
+ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
31
+
32
+ const mapNew = (entries) => new Map(entries);
33
+ const mapGet = (map, key) => map?.get(key);
34
+ const mapForEach = (map, cb) =>
35
+ collForEach(map, (value, key) => cb(key, value));
36
+ const mapMap = (coll, cb) =>
37
+ arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
38
+ const mapSet = (map, key, value) =>
39
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
40
+ const mapEnsure = (map, key, getDefaultValue) => {
41
+ if (!collHas(map, key)) {
42
+ mapSet(map, key, getDefaultValue());
43
+ }
44
+ return mapGet(map, key);
45
+ };
46
+
47
+ const setNew = (entryOrEntries) =>
48
+ new Set(
49
+ isArray(entryOrEntries) || isUndefined(entryOrEntries)
50
+ ? entryOrEntries
51
+ : [entryOrEntries],
52
+ );
53
+ const setAdd = (set, value) => set?.add(value);
54
+
55
+ const pairNew = (value) => [value, value];
56
+ const pairNewMap = () => [mapNew(), mapNew()];
57
+
58
+ const NON_ALPHANUMERIC = /[^A-Za-z0-9]+/;
59
+ const JSDOC = /^( *)\/\*\* *(.*?) *\*\/$/gm;
60
+ const substr = (str, start, end) => str.substring(start, end);
61
+ const upper = (str) => str.toUpperCase();
62
+ const lower = (str) => str.toLowerCase();
63
+ const mapUnique = (map, id, value, index = 1) => {
64
+ const uniqueId = `${id}${index == 1 ? '' : index}`;
65
+ if (collHas(map, uniqueId)) {
66
+ return mapUnique(map, id, value, index + 1);
67
+ } else {
68
+ mapSet(map, uniqueId, value);
69
+ return uniqueId;
70
+ }
71
+ };
72
+ const formatJsDoc = (file) =>
73
+ file.replace(JSDOC, (_, indent, text) => {
74
+ const lineLength = 77 - length(indent);
75
+ return `${indent}/**
76
+ ${text.replace(
77
+ new RegExp(`([^\\n]{1,${lineLength}})(\\s|$)`, 'g'),
78
+ `${indent} * $1
79
+ `,
80
+ )}${indent} */`;
81
+ });
82
+ const length = (str) => str.length;
83
+ const join = (array, sep = EMPTY_STRING) => array.join(sep);
84
+ const flat = (array) => array.flat(1e3);
85
+ const camel = (str, firstCap = 0) =>
86
+ join(
87
+ arrayMap(
88
+ str.split(NON_ALPHANUMERIC),
89
+ (word, w) =>
90
+ (w > 0 || firstCap ? upper : lower)(substr(word, 0, 1)) +
91
+ substr(word, 1),
92
+ ),
93
+ );
94
+ const snake = (str) => upper(join(str.split(NON_ALPHANUMERIC), '_'));
95
+ const comment = (doc) => `/** ${doc}. */`;
96
+ const getCodeFunctions = () => {
97
+ const allImports = pairNewMap();
98
+ const types = mapNew();
99
+ const methods = mapNew();
100
+ const constants = mapNew();
101
+ const build = (...lines) => join(flat(lines), '\n');
102
+ const addImport = (location, source, ...items) =>
103
+ arrayForEach(items, (item) =>
104
+ setAdd(mapEnsure(allImports[location], source, setNew), item),
105
+ );
106
+ const addType = (name, body = '', doc = '') =>
107
+ mapUnique(types, name, [body, doc]);
108
+ const addMethod = (name, parameters, returnType, body, doc, generic = '') =>
109
+ mapUnique(methods, name, [parameters, returnType, body, doc, generic]);
110
+ const addFunction = (name, parameters, body) =>
111
+ mapUnique(
112
+ constants,
113
+ name,
114
+ isArray(body)
115
+ ? [`(${parameters}) => {`, body, '}']
116
+ : [`(${parameters}) => ${body}`],
117
+ );
118
+ const addConstant = (name, body) =>
119
+ mapGet(constants, name) === body ? name : mapUnique(constants, name, body);
120
+ const getImports = (location) => [
121
+ ...arraySort(
122
+ mapMap(
123
+ allImports[location],
124
+ (items, source) =>
125
+ `import {${join(
126
+ arraySort(collValues(items)),
127
+ ', ',
128
+ )}} from '${source}';`,
129
+ ),
130
+ ),
131
+ EMPTY_STRING,
132
+ ];
133
+ const getTypes = () =>
134
+ mapMap(types, ([body, doc], name) => [
135
+ comment(doc),
136
+ `export type ${name} = ${body};`,
137
+ EMPTY_STRING,
138
+ ]);
139
+ const getMethods = (location) =>
140
+ mapMap(methods, ([parameters, returnType, body, doc, generic], name) => {
141
+ const lines = location
142
+ ? [`${name}: ${generic}(${parameters}): ${returnType} => ${body},`]
143
+ : [`${name}${generic}(${parameters}): ${returnType};`];
144
+ if (!location) {
145
+ arrayUnshift(lines, comment(doc));
146
+ }
147
+ arrayPush(lines, EMPTY_STRING);
148
+ return lines;
149
+ });
150
+ const getConstants = () =>
151
+ mapMap(constants, (body, name) => {
152
+ body = isArray(body) ? body : [body];
153
+ arrayPush(body, `${arrayPop(body)};`);
154
+ return [`const ${name} = ${arrayShift(body)}`, body, EMPTY_STRING];
155
+ });
156
+ return [
157
+ build,
158
+ addImport,
159
+ addType,
160
+ addMethod,
161
+ addFunction,
162
+ addConstant,
163
+ getImports,
164
+ getTypes,
165
+ getMethods,
166
+ getConstants,
167
+ ];
168
+ };
169
+
170
+ const object = Object;
171
+ const objIds = object.keys;
172
+ const objFreeze = object.freeze;
173
+ const objMap = (obj, cb) =>
174
+ arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
175
+ const objIsEmpty = (obj) => arrayIsEmpty(objIds(obj));
176
+
177
+ const getCellType = (cell) => {
178
+ const type = getTypeOf(cell);
179
+ return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
180
+ ? type
181
+ : void 0;
182
+ };
183
+
184
+ const getCreateFunction = (getFunction) => {
185
+ const getFunctionsByStore = /* @__PURE__ */ new WeakMap();
186
+ return (store) => {
187
+ if (!getFunctionsByStore.has(store)) {
188
+ getFunctionsByStore.set(store, getFunction(store));
189
+ }
190
+ return getFunctionsByStore.get(store);
191
+ };
192
+ };
193
+
194
+ const THE_CONTENT_OF = 'the content of';
195
+ const THE_STORE = 'the Store';
196
+ const A_FUNCTION_FOR = 'A function for';
197
+ const EXPORT = 'export';
198
+ const LISTENER = 'listener';
199
+ const OR_UNDEFINED = ' | undefined';
200
+ const REGISTERS_A_LISTENER = `Registers a ${LISTENER} that will be called`;
201
+ const REPRESENTS = 'Represents';
202
+ const RETURNS_VOID = ' => void';
203
+ const THE_CONTENT_OF_THE_STORE = `${THE_CONTENT_OF} ${THE_STORE}`;
204
+ const THE_END_OF_THE_TRANSACTION = 'the end of the transaction';
205
+ const THE_SPECIFIED_ROW = 'the specified Row';
206
+ const getRowTypeDoc = (tableId, set = 0) =>
207
+ `${REPRESENTS} a Row when ${
208
+ set ? 's' : 'g'
209
+ }etting ${THE_CONTENT_OF} the '${tableId}' Table`;
210
+ const getIdsDoc = (idsNoun, parentNoun, sorted = 0) =>
211
+ `Gets ${
212
+ sorted ? 'sorted, paginated' : 'the'
213
+ } Ids of the ${idsNoun}s in ${parentNoun}`;
214
+ const getForEachDoc = (childNoun, parentNoun) =>
215
+ `Calls a function for each ${childNoun} in ${parentNoun}`;
216
+ const getHasDoc = (childNoun, parentNoun = THE_STORE) =>
217
+ `Gets whether ${childNoun} exists in ${parentNoun}`;
218
+ const getCallbackDoc = (takes) => `A function that takes ${takes}`;
219
+ const getListenerTypeDoc = (childNoun = 0, parentNoun = 0) =>
220
+ `${A_FUNCTION_FOR} listening to changes to ${nouns[childNoun]} in ${nouns[parentNoun]}`;
221
+ const getListenerDoc = (childNoun, parentNoun, pluralChild = 0) =>
222
+ `${REGISTERS_A_LISTENER} whenever ${childNoun} in ${parentNoun} change` +
223
+ (pluralChild ? '' : 's');
224
+ const getStoreContentDoc = (verb = 0) =>
225
+ `${verbs[verb]} ${THE_CONTENT_OF_THE_STORE}`;
226
+ const getTableDoc = (tableId) => `the '${tableId}' Table`;
227
+ const getRowDoc = (tableId) =>
228
+ `${THE_SPECIFIED_ROW} in ${getTableDoc(tableId)}`;
229
+ const getCellDoc = (cellId) => `the '${cellId}' Cell`;
230
+ const getTableContentDoc = (tableId, verb = 0) =>
231
+ `${verbs[verb]} ${THE_CONTENT_OF} ${getTableDoc(tableId)}`;
232
+ const getRowContentDoc = (tableId, verb = 0) =>
233
+ `${verbs[verb]} ${THE_CONTENT_OF} ${getRowDoc(tableId)}`;
234
+ const getCellContentDoc = (tableId, cellId, verb = 0) =>
235
+ `${verbs[verb]} ${getCellDoc(cellId)} for ${getRowDoc(tableId)}`;
236
+ const verbs = ['Gets', 'Sets', 'Sets part of', 'Deletes'];
237
+ const nouns = [
238
+ THE_STORE,
239
+ 'anything',
240
+ 'Table Ids',
241
+ 'a Table',
242
+ 'Row Ids',
243
+ 'a Row',
244
+ 'Cell Ids',
245
+ 'a Cell',
246
+ 'invalid Cell changes',
247
+ ];
248
+
249
+ const COMMON_IMPORTS = [
250
+ 'ChangedCells',
251
+ 'Id',
252
+ 'IdOrNull',
253
+ 'Ids',
254
+ 'InvalidCells',
255
+ 'Json',
256
+ 'Store',
257
+ ];
258
+ const storeMethod = (method, parameters = EMPTY_STRING, cast = EMPTY_STRING) =>
259
+ `store.${method}(${parameters})${cast ? ` as ${cast}` : EMPTY_STRING}`;
260
+ const fluentStoreMethod = (method, parameters = EMPTY_STRING) =>
261
+ `fluent(() => ${storeMethod(method, parameters)})`;
262
+ const storeListener = (
263
+ method,
264
+ beforeParameters = EMPTY_STRING,
265
+ afterParameters = EMPTY_STRING,
266
+ ) =>
267
+ `store.${method}(${
268
+ beforeParameters ? `${beforeParameters}, ` : EMPTY_STRING
269
+ }proxy(${LISTENER})${
270
+ afterParameters ? `, ${afterParameters}` : EMPTY_STRING
271
+ })`;
272
+ const getStoreApi = (schema, module) => {
273
+ if (objIsEmpty(schema)) {
274
+ return pairNew(EMPTY_STRING);
275
+ }
276
+ const [
277
+ build,
278
+ addImport,
279
+ addType,
280
+ addMethod,
281
+ addFunction,
282
+ addConstant,
283
+ getImports,
284
+ getTypes,
285
+ getMethods,
286
+ getConstants,
287
+ ] = getCodeFunctions();
288
+ const moduleDefinition = `./${camel(module)}.d`;
289
+ const storeType = camel(module, 1);
290
+ const storeInstance = camel(storeType);
291
+ const tableTypes = mapNew();
292
+ const mapTableSchema = (callback) =>
293
+ objMap(schema, (_, tableId) => {
294
+ return callback(
295
+ tableId,
296
+ mapEnsure(tableTypes, tableId, () => {
297
+ const table = camel(tableId, 1);
298
+ return [
299
+ addType(
300
+ `${table}Table`,
301
+ `{[rowId: Id]: ${table}Row}`,
302
+ `${REPRESENTS} the '${tableId}' Table`,
303
+ ),
304
+ addType(
305
+ `${table}Row`,
306
+ `{${join(
307
+ mapCellSchema(
308
+ tableId,
309
+ (cellId, type, defaultValue) =>
310
+ `'${cellId}'${
311
+ isUndefined(defaultValue) ? '?' : EMPTY_STRING
312
+ }: ${type};`,
313
+ ),
314
+ ' ',
315
+ )}}`,
316
+ getRowTypeDoc(tableId),
317
+ ),
318
+ addType(
319
+ `${table}RowWhenSet`,
320
+ `{${join(
321
+ mapCellSchema(
322
+ tableId,
323
+ (cellId, type) => `'${cellId}'?: ${type};`,
324
+ ),
325
+ ' ',
326
+ )}}`,
327
+ getRowTypeDoc(tableId, 1),
328
+ ),
329
+ addType(
330
+ `${table}CellId`,
331
+ join(
332
+ mapCellSchema(tableId, (cellId) => `'${cellId}'`),
333
+ ' | ',
334
+ ),
335
+ `A Cell Id for the '${tableId}' Table`,
336
+ ),
337
+ addType(
338
+ `${table}CellCallback`,
339
+ `(...[cellId, cell]: ${join(
340
+ mapCellSchema(
341
+ tableId,
342
+ (cellId, type) => `[cellId: '${cellId}', cell: ${type}]`,
343
+ ),
344
+ ' | ',
345
+ )})${RETURNS_VOID}`,
346
+ getCallbackDoc(
347
+ `a Cell Id and value from a Row in the '${tableId}' Table`,
348
+ ),
349
+ ),
350
+ addType(
351
+ `${table}RowCallback`,
352
+ `(rowId: Id, forEachCell: (cellCallback: ${table}CellCallback)${RETURNS_VOID})${RETURNS_VOID}`,
353
+ getCallbackDoc(
354
+ `a Row Id from the '${tableId}' Table, and a Cell iterator`,
355
+ ),
356
+ ),
357
+ ];
358
+ }),
359
+ camel(tableId, 1),
360
+ addConstant(snake(tableId), `'${tableId}'`),
361
+ );
362
+ });
363
+ const mapCellSchema = (tableId, callback) =>
364
+ objMap(schema[tableId], (cellSchema, cellId) =>
365
+ callback(
366
+ cellId,
367
+ cellSchema[TYPE],
368
+ cellSchema[DEFAULT],
369
+ addConstant(snake(cellId), `'${cellId}'`),
370
+ camel(cellId, 1),
371
+ ),
372
+ );
373
+ const tablesType = addType(
374
+ 'Tables',
375
+ `{${join(
376
+ mapTableSchema(
377
+ (tableId, tableTypes2) => `'${tableId}'?: ${tableTypes2[0]};`,
378
+ ),
379
+ ' ',
380
+ )}}`,
381
+ `${REPRESENTS} ${THE_CONTENT_OF_THE_STORE}`,
382
+ );
383
+ const tableIdType = addType(
384
+ 'TableId',
385
+ join(
386
+ mapTableSchema((tableId) => `'${tableId}'`),
387
+ ' | ',
388
+ ),
389
+ `A Table Id in ${THE_STORE}`,
390
+ );
391
+ const tableCallbackType = addType(
392
+ 'TableCallback',
393
+ `(...[tableId, rowCallback]: ${join(
394
+ mapTableSchema(
395
+ (tableId, tableTypes2) =>
396
+ `[tableId: '${tableId}', forEachRow: (rowCallback: ${tableTypes2[5]})${RETURNS_VOID}]`,
397
+ ),
398
+ ' | ',
399
+ )})${RETURNS_VOID}`,
400
+ getCallbackDoc('a Table Id, and a Row iterator'),
401
+ );
402
+ const getCellChangeType = addType(
403
+ 'GetCellChange',
404
+ `(...[tableId, rowId, cellId]: ${join(
405
+ mapTableSchema(
406
+ (tableId, tableTypes2) =>
407
+ `[tableId: '${tableId}', rowId: Id, cellId: ${tableTypes2[3]}]`,
408
+ ),
409
+ ' | ',
410
+ )}) => CellChange`,
411
+ `${A_FUNCTION_FOR} returning information about any Cell's changes during a transaction`,
412
+ );
413
+ const tablesListenerType = addType(
414
+ 'TablesListener',
415
+ `(${storeInstance}: ${storeType}, getCellChange: ${getCellChangeType}${OR_UNDEFINED})${RETURNS_VOID}`,
416
+ getListenerTypeDoc(1),
417
+ );
418
+ const tableIdsListenerType = addType(
419
+ 'TableIdsListener',
420
+ `(${storeInstance}: ${storeType})${RETURNS_VOID}`,
421
+ getListenerTypeDoc(2),
422
+ );
423
+ const tableListenerType = addType(
424
+ 'TableListener',
425
+ `(${storeInstance}: ${storeType}, tableId: ${tableIdType}, getCellChange: ${getCellChangeType}${OR_UNDEFINED})${RETURNS_VOID}`,
426
+ getListenerTypeDoc(3),
427
+ );
428
+ const rowIdsListenerType = addType(
429
+ 'RowIdsListener',
430
+ `(${storeInstance}: ${storeType}, tableId: ${tableIdType})${RETURNS_VOID}`,
431
+ getListenerTypeDoc(4, 3),
432
+ );
433
+ const rowListenerType = addType(
434
+ 'RowListener',
435
+ `(${storeInstance}: ${storeType}, tableId: ${tableIdType}, rowId: Id, getCellChange: ${getCellChangeType}${OR_UNDEFINED})${RETURNS_VOID}`,
436
+ getListenerTypeDoc(5, 3),
437
+ );
438
+ const cellIdsListenerType = addType(
439
+ 'CellIdsListener',
440
+ `(${storeInstance}: ${storeType}, tableId: ${tableIdType}, rowId: Id)` +
441
+ RETURNS_VOID,
442
+ getListenerTypeDoc(6, 5),
443
+ );
444
+ const cellListenerType = addType(
445
+ 'CellListener',
446
+ `(...[${storeInstance}, tableId, rowId, cellId, newCell, oldCell, getCellChange]: ${join(
447
+ flat(
448
+ mapTableSchema((tableId) =>
449
+ mapCellSchema(
450
+ tableId,
451
+ (cellId, type) =>
452
+ `[${storeInstance}: ${storeType}, tableId: '${tableId}', rowId: Id, cellId: '${cellId}', newCell: ${type}${OR_UNDEFINED}, oldCell: ${type}${OR_UNDEFINED}, getCellChange: ${getCellChangeType} | undefined]`,
453
+ ),
454
+ ),
455
+ ),
456
+ ' | ',
457
+ )})${RETURNS_VOID}`,
458
+ getListenerTypeDoc(7, 5),
459
+ );
460
+ const invalidCellListenerType = addType(
461
+ 'InvalidCellListener',
462
+ `(${storeInstance}: ${storeType}, tableId: Id, rowId: Id, cellId: Id, invalidCells: any[])${RETURNS_VOID};`,
463
+ getListenerTypeDoc(8),
464
+ );
465
+ const transactionListenerType = addType(
466
+ 'TransactionListener',
467
+ `(${storeInstance}: ${storeType}, cellsTouched: boolean)${RETURNS_VOID};`,
468
+ `${A_FUNCTION_FOR} listening to the completion of a transaction`,
469
+ );
470
+ addMethod(
471
+ `hasTables`,
472
+ EMPTY_STRING,
473
+ BOOLEAN,
474
+ storeMethod('hasTables'),
475
+ getHasDoc('any Table'),
476
+ );
477
+ addMethod(
478
+ `getTables`,
479
+ EMPTY_STRING,
480
+ tablesType,
481
+ storeMethod('getTables'),
482
+ getStoreContentDoc(),
483
+ );
484
+ addMethod(
485
+ `setTables`,
486
+ `tables: ${tablesType}`,
487
+ storeType,
488
+ fluentStoreMethod('setTables', 'tables'),
489
+ getStoreContentDoc(1),
490
+ );
491
+ addMethod(
492
+ `delTables`,
493
+ EMPTY_STRING,
494
+ storeType,
495
+ fluentStoreMethod('delTables'),
496
+ getStoreContentDoc(3),
497
+ );
498
+ addMethod(
499
+ `getTableIds`,
500
+ EMPTY_STRING,
501
+ `${tableIdType}[]`,
502
+ storeMethod('getTableIds', EMPTY_STRING, `${tableIdType}[]`),
503
+ getIdsDoc('Table', THE_STORE),
504
+ );
505
+ addMethod(
506
+ 'forEachTable',
507
+ `tableCallback: ${tableCallbackType}`,
508
+ 'void',
509
+ storeMethod('forEachTable', 'tableCallback as any'),
510
+ getForEachDoc('Table', THE_STORE),
511
+ );
512
+ const mapCellTypes = mapNew();
513
+ mapTableSchema(
514
+ (
515
+ tableId,
516
+ [
517
+ tableType,
518
+ rowType,
519
+ rowWhenSetType,
520
+ cellIdType,
521
+ cellCallbackType,
522
+ rowCallbackType,
523
+ ],
524
+ tableName,
525
+ TABLE_ID,
526
+ ) => {
527
+ addImport(
528
+ 1,
529
+ moduleDefinition,
530
+ tableType,
531
+ rowType,
532
+ rowWhenSetType,
533
+ cellIdType,
534
+ cellCallbackType,
535
+ rowCallbackType,
536
+ );
537
+ addMethod(
538
+ `has${tableName}Table`,
539
+ EMPTY_STRING,
540
+ BOOLEAN,
541
+ storeMethod('hasTable', TABLE_ID),
542
+ getHasDoc(getTableDoc(tableId)),
543
+ );
544
+ addMethod(
545
+ `get${tableName}Table`,
546
+ EMPTY_STRING,
547
+ tableType,
548
+ storeMethod('getTable', TABLE_ID, tableType),
549
+ getTableContentDoc(tableId),
550
+ );
551
+ addMethod(
552
+ `set${tableName}Table`,
553
+ `table: ${tableType}`,
554
+ storeType,
555
+ fluentStoreMethod('setTable', `${TABLE_ID}, table`),
556
+ getTableContentDoc(tableId, 1),
557
+ );
558
+ addMethod(
559
+ `del${tableName}Table`,
560
+ EMPTY_STRING,
561
+ storeType,
562
+ fluentStoreMethod('delTable', TABLE_ID),
563
+ getTableContentDoc(tableId, 3),
564
+ );
565
+ addMethod(
566
+ `get${tableName}RowIds`,
567
+ EMPTY_STRING,
568
+ 'Ids',
569
+ storeMethod('getRowIds', TABLE_ID),
570
+ getIdsDoc('Row', getTableDoc(tableId)),
571
+ );
572
+ addMethod(
573
+ `get${tableName}SortedRowIds`,
574
+ `cellId?: ${cellIdType}, descending?: boolean, offset?: number, limit?: number`,
575
+ 'Ids',
576
+ storeMethod(
577
+ 'getSortedRowIds',
578
+ `${TABLE_ID}, cellId, descending, offset, limit`,
579
+ ),
580
+ getIdsDoc('Row', getTableDoc(tableId), 1),
581
+ );
582
+ addMethod(
583
+ `forEach${tableName}Row`,
584
+ `rowCallback: ${rowCallbackType}`,
585
+ 'void',
586
+ storeMethod('forEachRow', `${TABLE_ID}, rowCallback as any`),
587
+ getForEachDoc('Row', getTableDoc(tableId)),
588
+ );
589
+ addMethod(
590
+ `has${tableName}Row`,
591
+ 'rowId: Id',
592
+ BOOLEAN,
593
+ storeMethod('hasRow', `${TABLE_ID}, rowId`),
594
+ getHasDoc(THE_SPECIFIED_ROW, getTableDoc(tableId)),
595
+ );
596
+ addMethod(
597
+ `get${tableName}Row`,
598
+ 'rowId: Id',
599
+ rowType,
600
+ storeMethod('getRow', `${TABLE_ID}, rowId`, rowType),
601
+ getRowContentDoc(tableId),
602
+ );
603
+ addMethod(
604
+ `set${tableName}Row`,
605
+ `rowId: Id, row: ${rowWhenSetType}`,
606
+ storeType,
607
+ fluentStoreMethod('setRow', `${TABLE_ID}, rowId, row`),
608
+ getRowContentDoc(tableId, 1),
609
+ );
610
+ addMethod(
611
+ `add${tableName}Row`,
612
+ `row: ${rowWhenSetType}`,
613
+ `Id${OR_UNDEFINED}`,
614
+ storeMethod('addRow', `${TABLE_ID}, row`),
615
+ `Adds a new Row to ${getTableDoc(tableId)}`,
616
+ );
617
+ addMethod(
618
+ `set${tableName}PartialRow`,
619
+ `rowId: Id, partialRow: ${rowWhenSetType}`,
620
+ storeType,
621
+ fluentStoreMethod('setPartialRow', `${TABLE_ID}, rowId, partialRow`),
622
+ getRowContentDoc(tableId, 2),
623
+ );
624
+ addMethod(
625
+ `del${tableName}Row`,
626
+ `rowId: Id`,
627
+ storeType,
628
+ fluentStoreMethod('delRow', `${TABLE_ID}, rowId`),
629
+ getRowContentDoc(tableId, 3),
630
+ );
631
+ addMethod(
632
+ `get${tableName}CellIds`,
633
+ 'rowId: Id',
634
+ `${cellIdType}[]`,
635
+ storeMethod('getCellIds', `${TABLE_ID}, rowId`, `${cellIdType}[]`),
636
+ getIdsDoc('Cell', getRowDoc(tableId)),
637
+ );
638
+ addMethod(
639
+ `forEach${tableName}Cell`,
640
+ `rowId: Id, cellCallback: ${cellCallbackType}`,
641
+ 'void',
642
+ storeMethod('forEachCell', `${TABLE_ID}, rowId, cellCallback as any`),
643
+ getForEachDoc('Cell', getRowDoc(tableId)),
644
+ );
645
+ mapCellSchema(
646
+ tableId,
647
+ (cellId, type, defaultValue, CELL_ID, cellName) => {
648
+ const mapCellType = `Map${camel(type, 1)}`;
649
+ mapSet(mapCellTypes, type, mapCellType);
650
+ addMethod(
651
+ `has${tableName}${cellName}Cell`,
652
+ 'rowId: Id',
653
+ BOOLEAN,
654
+ storeMethod('hasCell', `${TABLE_ID}, rowId, ${CELL_ID}`),
655
+ getHasDoc(getCellDoc(cellId), getRowDoc(tableId)),
656
+ );
657
+ const returnCellType = `${type}${
658
+ isUndefined(defaultValue) ? OR_UNDEFINED : EMPTY_STRING
659
+ }`;
660
+ addMethod(
661
+ `get${tableName}${cellName}Cell`,
662
+ 'rowId: Id',
663
+ returnCellType,
664
+ storeMethod(
665
+ 'getCell',
666
+ `${TABLE_ID}, rowId, ${CELL_ID}`,
667
+ returnCellType,
668
+ ),
669
+ getCellContentDoc(tableId, cellId),
670
+ );
671
+ addMethod(
672
+ `set${tableName}${cellName}Cell`,
673
+ `rowId: Id, cell: ${type} | ${mapCellType}`,
674
+ storeType,
675
+ fluentStoreMethod(
676
+ 'setCell',
677
+ `${TABLE_ID}, rowId, ${CELL_ID}, cell as any`,
678
+ ),
679
+ getCellContentDoc(tableId, cellId, 1),
680
+ );
681
+ addMethod(
682
+ `del${tableName}${cellName}Cell`,
683
+ `rowId: Id`,
684
+ storeType,
685
+ fluentStoreMethod('delCell', `${TABLE_ID}, rowId, ${CELL_ID}`),
686
+ getCellContentDoc(tableId, cellId, 3),
687
+ );
688
+ },
689
+ );
690
+ },
691
+ );
692
+ addMethod(
693
+ 'getJson',
694
+ EMPTY_STRING,
695
+ 'Json',
696
+ storeMethod('getJson'),
697
+ `${verbs[0]} a string serialization ${THE_CONTENT_OF_THE_STORE}`,
698
+ );
699
+ addMethod(
700
+ 'setJson',
701
+ 'json: Json',
702
+ storeType,
703
+ fluentStoreMethod('setJson', 'json'),
704
+ `${verbs[1]} ${THE_CONTENT_OF_THE_STORE} from a serialized string`,
705
+ );
706
+ addMethod(
707
+ 'transaction',
708
+ 'actions: () => Return, doRollback?: (changedCells: ChangedCells, invalidCells: InvalidCells) => boolean',
709
+ 'Return',
710
+ storeMethod('transaction', 'actions, doRollback'),
711
+ 'Execute a transaction to make multiple mutations',
712
+ '<Return>',
713
+ );
714
+ addMethod(
715
+ 'startTransaction',
716
+ EMPTY_STRING,
717
+ storeType,
718
+ fluentStoreMethod('startTransaction'),
719
+ 'Explicitly starts a transaction',
720
+ );
721
+ addMethod(
722
+ 'finishTransaction',
723
+ 'doRollback?: (changedCells: ChangedCells, invalidCells: InvalidCells) => boolean,',
724
+ storeType,
725
+ fluentStoreMethod('finishTransaction', 'doRollback'),
726
+ 'Explicitly finishes a transaction',
727
+ );
728
+ addMethod(
729
+ 'addTablesListener',
730
+ `${LISTENER}: ${tablesListenerType}, mutator?: boolean`,
731
+ 'Id',
732
+ storeListener('addTablesListener', EMPTY_STRING, 'mutator'),
733
+ `${REGISTERS_A_LISTENER} whenever ${THE_CONTENT_OF_THE_STORE} changes`,
734
+ );
735
+ addMethod(
736
+ 'addTableIdsListener',
737
+ `${LISTENER}: ${tableIdsListenerType}, mutator?: boolean`,
738
+ 'Id',
739
+ storeListener('addTableIdsListener', EMPTY_STRING, 'mutator'),
740
+ getListenerDoc('the Table Ids', THE_STORE, 1),
741
+ );
742
+ addMethod(
743
+ 'addTableListener',
744
+ `tableId: ${tableIdType} | null, ${LISTENER}: ${tableListenerType}, mutator?: boolean`,
745
+ 'Id',
746
+ storeListener('addTableListener', 'tableId', 'mutator'),
747
+ getListenerDoc('a Table', THE_STORE),
748
+ );
749
+ addMethod(
750
+ 'addRowIdsListener',
751
+ `tableId: ${tableIdType} | null, ${LISTENER}: ${rowIdsListenerType}, mutator?: boolean`,
752
+ 'Id',
753
+ storeListener('addRowIdsListener', 'tableId', 'mutator'),
754
+ getListenerDoc('the Row Ids', 'a Table', 1),
755
+ );
756
+ addMethod(
757
+ 'addRowListener',
758
+ `tableId: ${tableIdType} | null, rowId: IdOrNull, ${LISTENER}: ${rowListenerType}, mutator?: boolean`,
759
+ 'Id',
760
+ storeListener('addRowListener', 'tableId, rowId', 'mutator'),
761
+ getListenerDoc('a Row', 'a Table'),
762
+ );
763
+ addMethod(
764
+ 'addCellIdsListener',
765
+ `tableId: ${tableIdType} | null, rowId: IdOrNull, ${LISTENER}: ${cellIdsListenerType}, mutator?: boolean`,
766
+ 'Id',
767
+ storeListener('addCellIdsListener', 'tableId, rowId', 'mutator'),
768
+ getListenerDoc('the Cell Ids', 'a Row', 1),
769
+ );
770
+ addMethod(
771
+ 'addCellListener',
772
+ `tableId: ${tableIdType} | null, rowId: IdOrNull, cellId: ${join(
773
+ mapTableSchema((_, tableTypes2) => tableTypes2[3]),
774
+ ' | ',
775
+ )} | null, ${LISTENER}: ${cellListenerType}, mutator?: boolean`,
776
+ 'Id',
777
+ storeListener('addCellListener', 'tableId, rowId, cellId', 'mutator'),
778
+ getListenerDoc('a Cell', 'a Row'),
779
+ );
780
+ addMethod(
781
+ 'addInvalidCellListener',
782
+ `tableId: IdOrNull, rowId: IdOrNull, cellId: IdOrNull, ${LISTENER}: ${invalidCellListenerType}, mutator?: boolean`,
783
+ 'Id',
784
+ storeListener('addCellListener', 'tableId, rowId, cellId', 'mutator'),
785
+ `${REGISTERS_A_LISTENER} whenever an invalid Cell change was attempted`,
786
+ );
787
+ addMethod(
788
+ 'addWillFinishTransactionListener',
789
+ `${LISTENER}: ${transactionListenerType}`,
790
+ 'Id',
791
+ storeListener('addWillFinishTransactionListener'),
792
+ `${REGISTERS_A_LISTENER} just before ${THE_END_OF_THE_TRANSACTION}`,
793
+ );
794
+ addMethod(
795
+ 'addDidFinishTransactionListener',
796
+ `${LISTENER}: ${transactionListenerType}`,
797
+ 'Id',
798
+ storeListener('addDidFinishTransactionListener'),
799
+ `${REGISTERS_A_LISTENER} just after ${THE_END_OF_THE_TRANSACTION}`,
800
+ );
801
+ addMethod(
802
+ 'callListener',
803
+ `${LISTENER}Id: Id`,
804
+ storeType,
805
+ fluentStoreMethod('callListener', `${LISTENER}Id`),
806
+ `Manually provoke a ${LISTENER} to be called`,
807
+ );
808
+ addMethod(
809
+ 'delListener',
810
+ `${LISTENER}Id: Id`,
811
+ storeType,
812
+ fluentStoreMethod('delListener', `${LISTENER}Id`),
813
+ `Remove a ${LISTENER} that was previously added to ${THE_STORE}`,
814
+ );
815
+ addMethod(
816
+ 'getStore',
817
+ EMPTY_STRING,
818
+ 'Store',
819
+ 'store',
820
+ `${verbs[0]} the underlying Store object`,
821
+ );
822
+ mapForEach(mapCellTypes, (type, mapCellType) =>
823
+ addType(
824
+ mapCellType,
825
+ `(cell: ${type}${OR_UNDEFINED}) => ${type}`,
826
+ `Takes a ${type} Cell value and returns another`,
827
+ ),
828
+ );
829
+ addImport(0, 'tinybase', 'CellChange', ...COMMON_IMPORTS);
830
+ addImport(1, 'tinybase', 'createStore', ...COMMON_IMPORTS);
831
+ addImport(
832
+ 1,
833
+ moduleDefinition,
834
+ storeType,
835
+ `create${storeType} as create${storeType}Decl`,
836
+ tablesType,
837
+ tableIdType,
838
+ tableCallbackType,
839
+ tablesListenerType,
840
+ tableIdsListenerType,
841
+ tableListenerType,
842
+ rowIdsListenerType,
843
+ rowListenerType,
844
+ cellIdsListenerType,
845
+ cellListenerType,
846
+ invalidCellListenerType,
847
+ transactionListenerType,
848
+ ...collValues(mapCellTypes),
849
+ );
850
+ addConstant('store', [
851
+ 'createStore().setSchema({',
852
+ flat(
853
+ mapTableSchema((tableId, _, __, TABLE_ID) => [
854
+ `[${TABLE_ID}]: {`,
855
+ ...mapCellSchema(
856
+ tableId,
857
+ (_2, type, defaultValue, CELL_ID) =>
858
+ `[${CELL_ID}]: {[${addConstant(
859
+ snake(TYPE),
860
+ `'${TYPE}'`,
861
+ )}]: ${addConstant(snake(type), `'${type}'`)}${
862
+ isUndefined(defaultValue)
863
+ ? EMPTY_STRING
864
+ : `, [${addConstant(snake(DEFAULT), `'${DEFAULT}'`)}]: ${
865
+ isString(defaultValue)
866
+ ? addConstant(snake(defaultValue), `'${defaultValue}'`)
867
+ : defaultValue
868
+ }`
869
+ }},`,
870
+ ),
871
+ `},`,
872
+ ]),
873
+ ),
874
+ '})',
875
+ ]);
876
+ addFunction('fluent', 'actions: () => Store', [
877
+ 'actions();',
878
+ `return ${storeInstance};`,
879
+ ]);
880
+ addFunction(
881
+ 'proxy',
882
+ `${LISTENER}: any`,
883
+ `(_: Store, ...args: any[]) => ${LISTENER}(${storeInstance}, ...args)`,
884
+ );
885
+ addConstant(storeInstance, ['{', ...getMethods(1), '}']);
886
+ return [
887
+ build(
888
+ ...getImports(0),
889
+ ...getTypes(),
890
+ `${EXPORT} interface ${storeType} {`,
891
+ ...getMethods(0),
892
+ `}`,
893
+ EMPTY_STRING,
894
+ comment(`Creates a ${storeType} object`),
895
+ `${EXPORT} function create${storeType}(): ${storeType};`,
896
+ ),
897
+ build(
898
+ ...getImports(1),
899
+ `${EXPORT} const create${storeType}: typeof create${storeType}Decl = () => {`,
900
+ ...getConstants(),
901
+ `return Object.freeze(${storeInstance});`,
902
+ `};`,
903
+ ),
904
+ ];
905
+ };
906
+
907
+ const prettierConfig = {
908
+ parser: 'typescript',
909
+ singleQuote: true,
910
+ trailingComma: 'all',
911
+ bracketSpacing: false,
912
+ jsdocSingleLineComment: false,
913
+ };
914
+ const createTools = getCreateFunction((store) => {
915
+ const getStoreStats = (detail) => {
916
+ let totalTables = 0;
917
+ let totalRows = 0;
918
+ let totalCells = 0;
919
+ const tables = {};
920
+ store.forEachTable((tableId, forEachRow) => {
921
+ totalTables++;
922
+ let tableRows = 0;
923
+ let tableCells = 0;
924
+ const rows = {};
925
+ forEachRow((rowId, forEachCell) => {
926
+ tableRows++;
927
+ let rowCells = 0;
928
+ forEachCell(() => rowCells++);
929
+ tableCells += rowCells;
930
+ if (detail) {
931
+ rows[rowId] = {rowCells};
932
+ }
933
+ });
934
+ totalRows += tableRows;
935
+ totalCells += tableCells;
936
+ if (detail) {
937
+ tables[tableId] = {tableRows, tableCells, rows};
938
+ }
939
+ });
940
+ return {
941
+ totalTables,
942
+ totalRows,
943
+ totalCells,
944
+ jsonLength: length(store.getJson()),
945
+ ...(detail ? {detail: {tables}} : {}),
946
+ };
947
+ };
948
+ const getStoreSchema = () => {
949
+ const schema = jsonParse(store.getSchemaJson());
950
+ if (
951
+ !objIsEmpty(schema) ||
952
+ arrayEvery(store.getTableIds(), (tableId) => {
953
+ const rowIds = store.getRowIds(tableId);
954
+ const cellsMeta = mapNew();
955
+ if (
956
+ arrayEvery(rowIds, (rowId) =>
957
+ arrayEvery(store.getCellIds(tableId, rowId), (cellId) => {
958
+ const value = store.getCell(tableId, rowId, cellId);
959
+ const cellMeta = mapEnsure(cellsMeta, cellId, () => [
960
+ getCellType(value),
961
+ mapNew(),
962
+ [0],
963
+ 0,
964
+ ]);
965
+ const [type, values, [maxCount]] = cellMeta;
966
+ const count = mapEnsure(values, value, () => 0) + 1;
967
+ if (count > maxCount) {
968
+ cellMeta[2] = [count, value];
969
+ }
970
+ mapSet(values, value, count);
971
+ cellMeta[3]++;
972
+ return type == getCellType(value);
973
+ }),
974
+ )
975
+ ) {
976
+ schema[tableId] = {};
977
+ collForEach(cellsMeta, ([type, , [, maxValue], count], cellId) => {
978
+ schema[tableId][cellId] = {
979
+ [TYPE]: type,
980
+ ...(count == arrayLength(rowIds) ? {[DEFAULT]: maxValue} : {}),
981
+ };
982
+ });
983
+ return 1;
984
+ }
985
+ })
986
+ ) {
987
+ return schema;
988
+ }
989
+ return {};
990
+ };
991
+ const getStoreApi$1 = (module) => getStoreApi(getStoreSchema(), module);
992
+ const getPrettyStoreApi = async (module) => {
993
+ let format;
994
+ try {
995
+ format = (await import('prettier')).format;
996
+ } catch {
997
+ format = (str) => str;
998
+ }
999
+ return arrayMap(getStoreApi$1(module), (file) =>
1000
+ formatJsDoc(format(file, prettierConfig)),
1001
+ );
1002
+ };
1003
+ const tools = {
1004
+ getStoreStats,
1005
+ getStoreSchema,
1006
+ getStoreApi: getStoreApi$1,
1007
+ getPrettyStoreApi,
1008
+ };
1009
+ return objFreeze(tools);
1010
+ });
1011
+
1012
+ export {createTools};