@seedprotocol/sdk 0.7.3 → 0.7.4-next.784.g879c6a3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BasePathResolver-Cm4apKRb.js → BasePathResolver-DxdS0wJ0.js} +43 -8
- package/dist/BasePathResolver-DxdS0wJ0.js.map +1 -0
- package/dist/{ClientManager-i3nJASkg.js → ClientManager-De-vKHGe.js} +37 -38
- package/dist/ClientManager-De-vKHGe.js.map +1 -0
- package/dist/{Item-DBFchXpC.js → Item-cq9VcsAY.js} +365 -191
- package/dist/Item-cq9VcsAY.js.map +1 -0
- package/dist/{ModelProperty-BS49g01Y.js → ModelProperty-DuuoFXaC.js} +45 -37
- package/dist/ModelProperty-DuuoFXaC.js.map +1 -0
- package/dist/{Schema-CpMNEnUO.js → Schema-Dc5EA8Yb.js} +246 -68
- package/dist/Schema-Dc5EA8Yb.js.map +1 -0
- package/dist/{SchemaValidationService-DieV4KL-.js → SchemaValidationService-DViJ056F.js} +49 -36
- package/dist/SchemaValidationService-DViJ056F.js.map +1 -0
- package/dist/{backfillMetadataPropertyIds-DSoOoTnX.js → backfillMetadataPropertyIds-DacVthS5.js} +3 -3
- package/dist/{backfillMetadataPropertyIds-DSoOoTnX.js.map → backfillMetadataPropertyIds-DacVthS5.js.map} +1 -1
- package/dist/{configurePlatform-D0lQGAMQ.js → configurePlatform-DlZ23w7e.js} +2 -2
- package/dist/{configurePlatform-D0lQGAMQ.js.map → configurePlatform-DlZ23w7e.js.map} +1 -1
- package/dist/{detachRowsBeforeDelete-S0q-DJPT.js → detachRowsBeforeDelete-YRSZY6dO.js} +2 -2
- package/dist/{detachRowsBeforeDelete-S0q-DJPT.js.map → detachRowsBeforeDelete-YRSZY6dO.js.map} +1 -1
- package/dist/{eas-6pjU-OuX.js → eas-D_6ptL_F.js} +4 -4
- package/dist/{eas-6pjU-OuX.js.map → eas-D_6ptL_F.js.map} +1 -1
- package/dist/{index-8O3Uow-Y.js → errors-Cl8rbtKR.js} +192 -48
- package/dist/errors-Cl8rbtKR.js.map +1 -0
- package/dist/{getItem-CxBNZ-WL.js → getItem-BcmJcUZB.js} +5 -5
- package/dist/{getItem-CxBNZ-WL.js.map → getItem-BcmJcUZB.js.map} +1 -1
- package/dist/{getPublishPayload-CTCvRUoU.js → getPublishPayload-C278kK9P.js} +15 -15
- package/dist/{getPublishPayload-CTCvRUoU.js.map → getPublishPayload-C278kK9P.js.map} +1 -1
- package/dist/{getPublishUploads-SFHCbf_y.js → getPublishUploads-DJ1UPh7i.js} +9 -9
- package/dist/{getPublishUploads-SFHCbf_y.js.map → getPublishUploads-DJ1UPh7i.js.map} +1 -1
- package/dist/{index-Cvt5UBz4.js → index-CqnU-5i0.js} +9 -9
- package/dist/index-CqnU-5i0.js.map +1 -0
- package/dist/{index-AVFTVp1m.js → index-DAl9U4rn.js} +2 -2
- package/dist/index-DAl9U4rn.js.map +1 -0
- package/dist/{index.browser-DBhxRoe8.js → index.browser-J6QZ9smP.js} +10 -10
- package/dist/{index.browser-DBhxRoe8.js.map → index.browser-J6QZ9smP.js.map} +1 -1
- package/dist/{index.node-CJhlcNHM.js → index.node-C9VB9NlX.js} +9 -9
- package/dist/index.node-C9VB9NlX.js.map +1 -0
- package/dist/main.js +24 -24
- package/dist/{model-DGMe-TTm.js → model-oHA3YhOd.js} +5 -1
- package/dist/model-oHA3YhOd.js.map +1 -0
- package/dist/node.js +11 -11
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +5 -5
- package/dist/platform.node.js +4 -4
- package/dist/{property-DwPD283A.js → property-Brgr5RdT.js} +11 -11
- package/dist/{property-DwPD283A.js.map → property-Brgr5RdT.js.map} +1 -1
- package/dist/propertyValidationRules-CDRitiiK.js +51 -0
- package/dist/propertyValidationRules-CDRitiiK.js.map +1 -0
- package/dist/{publishDraftGraph-BOn3_Occ.js → publishDraftGraph-C37ibxb5.js} +6 -6
- package/dist/{publishDraftGraph-BOn3_Occ.js.map → publishDraftGraph-C37ibxb5.js.map} +1 -1
- package/dist/{resetAmbiguousLegacyItemData-BkYmBeJc.js → resetAmbiguousLegacyItemData-CcLFRREE.js} +2 -2
- package/dist/{resetAmbiguousLegacyItemData-BkYmBeJc.js.map → resetAmbiguousLegacyItemData-CcLFRREE.js.map} +1 -1
- package/dist/{resolveModelForSyncedSeed-BL24nLa7.js → resolveModelForSyncedSeed-BTAeCOJE.js} +2 -2
- package/dist/{resolveModelForSyncedSeed-BL24nLa7.js.map → resolveModelForSyncedSeed-BTAeCOJE.js.map} +1 -1
- package/dist/src/Item/Item.d.ts +6 -2
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/Item/errors.d.ts +23 -0
- package/dist/src/Item/errors.d.ts.map +1 -0
- package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/loadOrCreateProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/analyzeInput.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts +19 -0
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveImage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
- package/dist/src/Model/Model.d.ts +2 -0
- package/dist/src/Model/Model.d.ts.map +1 -1
- package/dist/src/Model/service/actors/createModelProperties.d.ts.map +1 -1
- package/dist/src/ModelProperty/ModelProperty.d.ts +2 -0
- package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
- package/dist/src/Schema/Schema.d.ts +11 -2
- package/dist/src/Schema/Schema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/checkExistingSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts +4 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
- package/dist/src/db/Db/BaseDb.d.ts +5 -2
- package/dist/src/db/Db/BaseDb.d.ts.map +1 -1
- package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
- package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/entity/draftSaveErrors.d.ts +4 -0
- package/dist/src/helpers/entity/draftSaveErrors.d.ts.map +1 -0
- package/dist/src/helpers/entity/entityUnload.d.ts +2 -1
- package/dist/src/helpers/entity/entityUnload.d.ts.map +1 -1
- package/dist/src/helpers/entity/evictionEpoch.d.ts +27 -2
- package/dist/src/helpers/entity/evictionEpoch.d.ts.map +1 -1
- package/dist/src/helpers/isSqliteUniqueConstraintError.d.ts.map +1 -1
- package/dist/src/helpers/model.d.ts.map +1 -1
- package/dist/src/helpers/propertyValidationRules.d.ts +12 -0
- package/dist/src/helpers/propertyValidationRules.d.ts.map +1 -0
- package/dist/src/helpers/propertyWriteQueue.d.ts +15 -0
- package/dist/src/helpers/propertyWriteQueue.d.ts.map +1 -0
- package/dist/src/helpers/schema.d.ts.map +1 -1
- package/dist/src/helpers/storageFileName.d.ts +7 -0
- package/dist/src/helpers/storageFileName.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/node/db/Db.d.ts +1 -1
- package/dist/src/node/db/Db.d.ts.map +1 -1
- package/dist/src/node/index.d.ts +1 -0
- package/dist/src/node/index.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +12 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/{syncDbWithEas-Bv2Fe38J.js → syncDbWithEas-B-Ho0IOB.js} +50 -27
- package/dist/syncDbWithEas-B-Ho0IOB.js.map +1 -0
- package/dist/{tabEvents-9s2WCYw-.js → tabEvents-BTzckWrN.js} +4 -4
- package/dist/{tabEvents-9s2WCYw-.js.map → tabEvents-BTzckWrN.js.map} +1 -1
- package/dist/{tolerantWebAccess-iUu80pAP.js → tolerantWebAccess-DOm2Xv-f.js} +6 -6
- package/dist/{tolerantWebAccess-iUu80pAP.js.map → tolerantWebAccess-DOm2Xv-f.js.map} +1 -1
- package/dist/{updateSeedRevokedAt-zBfi931j.js → updateSeedRevokedAt-IHXnJI-i.js} +3 -3
- package/dist/{updateSeedRevokedAt-zBfi931j.js.map → updateSeedRevokedAt-IHXnJI-i.js.map} +1 -1
- package/package.json +5 -5
- package/dist/BasePathResolver-Cm4apKRb.js.map +0 -1
- package/dist/ClientManager-i3nJASkg.js.map +0 -1
- package/dist/Item-DBFchXpC.js.map +0 -1
- package/dist/ModelProperty-BS49g01Y.js.map +0 -1
- package/dist/Schema-CpMNEnUO.js.map +0 -1
- package/dist/SchemaValidationService-DieV4KL-.js.map +0 -1
- package/dist/index-8O3Uow-Y.js.map +0 -1
- package/dist/index-AVFTVp1m.js.map +0 -1
- package/dist/index-Cvt5UBz4.js.map +0 -1
- package/dist/index.node-CJhlcNHM.js.map +0 -1
- package/dist/model-DGMe-TTm.js.map +0 -1
- package/dist/syncDbWithEas-Bv2Fe38J.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { fromCallback, fromPromise, setup, assign, createActor } from 'xstate';
|
|
2
|
-
import { E as BaseDb, s as models, u as properties, $ as generateId, aF as isInternalSchema, aG as writeModelToDb, aH as writePropertyToDb, aI as addSchemaToDb, q as modelSchemas, z as schemas, F as AmbiguousModelError, aJ as renameModelInDb, a as TProperty } from './BasePathResolver-
|
|
2
|
+
import { E as BaseDb, s as models, u as properties, $ as generateId, aF as isInternalSchema, aG as writeModelToDb, aH as writePropertyToDb, aI as addSchemaToDb, q as modelSchemas, z as schemas, F as AmbiguousModelError, aJ as renameModelInDb, a as TProperty } from './BasePathResolver-DxdS0wJ0.js';
|
|
3
3
|
import { eq, and, isNull, or } from 'drizzle-orm';
|
|
4
4
|
import debug from 'debug';
|
|
5
|
-
import { n as waitForEntityIdle, D as DEFAULT_READY_TIMEOUT_MS, $ as getInvariantSafePropertyDescriptor, q as findEntity, C as ClientManagerState, I as Item, a0 as clearDestroySubscriptions, t as forceRemoveFromCaches, a1 as unloadEntity, u as runDestroyLifecycle } from './Item-
|
|
6
|
-
import { k as getClient } from './ClientManager-
|
|
7
|
-
import { modelPropertiesToObject } from './model-
|
|
5
|
+
import { n as waitForEntityIdle, D as DEFAULT_READY_TIMEOUT_MS, $ as getInvariantSafePropertyDescriptor, q as findEntity, C as ClientManagerState, I as Item, a0 as clearDestroySubscriptions, t as forceRemoveFromCaches, a1 as unloadEntity, u as runDestroyLifecycle } from './Item-cq9VcsAY.js';
|
|
6
|
+
import { k as getClient } from './ClientManager-De-vKHGe.js';
|
|
7
|
+
import { modelPropertiesToObject } from './model-oHA3YhOd.js';
|
|
8
8
|
import { toSnakeCase } from 'drizzle-orm/casing';
|
|
9
9
|
import { Type } from '@sinclair/typebox';
|
|
10
10
|
|
|
@@ -35,7 +35,7 @@ const createPropertyInstances = async (propertyFileIds) => {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
try {
|
|
38
|
-
const mod = await import('./ModelProperty-
|
|
38
|
+
const mod = await import('./ModelProperty-DuuoFXaC.js');
|
|
39
39
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
40
40
|
if (!ModelProperty) {
|
|
41
41
|
logger$7('createPropertyInstances: ModelProperty not available from dynamic import');
|
|
@@ -101,11 +101,11 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context }, self })
|
|
|
101
101
|
if (!modelRecord) {
|
|
102
102
|
// Model names are only unique per schema: prefer this schema's row, and otherwise only
|
|
103
103
|
// consider same-name rows that no schema claims yet (never another schema's model).
|
|
104
|
-
const _mod_0 = await import('./BasePathResolver-
|
|
105
|
-
const _ns_0 = _mod_0.
|
|
104
|
+
const _mod_0 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
105
|
+
const _ns_0 = _mod_0.b1;
|
|
106
106
|
const { modelSchemas } = _ns_0;
|
|
107
|
-
const _mod_1 = await import('./BasePathResolver-
|
|
108
|
-
const _ns_1 = _mod_1.
|
|
107
|
+
const _mod_1 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
108
|
+
const _ns_1 = _mod_1.b0;
|
|
109
109
|
const { schemas: schemasTable } = _ns_1;
|
|
110
110
|
let dbModels = await db
|
|
111
111
|
.select({
|
|
@@ -252,7 +252,7 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context }, self })
|
|
|
252
252
|
// Step 2: Fallback to Schema context (only if database doesn't have the model)
|
|
253
253
|
// This handles the case where model exists in schema file but not yet in database
|
|
254
254
|
try {
|
|
255
|
-
const _mod_2 = await import('./Schema-
|
|
255
|
+
const _mod_2 = await import('./Schema-Dc5EA8Yb.js');
|
|
256
256
|
const _ns_2 = _mod_2.b;
|
|
257
257
|
const schemaMod = _ns_2;
|
|
258
258
|
const { Schema } = schemaMod;
|
|
@@ -403,12 +403,12 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context }, self })
|
|
|
403
403
|
}
|
|
404
404
|
// Also check database for models (in case they're persisted but not in Schema context)
|
|
405
405
|
if (db) {
|
|
406
|
-
const _mod_3 = await import('./BasePathResolver-
|
|
407
|
-
const _ns_3 = _mod_3.
|
|
406
|
+
const _mod_3 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
407
|
+
const _ns_3 = _mod_3.b1;
|
|
408
408
|
const modelSchemaSchemaMod = _ns_3;
|
|
409
409
|
const { modelSchemas } = modelSchemaSchemaMod;
|
|
410
|
-
const _mod_4 = await import('./BasePathResolver-
|
|
411
|
-
const _ns_4 = _mod_4.
|
|
410
|
+
const _mod_4 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
411
|
+
const _ns_4 = _mod_4.b0;
|
|
412
412
|
const schemaSchemaMod = _ns_4;
|
|
413
413
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
414
414
|
// Query all models for this schema to check for duplicates (case-insensitive)
|
|
@@ -503,7 +503,7 @@ const loadOrCreateModel = fromCallback(({ sendBack, input: { context }, self })
|
|
|
503
503
|
}
|
|
504
504
|
// Mark schema as draft when a new model is created so saveNewVersion() can persist it
|
|
505
505
|
try {
|
|
506
|
-
const _mod_5 = await import('./Schema-
|
|
506
|
+
const _mod_5 = await import('./Schema-Dc5EA8Yb.js');
|
|
507
507
|
const _ns_5 = _mod_5.b;
|
|
508
508
|
const schemaMod = _ns_5;
|
|
509
509
|
const { Schema } = schemaMod;
|
|
@@ -551,10 +551,10 @@ const validateModel = fromCallback(({ sendBack, input: { context }, self }) => {
|
|
|
551
551
|
const _validateModel = async () => {
|
|
552
552
|
try {
|
|
553
553
|
// Use dynamic imports to break circular dependencies
|
|
554
|
-
const validationServiceMod = await import('./SchemaValidationService-
|
|
554
|
+
const validationServiceMod = await import('./SchemaValidationService-DViJ056F.js');
|
|
555
555
|
const { SchemaValidationService } = validationServiceMod;
|
|
556
556
|
const validationService = new SchemaValidationService();
|
|
557
|
-
const _mod_6 = await import('./Schema-
|
|
557
|
+
const _mod_6 = await import('./Schema-Dc5EA8Yb.js');
|
|
558
558
|
const _ns_6 = _mod_6.b;
|
|
559
559
|
const schemaMod = _ns_6;
|
|
560
560
|
const { Schema } = schemaMod;
|
|
@@ -673,7 +673,7 @@ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
|
|
|
673
673
|
return;
|
|
674
674
|
}
|
|
675
675
|
logger$5(`Creating ${Object.keys(propertyDefinitions).length} properties for model "${modelName}" (id: ${_dbId})`);
|
|
676
|
-
const mod = await import('./ModelProperty-
|
|
676
|
+
const mod = await import('./ModelProperty-DuuoFXaC.js');
|
|
677
677
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
678
678
|
if (!ModelProperty) {
|
|
679
679
|
logger$5('ModelProperty not available from dynamic import');
|
|
@@ -698,8 +698,8 @@ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
|
|
|
698
698
|
: undefined;
|
|
699
699
|
// Otherwise use provided ID or generate a random one
|
|
700
700
|
// IDs should be generated in the import process before creating properties
|
|
701
|
-
const _mod_7 = await import('./BasePathResolver-
|
|
702
|
-
const _ns_7 = _mod_7.
|
|
701
|
+
const _mod_7 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
702
|
+
const _ns_7 = _mod_7.b5;
|
|
703
703
|
const { generateId } = _ns_7;
|
|
704
704
|
const propertyFileId = propData.id || propertyRecord?.schemaFileId || generateId();
|
|
705
705
|
logger$5(`Creating property "${propName}" with fileId "${propertyFileId}"`);
|
|
@@ -716,8 +716,8 @@ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
|
|
|
716
716
|
}
|
|
717
717
|
else if (refModelName) {
|
|
718
718
|
// Fallback: resolve the ref by name within this model's schema
|
|
719
|
-
const _mod_8 = await import('./BasePathResolver-
|
|
720
|
-
const _ns_8 = _mod_8.
|
|
719
|
+
const _mod_8 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
720
|
+
const _ns_8 = _mod_8.b2;
|
|
721
721
|
const { resolveModelRecord } = _ns_8;
|
|
722
722
|
const refModelRecord = await resolveModelRecord(refModelName, { schemaName }, db);
|
|
723
723
|
if (refModelRecord?.id) {
|
|
@@ -754,6 +754,10 @@ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
|
|
|
754
754
|
localStorageDir: propData.localStorageDir ?? propertyRecord?.localStorageDir ?? undefined,
|
|
755
755
|
filenameSuffix: propData.filenameSuffix ?? propertyRecord?.filenameSuffix ?? undefined,
|
|
756
756
|
required: propData.required,
|
|
757
|
+
// Rules defined in code live only on the instance (the properties table has no column
|
|
758
|
+
// for them); getPropertySchema reads them from here when no schema file has them.
|
|
759
|
+
validation: propData.validation,
|
|
760
|
+
htmlEmbeddedDataUriPolicy: propData.htmlEmbeddedDataUriPolicy,
|
|
757
761
|
_propertyFileId: propertyFileId, // Store schemaFileId for getById() lookups
|
|
758
762
|
_dbId: propertyRecord?.schemaFileId === propertyFileId ? propertyRecord.id : undefined, // Already persisted: skip the write
|
|
759
763
|
}, { schemaName }); // Use 'as any' because _propertyFileId is not in TProperty type
|
|
@@ -785,6 +789,12 @@ const createModelProperties = fromCallback(({ sendBack, input, self }) => {
|
|
|
785
789
|
*/
|
|
786
790
|
let epoch = 0;
|
|
787
791
|
const lastEvictionBySchema = new Map();
|
|
792
|
+
// Schemas whose destroy() is still running (by name)
|
|
793
|
+
const destroyingSchemas = new Map();
|
|
794
|
+
// Single models destroyed (Model.destroy), by modelFileId
|
|
795
|
+
const lastDestroyByModelId = new Map();
|
|
796
|
+
// Models whose destroy() is still deleting their rows
|
|
797
|
+
const destroyingModelIds = new Map();
|
|
788
798
|
function currentEvictionEpoch() {
|
|
789
799
|
return epoch;
|
|
790
800
|
}
|
|
@@ -793,15 +803,73 @@ function recordSchemaEviction(schemaName) {
|
|
|
793
803
|
epoch += 1;
|
|
794
804
|
lastEvictionBySchema.set(schemaName, epoch);
|
|
795
805
|
}
|
|
796
|
-
/**
|
|
806
|
+
/**
|
|
807
|
+
* Called by Schema.destroy before it evicts the schema's models; `finishSchemaDestroy` once its rows
|
|
808
|
+
* are gone. The schema's actor stays live until then, and work it starts meanwhile (its live query
|
|
809
|
+
* reading a model row the drained write just landed) captures an epoch after the eviction, so the
|
|
810
|
+
* epoch alone can't tell it to stay away.
|
|
811
|
+
*/
|
|
812
|
+
function recordSchemaDestroy(schemaName) {
|
|
813
|
+
recordSchemaEviction(schemaName);
|
|
814
|
+
destroyingSchemas.set(schemaName, (destroyingSchemas.get(schemaName) ?? 0) + 1);
|
|
815
|
+
}
|
|
816
|
+
function finishSchemaDestroy(schemaName) {
|
|
817
|
+
const remaining = (destroyingSchemas.get(schemaName) ?? 1) - 1;
|
|
818
|
+
if (remaining > 0)
|
|
819
|
+
destroyingSchemas.set(schemaName, remaining);
|
|
820
|
+
else
|
|
821
|
+
destroyingSchemas.delete(schemaName);
|
|
822
|
+
// Work that read a row during the destroy and checks after it must still see the eviction
|
|
823
|
+
recordSchemaEviction(schemaName);
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* True when the schema is being destroyed, or its instances were evicted after `since` (an epoch
|
|
827
|
+
* from currentEvictionEpoch).
|
|
828
|
+
*/
|
|
797
829
|
function schemaEvictedSince(schemaName, since) {
|
|
798
|
-
if (
|
|
830
|
+
if (!schemaName)
|
|
831
|
+
return false;
|
|
832
|
+
if (destroyingSchemas.has(schemaName))
|
|
833
|
+
return true;
|
|
834
|
+
if (epoch === since)
|
|
799
835
|
return false;
|
|
800
836
|
return (lastEvictionBySchema.get(schemaName) ?? 0) > since;
|
|
801
837
|
}
|
|
802
|
-
/**
|
|
838
|
+
/**
|
|
839
|
+
* Called by Model.destroy before it clears the caches; `finishModelDestroy` once its rows are gone.
|
|
840
|
+
* Until then a lookup by id still finds the row, so it must not re-cache the model either.
|
|
841
|
+
*/
|
|
842
|
+
function recordModelDestroy(modelFileId) {
|
|
843
|
+
epoch += 1;
|
|
844
|
+
lastDestroyByModelId.set(modelFileId, epoch);
|
|
845
|
+
destroyingModelIds.set(modelFileId, (destroyingModelIds.get(modelFileId) ?? 0) + 1);
|
|
846
|
+
}
|
|
847
|
+
function finishModelDestroy(modelFileId) {
|
|
848
|
+
const remaining = (destroyingModelIds.get(modelFileId) ?? 1) - 1;
|
|
849
|
+
if (remaining > 0)
|
|
850
|
+
destroyingModelIds.set(modelFileId, remaining);
|
|
851
|
+
else
|
|
852
|
+
destroyingModelIds.delete(modelFileId);
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* True when the model is being destroyed, or was destroyed after `since` (an epoch from
|
|
856
|
+
* currentEvictionEpoch): a lookup that read its row must not create or cache an instance.
|
|
857
|
+
*/
|
|
858
|
+
function modelDestroyedSince(modelFileId, since) {
|
|
859
|
+
if (!modelFileId)
|
|
860
|
+
return false;
|
|
861
|
+
if (destroyingModelIds.has(modelFileId))
|
|
862
|
+
return true;
|
|
863
|
+
if (epoch === since)
|
|
864
|
+
return false;
|
|
865
|
+
return (lastDestroyByModelId.get(modelFileId) ?? 0) > since;
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* True when any schema was evicted after `since` or is being destroyed (cheap check before looking up
|
|
869
|
+
* which schemas apply).
|
|
870
|
+
*/
|
|
803
871
|
function anyEvictionSince(since) {
|
|
804
|
-
return epoch !== since;
|
|
872
|
+
return epoch !== since || destroyingSchemas.size > 0;
|
|
805
873
|
}
|
|
806
874
|
|
|
807
875
|
const logger$4 = debug('seedSdk:write:validateEntity');
|
|
@@ -817,7 +885,7 @@ const validateEntity = fromPromise(async ({ input }) => {
|
|
|
817
885
|
const evictionEpoch = currentEvictionEpoch();
|
|
818
886
|
/** The schema to validate against; throws (validation then skips the schema check) once it was evicted. */
|
|
819
887
|
const schemaForValidation = async (schemaName) => {
|
|
820
|
-
const _mod_9 = await import('./Schema-
|
|
888
|
+
const _mod_9 = await import('./Schema-Dc5EA8Yb.js');
|
|
821
889
|
const _ns_9 = _mod_9.b;
|
|
822
890
|
const { Schema } = _ns_9;
|
|
823
891
|
if (schemaEvictedSince(schemaName, evictionEpoch)) {
|
|
@@ -835,7 +903,7 @@ const validateEntity = fromPromise(async ({ input }) => {
|
|
|
835
903
|
const structureMsg = `[validateEntity] Validating model structure`;
|
|
836
904
|
logger$4(structureMsg);
|
|
837
905
|
// Use existing Model validation
|
|
838
|
-
const validationServiceMod = await import('./SchemaValidationService-
|
|
906
|
+
const validationServiceMod = await import('./SchemaValidationService-DViJ056F.js');
|
|
839
907
|
const { SchemaValidationService } = validationServiceMod;
|
|
840
908
|
const validationService = new SchemaValidationService();
|
|
841
909
|
// Validate model structure
|
|
@@ -885,7 +953,7 @@ const validateEntity = fromPromise(async ({ input }) => {
|
|
|
885
953
|
}
|
|
886
954
|
else if (entityInput.entityType === 'modelProperty') {
|
|
887
955
|
// Use existing ModelProperty validation
|
|
888
|
-
const validationServiceMod = await import('./SchemaValidationService-
|
|
956
|
+
const validationServiceMod = await import('./SchemaValidationService-DViJ056F.js');
|
|
889
957
|
const { SchemaValidationService } = validationServiceMod;
|
|
890
958
|
const validationService = new SchemaValidationService();
|
|
891
959
|
// Validate property structure
|
|
@@ -925,7 +993,7 @@ const validateEntity = fromPromise(async ({ input }) => {
|
|
|
925
993
|
}
|
|
926
994
|
else if (entityInput.entityType === 'schema') {
|
|
927
995
|
// Schema validation - use existing validation
|
|
928
|
-
const validationServiceMod = await import('./SchemaValidationService-
|
|
996
|
+
const validationServiceMod = await import('./SchemaValidationService-DViJ056F.js');
|
|
929
997
|
const { SchemaValidationService } = validationServiceMod;
|
|
930
998
|
const validationService = new SchemaValidationService();
|
|
931
999
|
const schemaResult = validationService.validateSchema(entityInput.entityData);
|
|
@@ -1014,7 +1082,7 @@ const writeToDatabase = fromCallback(({ sendBack, input }) => {
|
|
|
1014
1082
|
// initial write completes is not overwritten by the stale requestWrite payload.
|
|
1015
1083
|
let dataToWrite = input.entityData;
|
|
1016
1084
|
try {
|
|
1017
|
-
const mod = await import('./ModelProperty-
|
|
1085
|
+
const mod = await import('./ModelProperty-DuuoFXaC.js');
|
|
1018
1086
|
const ModelProperty = mod?.ModelProperty ?? mod?.default;
|
|
1019
1087
|
if (ModelProperty && typeof ModelProperty.getById === 'function') {
|
|
1020
1088
|
const instance = ModelProperty.getById(input.entityId);
|
|
@@ -1408,7 +1476,7 @@ const modelMachine = setup({
|
|
|
1408
1476
|
// Create ModelProperty instances for any new property IDs
|
|
1409
1477
|
if (Array.isArray(newPropertyIds) && newPropertyIds.length > 0) {
|
|
1410
1478
|
// Import and create instances asynchronously (fire-and-forget)
|
|
1411
|
-
import('./ModelProperty-
|
|
1479
|
+
import('./ModelProperty-DuuoFXaC.js').then(({ ModelProperty }) => {
|
|
1412
1480
|
if (self.getSnapshot().status === 'stopped')
|
|
1413
1481
|
return;
|
|
1414
1482
|
const createPromises = newPropertyIds.map(async (propertyFileId) => {
|
|
@@ -1908,12 +1976,33 @@ const getModelsData = async (schemaIdentifier) => {
|
|
|
1908
1976
|
return rows;
|
|
1909
1977
|
};
|
|
1910
1978
|
|
|
1979
|
+
/**
|
|
1980
|
+
* Errors from draft saves that assignment starts in the background (schema/model renames and
|
|
1981
|
+
* tracked-property edits). Nothing awaits those saves, so the error is kept for `lastSaveError`
|
|
1982
|
+
* instead of only being logged. Keyed by the instance's service, which the instance and its
|
|
1983
|
+
* proxy share.
|
|
1984
|
+
*/
|
|
1985
|
+
const draftSaveErrors = new WeakMap();
|
|
1986
|
+
function getDraftSaveError(service) {
|
|
1987
|
+
return draftSaveErrors.get(service);
|
|
1988
|
+
}
|
|
1989
|
+
/** Run a background draft save, recording its failure (or clearing an earlier one on success). */
|
|
1990
|
+
function trackDraftSave(service, save, label) {
|
|
1991
|
+
save.then(() => {
|
|
1992
|
+
draftSaveErrors.delete(service);
|
|
1993
|
+
}, (error) => {
|
|
1994
|
+
const recorded = error instanceof Error ? error : new Error(String(error));
|
|
1995
|
+
draftSaveErrors.set(service, recorded);
|
|
1996
|
+
console.warn(`[seed] ${label}: draft save failed (see lastSaveError):`, recorded.message);
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
|
|
1911
2000
|
const logger = debug('seedSdk:model:Model');
|
|
1912
2001
|
const saveDraftLogger = debug('seedSdk:model:saveDraftToDb');
|
|
1913
2002
|
// Lazy import cache for ModelProperty to avoid circular dependency
|
|
1914
2003
|
// Eagerly start loading to minimize delay on first access
|
|
1915
2004
|
let ModelPropertyClass = null;
|
|
1916
|
-
const modelPropertyImportPromise = import('./ModelProperty-
|
|
2005
|
+
const modelPropertyImportPromise = import('./ModelProperty-DuuoFXaC.js')
|
|
1917
2006
|
.then(module => {
|
|
1918
2007
|
ModelPropertyClass = module.ModelProperty;
|
|
1919
2008
|
return ModelPropertyClass;
|
|
@@ -2356,9 +2445,7 @@ class Model {
|
|
|
2356
2445
|
propertyKey: 'modelName',
|
|
2357
2446
|
});
|
|
2358
2447
|
// Save draft to database immediately so changes persist
|
|
2359
|
-
target._saveDraftToDb(oldName, newName)
|
|
2360
|
-
logger(`Failed to save draft to database: ${error instanceof Error ? error.message : String(error)}`);
|
|
2361
|
-
});
|
|
2448
|
+
trackDraftSave(target._service, target._saveDraftToDb(oldName, newName), `Model "${newName}"`);
|
|
2362
2449
|
// NOTE: Schema is not notified of model name changes during edits.
|
|
2363
2450
|
// Schema will read from Model instances when persisting/saving.
|
|
2364
2451
|
}
|
|
@@ -2868,9 +2955,11 @@ class Model {
|
|
|
2868
2955
|
.limit(1);
|
|
2869
2956
|
const record = rows[0];
|
|
2870
2957
|
if (record?.modelName && record.schemaName && record.modelFileId) {
|
|
2871
|
-
// Its schema was evicted while we read the row: don't bring
|
|
2958
|
+
// Its schema was evicted, or it was destroyed, while we read the row: don't bring it back.
|
|
2872
2959
|
if (schemaEvictedSince(record.schemaName, evictionEpoch))
|
|
2873
2960
|
return undefined;
|
|
2961
|
+
if (modelDestroyedSince(record.modelFileId, evictionEpoch))
|
|
2962
|
+
return undefined;
|
|
2874
2963
|
return this.create(record.modelName, record.schemaName, { id: record.modelFileId });
|
|
2875
2964
|
}
|
|
2876
2965
|
}
|
|
@@ -2904,8 +2993,8 @@ class Model {
|
|
|
2904
2993
|
const evictionEpoch = options?.evictionEpoch ?? currentEvictionEpoch();
|
|
2905
2994
|
try {
|
|
2906
2995
|
// Query model by name (throws AmbiguousModelError when several schemas define it)
|
|
2907
|
-
const _mod_10 = await import('./BasePathResolver-
|
|
2908
|
-
const _ns_10 = _mod_10.
|
|
2996
|
+
const _mod_10 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
2997
|
+
const _ns_10 = _mod_10.b2;
|
|
2909
2998
|
const { resolveModelRecord } = _ns_10;
|
|
2910
2999
|
const resolved = await resolveModelRecord(modelName, {}, db);
|
|
2911
3000
|
if (!resolved?.schemaFileId) {
|
|
@@ -2929,10 +3018,13 @@ class Model {
|
|
|
2929
3018
|
if (!record.modelName || !record.schemaName || !record.modelFileId) {
|
|
2930
3019
|
return undefined;
|
|
2931
3020
|
}
|
|
2932
|
-
// Its schema was evicted while we read the row: don't bring
|
|
3021
|
+
// Its schema was evicted, or it was destroyed, while we read the row: don't bring it back.
|
|
2933
3022
|
if (schemaEvictedSince(record.schemaName, evictionEpoch)) {
|
|
2934
3023
|
return undefined;
|
|
2935
3024
|
}
|
|
3025
|
+
if (modelDestroyedSince(record.modelFileId, evictionEpoch)) {
|
|
3026
|
+
return undefined;
|
|
3027
|
+
}
|
|
2936
3028
|
// Create model instance (will be cached)
|
|
2937
3029
|
return this.create(record.modelName, record.schemaName, {
|
|
2938
3030
|
id: record.modelFileId, // id is now the schemaFileId (string)
|
|
@@ -2999,6 +3091,11 @@ class Model {
|
|
|
2999
3091
|
logger(`Model.createById: schema "${schemaName}" was evicted during the lookup of "${modelFileId}"`);
|
|
3000
3092
|
return undefined;
|
|
3001
3093
|
}
|
|
3094
|
+
// Destroyed while we read the row: destroy() clears the caches before it deletes the rows
|
|
3095
|
+
if (modelDestroyedSince(modelFileId, evictionEpoch)) {
|
|
3096
|
+
logger(`Model.createById: model "${modelFileId}" was destroyed during the lookup`);
|
|
3097
|
+
return undefined;
|
|
3098
|
+
}
|
|
3002
3099
|
// Step 3: Create model using existing create method (which will handle caching)
|
|
3003
3100
|
logger(`Model.createById: Creating model "${modelName}" in schema "${schemaName}" from ID "${modelFileId}"`);
|
|
3004
3101
|
return this.create(modelName, schemaName, {
|
|
@@ -3076,10 +3173,13 @@ class Model {
|
|
|
3076
3173
|
if (!record.modelName || !record.schemaName || !record.modelFileId) {
|
|
3077
3174
|
continue;
|
|
3078
3175
|
}
|
|
3079
|
-
// Its schema was evicted while we read the rows: don't bring
|
|
3176
|
+
// Its schema was evicted, or the model destroyed, while we read the rows: don't bring it back.
|
|
3080
3177
|
if (schemaEvictedSince(record.schemaName, evictionEpoch)) {
|
|
3081
3178
|
continue;
|
|
3082
3179
|
}
|
|
3180
|
+
if (modelDestroyedSince(record.modelFileId, evictionEpoch)) {
|
|
3181
|
+
continue;
|
|
3182
|
+
}
|
|
3083
3183
|
// Check cache first
|
|
3084
3184
|
const cached = this.getById(record.modelFileId);
|
|
3085
3185
|
if (cached) {
|
|
@@ -3373,6 +3473,10 @@ class Model {
|
|
|
3373
3473
|
get status() {
|
|
3374
3474
|
return this._getSnapshot().value;
|
|
3375
3475
|
}
|
|
3476
|
+
/** The error from the last draft save a rename started, or undefined once a later one succeeds. */
|
|
3477
|
+
get lastSaveError() {
|
|
3478
|
+
return getDraftSaveError(this._service);
|
|
3479
|
+
}
|
|
3376
3480
|
get validationErrors() {
|
|
3377
3481
|
return this._getSnapshotContext()._validationErrors || [];
|
|
3378
3482
|
}
|
|
@@ -3611,6 +3715,9 @@ class Model {
|
|
|
3611
3715
|
const schemaName = context.schemaName;
|
|
3612
3716
|
const nameKey = schemaName && modelName ? `${schemaName}:${modelName}` : '';
|
|
3613
3717
|
clearDestroySubscriptions(this, { instanceState: modelInstanceState });
|
|
3718
|
+
// Before the caches are cleared, so a lookup by id already reading the row doesn't re-cache it
|
|
3719
|
+
if (modelFileId)
|
|
3720
|
+
recordModelDestroy(modelFileId);
|
|
3614
3721
|
const cacheKeys = [];
|
|
3615
3722
|
if (modelFileId)
|
|
3616
3723
|
cacheKeys.push(modelFileId);
|
|
@@ -3624,7 +3731,7 @@ class Model {
|
|
|
3624
3731
|
Model.instanceCache,
|
|
3625
3732
|
],
|
|
3626
3733
|
});
|
|
3627
|
-
|
|
3734
|
+
const destroying = runDestroyLifecycle(this, {
|
|
3628
3735
|
getService: (instance) => instance._service,
|
|
3629
3736
|
doDestroy: async () => {
|
|
3630
3737
|
const db = BaseDb.getAppDb();
|
|
@@ -3638,7 +3745,7 @@ class Model {
|
|
|
3638
3745
|
.limit(1);
|
|
3639
3746
|
if (modelRecords.length > 0) {
|
|
3640
3747
|
const modelId = modelRecords[0].id;
|
|
3641
|
-
const { detachModelRows } = await import('./detachRowsBeforeDelete-
|
|
3748
|
+
const { detachModelRows } = await import('./detachRowsBeforeDelete-YRSZY6dO.js');
|
|
3642
3749
|
await detachModelRows(db, [typeof modelId === 'string' ? parseInt(modelId, 10) : modelId]);
|
|
3643
3750
|
await db.delete(modelSchemas).where(eq(modelSchemas.modelId, modelId));
|
|
3644
3751
|
await db
|
|
@@ -3649,7 +3756,7 @@ class Model {
|
|
|
3649
3756
|
}
|
|
3650
3757
|
if (schemaName && modelName) {
|
|
3651
3758
|
// Imported here, not at module load: Model and Schema import each other.
|
|
3652
|
-
const _mod_11 = await import('./Schema-
|
|
3759
|
+
const _mod_11 = await import('./Schema-Dc5EA8Yb.js');
|
|
3653
3760
|
const _ns_11 = _mod_11.b;
|
|
3654
3761
|
const { Schema } = _ns_11;
|
|
3655
3762
|
const schema = Schema.create(schemaName, { waitForReady: false });
|
|
@@ -3664,6 +3771,13 @@ class Model {
|
|
|
3664
3771
|
}
|
|
3665
3772
|
},
|
|
3666
3773
|
});
|
|
3774
|
+
try {
|
|
3775
|
+
await destroying;
|
|
3776
|
+
}
|
|
3777
|
+
finally {
|
|
3778
|
+
if (modelFileId)
|
|
3779
|
+
finishModelDestroy(modelFileId);
|
|
3780
|
+
}
|
|
3667
3781
|
}
|
|
3668
3782
|
/**
|
|
3669
3783
|
* Set up liveQuery subscription to watch for property changes in the database
|
|
@@ -3686,8 +3800,8 @@ class Model {
|
|
|
3686
3800
|
return undefined;
|
|
3687
3801
|
}
|
|
3688
3802
|
// Model names are only unique per schema: find this model's row by its id (schemaFileId).
|
|
3689
|
-
const _mod_12 = await import('./BasePathResolver-
|
|
3690
|
-
const _ns_12 = _mod_12.
|
|
3803
|
+
const _mod_12 = await import('./BasePathResolver-DxdS0wJ0.js');
|
|
3804
|
+
const _ns_12 = _mod_12.b2;
|
|
3691
3805
|
const { resolveModelRecord } = _ns_12;
|
|
3692
3806
|
const modelRecord = await resolveModelRecord(modelName, { modelFileId: context.id, schemaName: context.schemaName }, db);
|
|
3693
3807
|
if (!modelRecord?.id) {
|
|
@@ -3891,5 +4005,35 @@ var Model$1 = /*#__PURE__*/Object.freeze({
|
|
|
3891
4005
|
const TModelValues = Type.Record(Type.String(), Type.Any());
|
|
3892
4006
|
const TModelSchema = Type.Record(Type.String(), TProperty);
|
|
3893
4007
|
|
|
3894
|
-
|
|
3895
|
-
|
|
4008
|
+
/**
|
|
4009
|
+
* Thrown by Item.create when values don't fit the model: unknown keys, wrong types, or values
|
|
4010
|
+
* that break the property's validation rules. Nothing is written.
|
|
4011
|
+
*/
|
|
4012
|
+
class ItemCreateValidationError extends Error {
|
|
4013
|
+
constructor(modelName, problems) {
|
|
4014
|
+
super(`Cannot create ${modelName}: ` + problems.map((p) => `${p.property}: ${p.message}`).join('; '));
|
|
4015
|
+
this.name = 'ItemCreateValidationError';
|
|
4016
|
+
this.modelName = modelName;
|
|
4017
|
+
this.problems = problems;
|
|
4018
|
+
Object.setPrototypeOf(this, ItemCreateValidationError.prototype);
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
/** Thrown by Item.create when no model with that name exists (in the given schema, if any). */
|
|
4022
|
+
class UnknownModelError extends Error {
|
|
4023
|
+
constructor(modelName, schemaName) {
|
|
4024
|
+
super(`Model "${modelName}" not found${schemaName ? ` in schema "${schemaName}"` : ''}.`);
|
|
4025
|
+
this.name = 'UnknownModelError';
|
|
4026
|
+
this.modelName = modelName;
|
|
4027
|
+
this.schemaName = schemaName;
|
|
4028
|
+
Object.setPrototypeOf(this, UnknownModelError.prototype);
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
var errors = /*#__PURE__*/Object.freeze({
|
|
4033
|
+
__proto__: null,
|
|
4034
|
+
ItemCreateValidationError: ItemCreateValidationError,
|
|
4035
|
+
UnknownModelError: UnknownModelError
|
|
4036
|
+
});
|
|
4037
|
+
|
|
4038
|
+
export { ConflictError as C, ItemCreateValidationError as I, Model as M, TModelSchema as T, UnknownModelError as U, TModelValues as a, anyEvictionSince as b, currentEvictionEpoch as c, setupEntityLiveQuery as d, writeToDatabase$1 as e, finishSchemaDestroy as f, getDraftSaveError as g, Model$1 as h, isActorStopped as i, errors as j, recordSchemaDestroy as r, schemaEvictedSince as s, trackDraftSave as t, writeProcessMachine as w };
|
|
4039
|
+
//# sourceMappingURL=errors-Cl8rbtKR.js.map
|