@jarenjs/db 0.84.3 → 0.86.0
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/ARCHITECTURE.md +27 -3
- package/README.md +35 -14
- package/docs/HOSTS.md +131 -4
- package/docs/MODEL-FORMAT.md +15 -4
- package/docs/NATIVE-PLANS.md +24 -7
- package/docs/SQLITE-RELATIONAL.md +190 -0
- package/package.json +24 -4
- package/schemas/jaren-model.authoring.schema.json +157 -0
- package/schemas/jaren-model.draft-07.schema.json +157 -0
- package/schemas/jaren-model.schema.json +157 -0
- package/src/capture.js +4 -2
- package/src/ddl.js +8 -3
- package/src/dialects/sqlite-relational.js +314 -0
- package/src/dialects/sqlite-schema.js +142 -0
- package/src/dialects/sqlite.js +17 -0
- package/src/driver.js +3 -0
- package/src/drivers/bun.js +26 -15
- package/src/drivers/node-process-endpoint.js +13 -0
- package/src/drivers/node-process.js +177 -0
- package/src/drivers/node-worker-endpoint.js +3 -103
- package/src/drivers/node-worker.js +6 -178
- package/src/drivers/node.js +3 -0
- package/src/drivers/snapshot.js +49 -0
- package/src/drivers/sqlite-endpoint.js +113 -0
- package/src/drivers/worker-client.js +185 -0
- package/src/drivers/worker-protocol.js +15 -0
- package/src/emit.js +37 -5
- package/src/engine-metadata.js +18 -0
- package/src/errors.js +1 -0
- package/src/index.js +4 -1
- package/src/introspect.js +1 -2
- package/src/jobs.js +4 -2
- package/src/migrate.js +12 -16
- package/src/model-api.js +4 -0
- package/src/model.js +12 -0
- package/src/mutation.js +66 -14
- package/src/physical.js +37 -7
- package/src/plan.js +66 -3
- package/src/query-api.js +5 -0
- package/src/query.js +39 -6
- package/src/relational-api.js +6 -0
- package/src/store.js +6 -4
- package/src/table-migration.js +158 -0
- package/types/bun.d.ts +3 -0
- package/types/entity.d.ts +1 -0
- package/types/index.d.ts +11 -2
- package/types/model.d.ts +1 -0
- package/types/node-process.d.ts +33 -0
- package/types/node.d.ts +3 -0
- package/types/query.d.ts +2 -0
- package/types/relational.d.ts +114 -0
|
@@ -233,10 +233,167 @@
|
|
|
233
233
|
},
|
|
234
234
|
"generated": {
|
|
235
235
|
"type": "boolean"
|
|
236
|
+
},
|
|
237
|
+
"type": {
|
|
238
|
+
"enum": [
|
|
239
|
+
"INTEGER",
|
|
240
|
+
"REAL",
|
|
241
|
+
"TEXT",
|
|
242
|
+
"BLOB",
|
|
243
|
+
"NUMERIC"
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
"defaultValue": {
|
|
247
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
248
|
+
"anyOf": [
|
|
249
|
+
{
|
|
250
|
+
"type": [
|
|
251
|
+
"string",
|
|
252
|
+
"number",
|
|
253
|
+
"null"
|
|
254
|
+
]
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
"type": "object",
|
|
258
|
+
"required": [
|
|
259
|
+
"$sql"
|
|
260
|
+
],
|
|
261
|
+
"properties": {
|
|
262
|
+
"$sql": {
|
|
263
|
+
"enum": [
|
|
264
|
+
"column",
|
|
265
|
+
"value",
|
|
266
|
+
"binary",
|
|
267
|
+
"not",
|
|
268
|
+
"in",
|
|
269
|
+
"call",
|
|
270
|
+
"cast",
|
|
271
|
+
"collate",
|
|
272
|
+
"case",
|
|
273
|
+
"scalar",
|
|
274
|
+
"exists"
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
"collation": {
|
|
282
|
+
"enum": [
|
|
283
|
+
"BINARY",
|
|
284
|
+
"NOCASE",
|
|
285
|
+
"RTRIM"
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
"identity": {
|
|
289
|
+
"enum": [
|
|
290
|
+
"rowid",
|
|
291
|
+
"autoincrement"
|
|
292
|
+
]
|
|
293
|
+
},
|
|
294
|
+
"check": {
|
|
295
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
296
|
+
"anyOf": [
|
|
297
|
+
{
|
|
298
|
+
"type": [
|
|
299
|
+
"string",
|
|
300
|
+
"number",
|
|
301
|
+
"null"
|
|
302
|
+
]
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"type": "object",
|
|
306
|
+
"required": [
|
|
307
|
+
"$sql"
|
|
308
|
+
],
|
|
309
|
+
"properties": {
|
|
310
|
+
"$sql": {
|
|
311
|
+
"enum": [
|
|
312
|
+
"column",
|
|
313
|
+
"value",
|
|
314
|
+
"binary",
|
|
315
|
+
"not",
|
|
316
|
+
"in",
|
|
317
|
+
"call",
|
|
318
|
+
"cast",
|
|
319
|
+
"collate",
|
|
320
|
+
"case",
|
|
321
|
+
"scalar",
|
|
322
|
+
"exists"
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
]
|
|
328
|
+
},
|
|
329
|
+
"generatedExpression": {
|
|
330
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
331
|
+
"anyOf": [
|
|
332
|
+
{
|
|
333
|
+
"type": [
|
|
334
|
+
"string",
|
|
335
|
+
"number",
|
|
336
|
+
"null"
|
|
337
|
+
]
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
"type": "object",
|
|
341
|
+
"required": [
|
|
342
|
+
"$sql"
|
|
343
|
+
],
|
|
344
|
+
"properties": {
|
|
345
|
+
"$sql": {
|
|
346
|
+
"enum": [
|
|
347
|
+
"column",
|
|
348
|
+
"value",
|
|
349
|
+
"binary",
|
|
350
|
+
"not",
|
|
351
|
+
"in",
|
|
352
|
+
"call",
|
|
353
|
+
"cast",
|
|
354
|
+
"collate",
|
|
355
|
+
"case",
|
|
356
|
+
"scalar",
|
|
357
|
+
"exists"
|
|
358
|
+
]
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
]
|
|
363
|
+
},
|
|
364
|
+
"stored": {
|
|
365
|
+
"type": "boolean"
|
|
236
366
|
}
|
|
237
367
|
},
|
|
238
368
|
"additionalProperties": false
|
|
239
369
|
}
|
|
370
|
+
},
|
|
371
|
+
"constraints": {
|
|
372
|
+
"type": "array",
|
|
373
|
+
"items": {
|
|
374
|
+
"type": "object"
|
|
375
|
+
},
|
|
376
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
377
|
+
},
|
|
378
|
+
"indexes": {
|
|
379
|
+
"type": "array",
|
|
380
|
+
"items": {
|
|
381
|
+
"type": "object"
|
|
382
|
+
},
|
|
383
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
384
|
+
},
|
|
385
|
+
"triggers": {
|
|
386
|
+
"type": "array",
|
|
387
|
+
"items": {
|
|
388
|
+
"type": "object"
|
|
389
|
+
},
|
|
390
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
391
|
+
},
|
|
392
|
+
"strict": {
|
|
393
|
+
"type": "boolean"
|
|
394
|
+
},
|
|
395
|
+
"withoutRowid": {
|
|
396
|
+
"type": "boolean"
|
|
240
397
|
}
|
|
241
398
|
},
|
|
242
399
|
"additionalProperties": false
|
|
@@ -227,10 +227,167 @@
|
|
|
227
227
|
},
|
|
228
228
|
"generated": {
|
|
229
229
|
"type": "boolean"
|
|
230
|
+
},
|
|
231
|
+
"type": {
|
|
232
|
+
"enum": [
|
|
233
|
+
"INTEGER",
|
|
234
|
+
"REAL",
|
|
235
|
+
"TEXT",
|
|
236
|
+
"BLOB",
|
|
237
|
+
"NUMERIC"
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
"defaultValue": {
|
|
241
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
242
|
+
"anyOf": [
|
|
243
|
+
{
|
|
244
|
+
"type": [
|
|
245
|
+
"string",
|
|
246
|
+
"number",
|
|
247
|
+
"null"
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"type": "object",
|
|
252
|
+
"required": [
|
|
253
|
+
"$sql"
|
|
254
|
+
],
|
|
255
|
+
"properties": {
|
|
256
|
+
"$sql": {
|
|
257
|
+
"enum": [
|
|
258
|
+
"column",
|
|
259
|
+
"value",
|
|
260
|
+
"binary",
|
|
261
|
+
"not",
|
|
262
|
+
"in",
|
|
263
|
+
"call",
|
|
264
|
+
"cast",
|
|
265
|
+
"collate",
|
|
266
|
+
"case",
|
|
267
|
+
"scalar",
|
|
268
|
+
"exists"
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
"collation": {
|
|
276
|
+
"enum": [
|
|
277
|
+
"BINARY",
|
|
278
|
+
"NOCASE",
|
|
279
|
+
"RTRIM"
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
"identity": {
|
|
283
|
+
"enum": [
|
|
284
|
+
"rowid",
|
|
285
|
+
"autoincrement"
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
"check": {
|
|
289
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
290
|
+
"anyOf": [
|
|
291
|
+
{
|
|
292
|
+
"type": [
|
|
293
|
+
"string",
|
|
294
|
+
"number",
|
|
295
|
+
"null"
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"type": "object",
|
|
300
|
+
"required": [
|
|
301
|
+
"$sql"
|
|
302
|
+
],
|
|
303
|
+
"properties": {
|
|
304
|
+
"$sql": {
|
|
305
|
+
"enum": [
|
|
306
|
+
"column",
|
|
307
|
+
"value",
|
|
308
|
+
"binary",
|
|
309
|
+
"not",
|
|
310
|
+
"in",
|
|
311
|
+
"call",
|
|
312
|
+
"cast",
|
|
313
|
+
"collate",
|
|
314
|
+
"case",
|
|
315
|
+
"scalar",
|
|
316
|
+
"exists"
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
},
|
|
323
|
+
"generatedExpression": {
|
|
324
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
325
|
+
"anyOf": [
|
|
326
|
+
{
|
|
327
|
+
"type": [
|
|
328
|
+
"string",
|
|
329
|
+
"number",
|
|
330
|
+
"null"
|
|
331
|
+
]
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"type": "object",
|
|
335
|
+
"required": [
|
|
336
|
+
"$sql"
|
|
337
|
+
],
|
|
338
|
+
"properties": {
|
|
339
|
+
"$sql": {
|
|
340
|
+
"enum": [
|
|
341
|
+
"column",
|
|
342
|
+
"value",
|
|
343
|
+
"binary",
|
|
344
|
+
"not",
|
|
345
|
+
"in",
|
|
346
|
+
"call",
|
|
347
|
+
"cast",
|
|
348
|
+
"collate",
|
|
349
|
+
"case",
|
|
350
|
+
"scalar",
|
|
351
|
+
"exists"
|
|
352
|
+
]
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
},
|
|
358
|
+
"stored": {
|
|
359
|
+
"type": "boolean"
|
|
230
360
|
}
|
|
231
361
|
},
|
|
232
362
|
"additionalProperties": false
|
|
233
363
|
}
|
|
364
|
+
},
|
|
365
|
+
"constraints": {
|
|
366
|
+
"type": "array",
|
|
367
|
+
"items": {
|
|
368
|
+
"type": "object"
|
|
369
|
+
},
|
|
370
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
371
|
+
},
|
|
372
|
+
"indexes": {
|
|
373
|
+
"type": "array",
|
|
374
|
+
"items": {
|
|
375
|
+
"type": "object"
|
|
376
|
+
},
|
|
377
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
378
|
+
},
|
|
379
|
+
"triggers": {
|
|
380
|
+
"type": "array",
|
|
381
|
+
"items": {
|
|
382
|
+
"type": "object"
|
|
383
|
+
},
|
|
384
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
385
|
+
},
|
|
386
|
+
"strict": {
|
|
387
|
+
"type": "boolean"
|
|
388
|
+
},
|
|
389
|
+
"withoutRowid": {
|
|
390
|
+
"type": "boolean"
|
|
234
391
|
}
|
|
235
392
|
},
|
|
236
393
|
"additionalProperties": false
|
|
@@ -227,10 +227,167 @@
|
|
|
227
227
|
},
|
|
228
228
|
"generated": {
|
|
229
229
|
"type": "boolean"
|
|
230
|
+
},
|
|
231
|
+
"type": {
|
|
232
|
+
"enum": [
|
|
233
|
+
"INTEGER",
|
|
234
|
+
"REAL",
|
|
235
|
+
"TEXT",
|
|
236
|
+
"BLOB",
|
|
237
|
+
"NUMERIC"
|
|
238
|
+
]
|
|
239
|
+
},
|
|
240
|
+
"defaultValue": {
|
|
241
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
242
|
+
"anyOf": [
|
|
243
|
+
{
|
|
244
|
+
"type": [
|
|
245
|
+
"string",
|
|
246
|
+
"number",
|
|
247
|
+
"null"
|
|
248
|
+
]
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
"type": "object",
|
|
252
|
+
"required": [
|
|
253
|
+
"$sql"
|
|
254
|
+
],
|
|
255
|
+
"properties": {
|
|
256
|
+
"$sql": {
|
|
257
|
+
"enum": [
|
|
258
|
+
"column",
|
|
259
|
+
"value",
|
|
260
|
+
"binary",
|
|
261
|
+
"not",
|
|
262
|
+
"in",
|
|
263
|
+
"call",
|
|
264
|
+
"cast",
|
|
265
|
+
"collate",
|
|
266
|
+
"case",
|
|
267
|
+
"scalar",
|
|
268
|
+
"exists"
|
|
269
|
+
]
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
"collation": {
|
|
276
|
+
"enum": [
|
|
277
|
+
"BINARY",
|
|
278
|
+
"NOCASE",
|
|
279
|
+
"RTRIM"
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
"identity": {
|
|
283
|
+
"enum": [
|
|
284
|
+
"rowid",
|
|
285
|
+
"autoincrement"
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
"check": {
|
|
289
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
290
|
+
"anyOf": [
|
|
291
|
+
{
|
|
292
|
+
"type": [
|
|
293
|
+
"string",
|
|
294
|
+
"number",
|
|
295
|
+
"null"
|
|
296
|
+
]
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"type": "object",
|
|
300
|
+
"required": [
|
|
301
|
+
"$sql"
|
|
302
|
+
],
|
|
303
|
+
"properties": {
|
|
304
|
+
"$sql": {
|
|
305
|
+
"enum": [
|
|
306
|
+
"column",
|
|
307
|
+
"value",
|
|
308
|
+
"binary",
|
|
309
|
+
"not",
|
|
310
|
+
"in",
|
|
311
|
+
"call",
|
|
312
|
+
"cast",
|
|
313
|
+
"collate",
|
|
314
|
+
"case",
|
|
315
|
+
"scalar",
|
|
316
|
+
"exists"
|
|
317
|
+
]
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
},
|
|
323
|
+
"generatedExpression": {
|
|
324
|
+
"description": "A literal SQLite value or closed structural $sql expression; planTable validates its operator and contextual semantics.",
|
|
325
|
+
"anyOf": [
|
|
326
|
+
{
|
|
327
|
+
"type": [
|
|
328
|
+
"string",
|
|
329
|
+
"number",
|
|
330
|
+
"null"
|
|
331
|
+
]
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
"type": "object",
|
|
335
|
+
"required": [
|
|
336
|
+
"$sql"
|
|
337
|
+
],
|
|
338
|
+
"properties": {
|
|
339
|
+
"$sql": {
|
|
340
|
+
"enum": [
|
|
341
|
+
"column",
|
|
342
|
+
"value",
|
|
343
|
+
"binary",
|
|
344
|
+
"not",
|
|
345
|
+
"in",
|
|
346
|
+
"call",
|
|
347
|
+
"cast",
|
|
348
|
+
"collate",
|
|
349
|
+
"case",
|
|
350
|
+
"scalar",
|
|
351
|
+
"exists"
|
|
352
|
+
]
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
},
|
|
358
|
+
"stored": {
|
|
359
|
+
"type": "boolean"
|
|
230
360
|
}
|
|
231
361
|
},
|
|
232
362
|
"additionalProperties": false
|
|
233
363
|
}
|
|
364
|
+
},
|
|
365
|
+
"constraints": {
|
|
366
|
+
"type": "array",
|
|
367
|
+
"items": {
|
|
368
|
+
"type": "object"
|
|
369
|
+
},
|
|
370
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
371
|
+
},
|
|
372
|
+
"indexes": {
|
|
373
|
+
"type": "array",
|
|
374
|
+
"items": {
|
|
375
|
+
"type": "object"
|
|
376
|
+
},
|
|
377
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
378
|
+
},
|
|
379
|
+
"triggers": {
|
|
380
|
+
"type": "array",
|
|
381
|
+
"items": {
|
|
382
|
+
"type": "object"
|
|
383
|
+
},
|
|
384
|
+
"description": "Structural SQLite declarations validated by planTable."
|
|
385
|
+
},
|
|
386
|
+
"strict": {
|
|
387
|
+
"type": "boolean"
|
|
388
|
+
},
|
|
389
|
+
"withoutRowid": {
|
|
390
|
+
"type": "boolean"
|
|
234
391
|
}
|
|
235
392
|
},
|
|
236
393
|
"additionalProperties": false
|
package/src/capture.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
//@ts-check
|
|
2
|
+
import { CHANGES_TABLE, CHANGES_STATE_TABLE } from './engine-metadata.js';
|
|
3
|
+
export { CHANGES_TABLE, CHANGES_STATE_TABLE };
|
|
2
4
|
/**
|
|
3
5
|
* @file Change capture (D13): committed writes become an observable,
|
|
4
6
|
* ordered stream of RFC 6902 patches — derived from SQLite's own
|
|
@@ -37,13 +39,13 @@ import { chain, attempt } from './driver.js';
|
|
|
37
39
|
import { createCursor, drainPage, utf8Length, PAGE_LIMIT_DEFAULT } from './cursor.js';
|
|
38
40
|
|
|
39
41
|
/** The persisted change log (LIVE-FORMAT §5). */
|
|
40
|
-
|
|
42
|
+
|
|
41
43
|
/**
|
|
42
44
|
* The log's durable state: one row holding the highest sequence ever
|
|
43
45
|
* allocated for this file, so the high watermark survives a log that
|
|
44
46
|
* retention or maintenance has emptied (LIVE-FORMAT §5).
|
|
45
47
|
*/
|
|
46
|
-
|
|
48
|
+
|
|
47
49
|
export const DEFAULT_RETENTION = 1000;
|
|
48
50
|
|
|
49
51
|
/** A driver failure met by the change reader, classified — never raw. */
|
package/src/ddl.js
CHANGED
|
@@ -20,6 +20,7 @@ import { DbCompileError } from './errors.js';
|
|
|
20
20
|
import { chain } from './driver.js';
|
|
21
21
|
import { BBOX_COMPONENTS, BBOX_INDEX_ORDER, derivedMappingFor } from './derive.js';
|
|
22
22
|
import { expressionSql, expressionStem, expressionFunctions } from './expression.js';
|
|
23
|
+
import { planTable } from './dialects/sqlite-schema.js';
|
|
23
24
|
|
|
24
25
|
/** The fixed physical column names of the 0.1 mapping. */
|
|
25
26
|
export const KEY_COLUMN = 'key';
|
|
@@ -903,9 +904,13 @@ export function verifyShape(connection, plan, collection, docPath) {
|
|
|
903
904
|
* columnNames: Set<string> }}
|
|
904
905
|
*/
|
|
905
906
|
export function planEntity(name, entityMapping, entities, dialect) {
|
|
906
|
-
if (entityMapping.document === false)
|
|
907
|
-
|
|
908
|
-
|
|
907
|
+
if (entityMapping.document === false) {
|
|
908
|
+
const declared = entityMapping.ddl && dialect.name === 'sqlite' ? planTable(entityMapping.ddl) : null;
|
|
909
|
+
return { table: entityMapping.table,
|
|
910
|
+
physical: { ...entityMapping, triggers: dialect.invariantTriggers?.(entityMapping, entities, dialect) ?? [] },
|
|
911
|
+
createSql: declared?.createSql ?? [], expected: declared?.expected ?? { columns: [], indexes: [] },
|
|
912
|
+
columnNames: new Set(entityMapping.columns.map((c) => c.physical)) };
|
|
913
|
+
}
|
|
909
914
|
const storageType = (storage) => dialect.typeFor(storage, 'generated');
|
|
910
915
|
const keyType = (entityName) => {
|
|
911
916
|
const target = entities.entities[entityName];
|