@seedprotocol/sdk 0.7.3-next.613.g79a8dfd → 0.7.4-next.711.gce2b766
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/{db-CQt-gcAl.js → BasePathResolver-Cm4apKRb.js} +2041 -127
- package/dist/BasePathResolver-Cm4apKRb.js.map +1 -0
- package/dist/{ClientManager-DDA9956Y.js → ClientManager-i3nJASkg.js} +664 -277
- package/dist/ClientManager-i3nJASkg.js.map +1 -0
- package/dist/{Item-D4FigtYS.js → Item-DBFchXpC.js} +495 -219
- package/dist/Item-DBFchXpC.js.map +1 -0
- package/dist/{ModelProperty-BDt6AU2h.js → ModelProperty-BS49g01Y.js} +167 -47
- package/dist/ModelProperty-BS49g01Y.js.map +1 -0
- package/dist/{Schema-B8xqLWkL.js → Schema-CpMNEnUO.js} +53 -42
- package/dist/Schema-CpMNEnUO.js.map +1 -0
- package/dist/{SchemaValidationService-BPxkfDLU.js → SchemaValidationService-DieV4KL-.js} +13 -14
- package/dist/{SchemaValidationService-BPxkfDLU.js.map → SchemaValidationService-DieV4KL-.js.map} +1 -1
- package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js → backfillMetadataPropertyIds-DSoOoTnX.js} +14 -7
- package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js.map → backfillMetadataPropertyIds-DSoOoTnX.js.map} +1 -1
- package/dist/{configurePlatform-YcOiDQBZ.js → configurePlatform-D0lQGAMQ.js} +8 -7
- package/dist/{configurePlatform-YcOiDQBZ.js.map → configurePlatform-D0lQGAMQ.js.map} +1 -1
- package/dist/detachRowsBeforeDelete-S0q-DJPT.js +50 -0
- package/dist/detachRowsBeforeDelete-S0q-DJPT.js.map +1 -0
- package/dist/{eas-CpOD74Ke.js → eas-6pjU-OuX.js} +9 -8
- package/dist/eas-6pjU-OuX.js.map +1 -0
- package/dist/{getItem-B_OoFkd7.js → getItem-CxBNZ-WL.js} +13 -11
- package/dist/{getItem-B_OoFkd7.js.map → getItem-CxBNZ-WL.js.map} +1 -1
- package/dist/{getPublishPayload-Xl3sRkR-.js → getPublishPayload-CTCvRUoU.js} +50 -18
- package/dist/getPublishPayload-CTCvRUoU.js.map +1 -0
- package/dist/getPublishUploads-SFHCbf_y.js +648 -0
- package/dist/getPublishUploads-SFHCbf_y.js.map +1 -0
- package/dist/{index-Xl1_4Lmb.js → index-8O3Uow-Y.js} +125 -57
- package/dist/index-8O3Uow-Y.js.map +1 -0
- package/dist/{index-CSOQFAOn.js → index-AVFTVp1m.js} +2 -2
- package/dist/index-AVFTVp1m.js.map +1 -0
- package/dist/index-Cvt5UBz4.js +30 -0
- package/dist/index-Cvt5UBz4.js.map +1 -0
- package/dist/{index.browser-CjTe0vt1.js → index.browser-DBhxRoe8.js} +554 -165
- package/dist/index.browser-DBhxRoe8.js.map +1 -0
- package/dist/{index.node-Cfa7npS6.js → index.node-CJhlcNHM.js} +25 -13
- package/dist/index.node-CJhlcNHM.js.map +1 -0
- package/dist/main.js +30 -47
- package/dist/main.js.map +1 -1
- package/dist/mimeTypes-DHAHC4eZ.js +204 -0
- package/dist/mimeTypes-DHAHC4eZ.js.map +1 -0
- package/dist/node.js +19 -21
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +13 -11
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.node.js +18 -5
- package/dist/platform.node.js.map +1 -1
- package/dist/{property-BrXkY1Rg.js → property-DwPD283A.js} +14 -12
- package/dist/property-DwPD283A.js.map +1 -0
- package/dist/{publishDraftGraph-X0Wr9txE.js → publishDraftGraph-BOn3_Occ.js} +6 -9
- package/dist/{publishDraftGraph-X0Wr9txE.js.map → publishDraftGraph-BOn3_Occ.js.map} +1 -1
- package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js → resetAmbiguousLegacyItemData-BkYmBeJc.js} +14 -3
- package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js.map → resetAmbiguousLegacyItemData-BkYmBeJc.js.map} +1 -1
- package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js → resolveModelForSyncedSeed-BL24nLa7.js} +2 -2
- package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js.map → resolveModelForSyncedSeed-BL24nLa7.js.map} +1 -1
- package/dist/src/Item/Item.d.ts +21 -3
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/Item/service/actors/runPublish.d.ts +11 -2
- package/dist/src/Item/service/actors/runPublish.d.ts.map +1 -1
- package/dist/src/Item/service/itemMachineSingle.d.ts +12 -2
- package/dist/src/Item/service/itemMachineSingle.d.ts.map +1 -1
- package/dist/src/ItemProperty/ItemProperty.d.ts +5 -3
- package/dist/src/ItemProperty/ItemProperty.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/saveItemStorage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
- package/dist/src/Model/Model.d.ts +10 -4
- package/dist/src/Model/Model.d.ts.map +1 -1
- package/dist/src/Model/index.d.ts +2 -2
- package/dist/src/ModelProperty/ModelProperty.d.ts +10 -2
- package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
- package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +3 -0
- package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts.map +1 -1
- package/dist/src/Schema/Schema.d.ts +2 -2
- package/dist/src/Schema/Schema.d.ts.map +1 -1
- package/dist/src/Schema/index.d.ts +0 -1
- package/dist/src/Schema/index.d.ts.map +1 -1
- package/dist/src/browser/helpers/FileManager.d.ts +4 -1
- package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts +79 -4
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -1
- package/dist/src/browser/workers/FileDownloader.d.ts +19 -4
- package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
- package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
- package/dist/src/client/ClientManager.d.ts +30 -11
- package/dist/src/client/ClientManager.d.ts.map +1 -1
- package/dist/src/client/actors/platformClassesInit.d.ts +6 -0
- package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
- package/dist/src/client/actors/processSchemaFiles.d.ts.map +1 -1
- package/dist/src/client/actors/saveConfig.d.ts +13 -6
- package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
- package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
- package/dist/src/db/migrateLegacyItemStorageRows.d.ts +57 -0
- package/dist/src/db/migrateLegacyItemStorageRows.d.ts.map +1 -0
- package/dist/src/db/read/getCompositeChildPaths.d.ts +13 -0
- package/dist/src/db/read/getCompositeChildPaths.d.ts.map +1 -0
- package/dist/src/db/read/getItems.d.ts.map +1 -1
- package/dist/src/db/read/getPublishPayload.d.ts +1 -1
- package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
- package/dist/src/db/read/getPublishUploads.d.ts +32 -3
- package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
- package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
- package/dist/src/db/write/claimUnpublishedDrafts.d.ts +2 -0
- package/dist/src/db/write/claimUnpublishedDrafts.d.ts.map +1 -1
- package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts +44 -0
- package/dist/src/db/write/convertVerbatimItemStorageRow.d.ts.map +1 -0
- package/dist/src/db/write/createNewItem.d.ts.map +1 -1
- package/dist/src/eventBus.d.ts +5 -0
- package/dist/src/eventBus.d.ts.map +1 -1
- package/dist/src/events/files/download.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts +3 -3
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/IFileManager.d.ts +25 -1
- package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
- package/dist/src/helpers/arweaveContentTags.d.ts +33 -0
- package/dist/src/helpers/arweaveContentTags.d.ts.map +1 -0
- package/dist/src/helpers/cachedPropertyRefresh.d.ts +12 -0
- package/dist/src/helpers/cachedPropertyRefresh.d.ts.map +1 -0
- package/dist/src/helpers/compositeUpload.d.ts +28 -0
- package/dist/src/helpers/compositeUpload.d.ts.map +1 -0
- package/dist/src/helpers/db.d.ts +3 -0
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/easSdk.d.ts +16 -0
- package/dist/src/helpers/easSdk.d.ts.map +1 -0
- package/dist/src/helpers/entity/detachRowsBeforeDelete.d.ts +16 -0
- package/dist/src/helpers/entity/detachRowsBeforeDelete.d.ts.map +1 -0
- package/dist/src/helpers/entity/entityDestroy.d.ts +2 -0
- package/dist/src/helpers/entity/entityDestroy.d.ts.map +1 -1
- package/dist/src/helpers/itemStorageFile.d.ts +57 -0
- package/dist/src/helpers/itemStorageFile.d.ts.map +1 -0
- package/dist/src/helpers/mapWithConcurrency.d.ts +7 -0
- package/dist/src/helpers/mapWithConcurrency.d.ts.map +1 -0
- package/dist/src/helpers/mimeTypes.d.ts +43 -0
- package/dist/src/helpers/mimeTypes.d.ts.map +1 -0
- package/dist/src/helpers/ownership.d.ts +28 -4
- package/dist/src/helpers/ownership.d.ts.map +1 -1
- package/dist/src/helpers/property/index.d.ts +37 -51
- package/dist/src/helpers/property/index.d.ts.map +1 -1
- package/dist/src/helpers/publishConfig.d.ts +27 -8
- package/dist/src/helpers/publishConfig.d.ts.map +1 -1
- package/dist/src/helpers/storageDir.d.ts +16 -0
- package/dist/src/helpers/storageDir.d.ts.map +1 -0
- package/dist/src/helpers/tabCoordinator.d.ts +5 -1
- package/dist/src/helpers/tabCoordinator.d.ts.map +1 -1
- package/dist/src/helpers/tabEvents.d.ts +23 -2
- package/dist/src/helpers/tabEvents.d.ts.map +1 -1
- package/dist/src/helpers/updateSchema.d.ts +5 -0
- package/dist/src/helpers/updateSchema.d.ts.map +1 -1
- package/dist/src/helpers/waitForEntityIdle.d.ts +5 -0
- package/dist/src/helpers/waitForEntityIdle.d.ts.map +1 -1
- package/dist/src/imports/json.d.ts +9 -0
- package/dist/src/imports/json.d.ts.map +1 -1
- package/dist/src/index.d.ts +11 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/interfaces/IItem.d.ts +7 -1
- package/dist/src/interfaces/IItem.d.ts.map +1 -1
- package/dist/src/node/db/Db.d.ts.map +1 -1
- package/dist/src/node/helpers/PathResolver.d.ts.map +1 -1
- package/dist/src/node/index.d.ts +8 -1
- package/dist/src/node/index.d.ts.map +1 -1
- package/dist/src/platform/index.browser.d.ts +2 -0
- package/dist/src/platform/index.browser.d.ts.map +1 -1
- package/dist/src/platform/index.node.d.ts +2 -0
- package/dist/src/platform/index.node.d.ts.map +1 -1
- package/dist/src/types/fileManager.d.ts +3 -14
- package/dist/src/types/fileManager.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +12 -1
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/machines.d.ts +2 -0
- package/dist/src/types/machines.d.ts.map +1 -1
- package/dist/src/types/property.d.ts +8 -0
- package/dist/src/types/property.d.ts.map +1 -1
- package/dist/src/types/publish.d.ts +14 -0
- package/dist/src/types/publish.d.ts.map +1 -1
- package/dist/{syncDbWithEas-BU-jZ5bJ.js → syncDbWithEas-Bv2Fe38J.js} +17 -17
- package/dist/{syncDbWithEas-BU-jZ5bJ.js.map → syncDbWithEas-Bv2Fe38J.js.map} +1 -1
- package/dist/tabEvents-9s2WCYw-.js +335 -0
- package/dist/tabEvents-9s2WCYw-.js.map +1 -0
- package/dist/tolerantWebAccess-iUu80pAP.js +551 -0
- package/dist/tolerantWebAccess-iUu80pAP.js.map +1 -0
- package/dist/{updateSeedRevokedAt-iLpzae1i.js → updateSeedRevokedAt-zBfi931j.js} +3 -3
- package/dist/{updateSeedRevokedAt-iLpzae1i.js.map → updateSeedRevokedAt-zBfi931j.js.map} +1 -1
- package/package.json +11 -12
- package/src/node/easLodashRegister.js +4 -0
- package/dist/BasePathResolver-BdxCSIzn.js +0 -679
- package/dist/BasePathResolver-BdxCSIzn.js.map +0 -1
- package/dist/ClientManager-DDA9956Y.js.map +0 -1
- package/dist/Item-D4FigtYS.js.map +0 -1
- package/dist/ModelProperty-BDt6AU2h.js.map +0 -1
- package/dist/Schema-B8xqLWkL.js.map +0 -1
- package/dist/cjs/ModelProperty-B-cZm1yU.js +0 -1977
- package/dist/cjs/ModelProperty-B-cZm1yU.js.map +0 -1
- package/dist/cjs/Schema-STP972Xw.js +0 -5256
- package/dist/cjs/Schema-STP972Xw.js.map +0 -1
- package/dist/cjs/SchemaValidationService-CKNW1bKg.js +0 -778
- package/dist/cjs/SchemaValidationService-CKNW1bKg.js.map +0 -1
- package/dist/cjs/backfillMetadataPropertyIds-CP3y1skt.js +0 -89
- package/dist/cjs/backfillMetadataPropertyIds-CP3y1skt.js.map +0 -1
- package/dist/cjs/eas-CAnUC4wd.js +0 -138
- package/dist/cjs/eas-CAnUC4wd.js.map +0 -1
- package/dist/cjs/getItem-CWgb3e9G.js +0 -58
- package/dist/cjs/getItem-CWgb3e9G.js.map +0 -1
- package/dist/cjs/getPublishPayload-BsZWiJ03.js +0 -1603
- package/dist/cjs/getPublishPayload-BsZWiJ03.js.map +0 -1
- package/dist/cjs/getPublishUploads-BQr8aMVP.js +0 -495
- package/dist/cjs/getPublishUploads-BQr8aMVP.js.map +0 -1
- package/dist/cjs/index-nA5PxBSs.js +0 -70
- package/dist/cjs/index-nA5PxBSs.js.map +0 -1
- package/dist/cjs/index-usKaANAq.js +0 -22171
- package/dist/cjs/index-usKaANAq.js.map +0 -1
- package/dist/cjs/index.browser-BSf8HpnU.js +0 -22
- package/dist/cjs/index.browser-BSf8HpnU.js.map +0 -1
- package/dist/cjs/property-xMwPhQ5N.js +0 -327
- package/dist/cjs/property-xMwPhQ5N.js.map +0 -1
- package/dist/cjs/publishDraftGraph-BRWlR1KO.js +0 -403
- package/dist/cjs/publishDraftGraph-BRWlR1KO.js.map +0 -1
- package/dist/cjs/resetAmbiguousLegacyItemData-8nfkj9rz.js +0 -116
- package/dist/cjs/resetAmbiguousLegacyItemData-8nfkj9rz.js.map +0 -1
- package/dist/cjs/resolveModelForSyncedSeed-kYRuDWYw.js +0 -49
- package/dist/cjs/resolveModelForSyncedSeed-kYRuDWYw.js.map +0 -1
- package/dist/cjs/syncDbWithEas-DqRhV8o2.js +0 -886
- package/dist/cjs/syncDbWithEas-DqRhV8o2.js.map +0 -1
- package/dist/db-CQt-gcAl.js.map +0 -1
- package/dist/eas-CpOD74Ke.js.map +0 -1
- package/dist/getPublishPayload-Xl3sRkR-.js.map +0 -1
- package/dist/getPublishUploads-DHP01KgU.js +0 -484
- package/dist/getPublishUploads-DHP01KgU.js.map +0 -1
- package/dist/index-BGt4_oPO.js +0 -31
- package/dist/index-BGt4_oPO.js.map +0 -1
- package/dist/index-CSOQFAOn.js.map +0 -1
- package/dist/index-Xl1_4Lmb.js.map +0 -1
- package/dist/index.browser-CjTe0vt1.js.map +0 -1
- package/dist/index.node-Cfa7npS6.js.map +0 -1
- package/dist/main.cjs +0 -84
- package/dist/main.cjs.map +0 -1
- package/dist/property-BrXkY1Rg.js.map +0 -1
- package/dist/tabEvents-BZJMY5uK.js +0 -1344
- package/dist/tabEvents-BZJMY5uK.js.map +0 -1
- package/dist/tolerantWebAccess-BZ2RA_mb.js +0 -160
- package/dist/tolerantWebAccess-BZ2RA_mb.js.map +0 -1
|
@@ -1,17 +1,16 @@
|
|
|
1
|
+
import { startCase, isEqual } from 'lodash-es';
|
|
2
|
+
import { E as BaseDb, l as easSyncProcesses, G as eventEmitter, a8 as isNode, ah as isBrowser, I as BasePathResolver, aA as normalizeAddressConfig, h as appState, aL as downloadAllFilesRequestHandler, aM as downloadAllFilesBinaryRequestHandler, J as BaseFileManager, H as toSnakeCase, s as models$1, r as modelUids, A as seeds, aB as normalizeAddressList, z as schemas, aK as loadModelsFromDbForSchema, aI as addSchemaToDb, aF as isInternalSchema, aN as INTERNAL_SCHEMA_IDS, $ as generateId, aO as linkModelToSchema, n as normalizeDataType, aq as SEED_PROTOCOL_SCHEMA_NAME, q as modelSchemas, m as metadata$1, u as properties, L as resolveItemModelFileId, C as versions, o as htmlEmbeddedImageCoPublish, j as arweaveL1FinalizeJobs, y as publishProcesses, X as normalizePublisher, aP as getWatchedAddressesFromDb, aQ as getOwnedAddressesFromDb, aR as CLIENT_NOT_INITIALIZED } from './BasePathResolver-Cm4apKRb.js';
|
|
1
3
|
import debug from 'debug';
|
|
2
4
|
import { createActor, setup, assign, fromPromise, fromCallback, waitFor } from 'xstate';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { a as
|
|
6
|
-
import { eq, inArray, and, isNotNull, ne, desc, countDistinct, like, or, isNull } from 'drizzle-orm';
|
|
7
|
-
import { q as withDbTabLock, k as isLeaderTab, x as postTabMessage, y as onTabMessage, w as whenLeaderTab, z as listenForOtherTabsEvents, B as isNode, C as isBrowser, D as startTabCoordination, E as downloadAllFilesRequestHandler, G as downloadAllFilesBinaryRequestHandler, t as toSnakeCase, v as withSeedDbLock, b as generateId, p as parseAddressesPersistedPayload, e as emitAcrossTabs, A as ADDRESSES_PERSISTED_EVENT, L as LOCAL_COPIES_REMOVED_EVENT } from './tabEvents-BZJMY5uK.js';
|
|
5
|
+
import { x as MachineIds, a2 as ClientManagerEvents, a3 as withLockedItemStorageRow, a4 as getItemStorageFilePath, a5 as writeItemStorageFile, c as compareMetadataRowsLatestFirst, C as ClientManagerState, a6 as resolvePublisherFromSeedRow, J as isLocalUnsealedDraft, I as Item } from './Item-DBFchXpC.js';
|
|
6
|
+
import { eq, inArray, and, isNotNull, ne, desc, countDistinct, isNull, or, like } from 'drizzle-orm';
|
|
7
|
+
import { a as withDbTabLock, i as isLeaderTab, c as postTabMessage, o as onTabMessage, w as whenLeaderTab, l as listenForOtherTabsEvents, s as startTabCoordination, b as withSeedDbLock, p as parseAddressesPersistedPayload, e as emitAcrossTabs, A as ADDRESSES_PERSISTED_EVENT, L as LOCAL_COPIES_REMOVED_EVENT } from './tabEvents-9s2WCYw-.js';
|
|
8
8
|
import { seedGatewayConfigFromSeedConfig, setPreferredArweaveReadBaseUrls, resolveSeedGatewayEndpoints, setResolvedSeedGatewayEndpoints, BaseArweaveClient, ensureReadGatewaySelected, DEFAULT_ARWEAVE_HOST } from '@seedprotocol/arweave';
|
|
9
9
|
import { configureEasReadChain, BaseQueryClient, BaseEasClient, GET_SCHEMAS, whenEasReadChainSettled, getEasReadChainId, DEFAULT_EAS_CHAIN_ID, isEasReadChainConfigured, isValidEasAttestationUid } from '@seedprotocol/eas';
|
|
10
10
|
import 'pluralize';
|
|
11
11
|
import { sha3_256 } from '@noble/hashes/sha3';
|
|
12
|
-
import {
|
|
12
|
+
import { utf8ToBytes, bytesToHex } from '@noble/hashes/utils';
|
|
13
13
|
import { clearLocalQuerySource, registerLocalQuerySource, getSeed } from '@seedprotocol/query';
|
|
14
|
-
import { startCase } from 'lodash-es';
|
|
15
14
|
|
|
16
15
|
let writeTail = Promise.resolve();
|
|
17
16
|
function enqueueEasSyncDbWrite(fn) {
|
|
@@ -109,7 +108,7 @@ const runEasSync = fromPromise(async ({ input, }) => {
|
|
|
109
108
|
requestPayload: input.requestPayload,
|
|
110
109
|
persistedSnapshot: input.runningSnapshot,
|
|
111
110
|
});
|
|
112
|
-
const { runSyncFromEas } = await import('./syncDbWithEas-
|
|
111
|
+
const { runSyncFromEas } = await import('./syncDbWithEas-Bv2Fe38J.js');
|
|
113
112
|
try {
|
|
114
113
|
// Sync checks for rows and then inserts the rest (no unique index on uids), so syncs in
|
|
115
114
|
// different tabs take turns. A sync can run for minutes, so wait without a timeout.
|
|
@@ -285,7 +284,7 @@ function newCorrelationId() {
|
|
|
285
284
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
286
285
|
}
|
|
287
286
|
/** Requests deferred in this tab until it leads, by source; each runs once on takeover. */
|
|
288
|
-
const deferredUntilLeader = new Set();
|
|
287
|
+
const deferredUntilLeader$1 = new Set();
|
|
289
288
|
/**
|
|
290
289
|
* Automatic syncs run in the leader tab only (docs/MULTI_TAB.md). A tab that skips one runs it if
|
|
291
290
|
* it later becomes leader, so closing the leader doesn't lose the catch-up sync.
|
|
@@ -296,11 +295,11 @@ function runInLeaderTab(source, request) {
|
|
|
296
295
|
return;
|
|
297
296
|
}
|
|
298
297
|
log(`${source} sync skipped: another tab leads`);
|
|
299
|
-
if (deferredUntilLeader.has(source))
|
|
298
|
+
if (deferredUntilLeader$1.has(source))
|
|
300
299
|
return;
|
|
301
|
-
deferredUntilLeader.add(source);
|
|
300
|
+
deferredUntilLeader$1.add(source);
|
|
302
301
|
void whenLeaderTab().then(() => {
|
|
303
|
-
deferredUntilLeader.delete(source);
|
|
302
|
+
deferredUntilLeader$1.delete(source);
|
|
304
303
|
request();
|
|
305
304
|
});
|
|
306
305
|
}
|
|
@@ -374,10 +373,10 @@ var easSyncManager = /*#__PURE__*/Object.freeze({
|
|
|
374
373
|
startEasSyncActor: startEasSyncActor
|
|
375
374
|
});
|
|
376
375
|
|
|
377
|
-
const logger$
|
|
376
|
+
const logger$c = debug('seedSdk:services:events');
|
|
378
377
|
const handleServiceSaveState = (event) => {
|
|
379
378
|
const { state, serviceId } = event;
|
|
380
|
-
logger$
|
|
379
|
+
logger$c(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
|
|
381
380
|
// TODO: This is called from Node as well. Do we need it? If so, need to generalize this to all platforms.
|
|
382
381
|
// localStorage.setItem(`seed_sdk_service_${serviceId}`, JSON.stringify(state))
|
|
383
382
|
};
|
|
@@ -428,9 +427,18 @@ function normalizeSeedConfigEndpoints(config) {
|
|
|
428
427
|
return { ...config, endpoints: next };
|
|
429
428
|
}
|
|
430
429
|
|
|
431
|
-
const logger$
|
|
430
|
+
const logger$b = debug('seedSdk:ClientManager:initialize');
|
|
431
|
+
/**
|
|
432
|
+
* Whether a relative filesDir already names the .seed directory or a path inside
|
|
433
|
+
* it ('.seed', '.seed/files', './.seed/files'). '.seed-alt/x' is not: it is
|
|
434
|
+
* resolved under .seed like any other relative path.
|
|
435
|
+
*/
|
|
436
|
+
function isUnderDotSeed(relativePath) {
|
|
437
|
+
const firstSegment = relativePath.split(/[\\/]+/).find((segment) => segment !== '' && segment !== '.');
|
|
438
|
+
return firstSegment === '.seed';
|
|
439
|
+
}
|
|
432
440
|
const platformClassesInit = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
433
|
-
logger$
|
|
441
|
+
logger$b('initialize from ClientManager');
|
|
434
442
|
const { isInitialized } = context;
|
|
435
443
|
if (!event || !('options' in event)) {
|
|
436
444
|
throw new Error('Initialize event must include options');
|
|
@@ -463,7 +471,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
463
471
|
}
|
|
464
472
|
// Prefer the condition-resolved factory when available; fall back to explicit
|
|
465
473
|
// platform imports so source/vitest resolution stays reliable.
|
|
466
|
-
const { configurePlatform } = await import('./configurePlatform-
|
|
474
|
+
const { configurePlatform } = await import('./configurePlatform-D0lQGAMQ.js');
|
|
467
475
|
if (isBrowser()) {
|
|
468
476
|
const { createPlatformServices } = await import('./platform.browser.js');
|
|
469
477
|
configurePlatform(createPlatformServices());
|
|
@@ -526,8 +534,8 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
526
534
|
normalizedFilesDir = path.join(dotSeedDir, dirName);
|
|
527
535
|
}
|
|
528
536
|
else if (!path.isAbsolute(normalizedFilesDir)) {
|
|
529
|
-
// If it's a relative path, check if it already
|
|
530
|
-
if (
|
|
537
|
+
// If it's a relative path, check if it is already under .seed
|
|
538
|
+
if (isUnderDotSeed(normalizedFilesDir)) {
|
|
531
539
|
// Already relative to project root, resolve it
|
|
532
540
|
normalizedFilesDir = path.resolve(normalizedFilesDir);
|
|
533
541
|
}
|
|
@@ -550,6 +558,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
550
558
|
gatewaySidecarPort: gatewayConfig.hyper?.localSidecarPort,
|
|
551
559
|
gatewayProxyBaseUrl: resolvedGateway.proxyBaseUrl ?? gatewayConfig.proxyBaseUrl,
|
|
552
560
|
addresses: normalizedAddresses.owned,
|
|
561
|
+
addressesProvided: addresses !== undefined,
|
|
553
562
|
ownedAddresses: normalizedAddresses.owned,
|
|
554
563
|
watchedAddresses: normalizedAddresses.watched,
|
|
555
564
|
filesDir: normalizedFilesDir,
|
|
@@ -602,7 +611,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
602
611
|
};
|
|
603
612
|
});
|
|
604
613
|
|
|
605
|
-
const logger$
|
|
614
|
+
const logger$a = debug('seedSdk:client:writeToDb');
|
|
606
615
|
const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
607
616
|
const _saveAppState = async () => {
|
|
608
617
|
try {
|
|
@@ -610,7 +619,7 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
610
619
|
if (!appDb) {
|
|
611
620
|
// In test environments, continue anyway
|
|
612
621
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
613
|
-
logger$
|
|
622
|
+
logger$a('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
|
|
614
623
|
return;
|
|
615
624
|
}
|
|
616
625
|
throw new Error('App DB not found');
|
|
@@ -626,13 +635,13 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
626
635
|
value: JSON.stringify(value),
|
|
627
636
|
},
|
|
628
637
|
});
|
|
629
|
-
logger$
|
|
638
|
+
logger$a('result', result);
|
|
630
639
|
}
|
|
631
640
|
catch (error) {
|
|
632
|
-
logger$
|
|
641
|
+
logger$a('[client/actors] [saveAppState] Error saving app state:', error);
|
|
633
642
|
// In test environments, continue anyway
|
|
634
643
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
635
|
-
logger$
|
|
644
|
+
logger$a('[client/actors] [saveAppState] Continuing despite error in test environment');
|
|
636
645
|
return;
|
|
637
646
|
}
|
|
638
647
|
throw error;
|
|
@@ -647,10 +656,10 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
647
656
|
});
|
|
648
657
|
})
|
|
649
658
|
.catch((error) => {
|
|
650
|
-
logger$
|
|
659
|
+
logger$a('[client/actors] [saveAppState] Error in promise chain:', error);
|
|
651
660
|
// In test environments, still send success to allow state machine to progress
|
|
652
661
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
653
|
-
logger$
|
|
662
|
+
logger$a('[client/actors] [saveAppState] Sending success despite error in test environment');
|
|
654
663
|
sendBack({
|
|
655
664
|
type: 'saveAppStateSuccess',
|
|
656
665
|
key,
|
|
@@ -720,7 +729,7 @@ const fileSystemInit = fromCallback(({ sendBack, input: { context }, }) => {
|
|
|
720
729
|
};
|
|
721
730
|
});
|
|
722
731
|
|
|
723
|
-
const logger$
|
|
732
|
+
const logger$9 = debug('seedSdk:client:actors:dbInit');
|
|
724
733
|
const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
725
734
|
const _dbInit = async () => {
|
|
726
735
|
const { filesDir } = context;
|
|
@@ -734,14 +743,14 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
734
743
|
if (!appDb) {
|
|
735
744
|
throw new Error('Database not available after preparation');
|
|
736
745
|
}
|
|
737
|
-
logger$
|
|
746
|
+
logger$9('[client/actors] [dbInit] Database prepared and ready');
|
|
738
747
|
};
|
|
739
748
|
_dbInit()
|
|
740
749
|
.then(() => {
|
|
741
750
|
sendBack({ type: ClientManagerEvents.DB_READY });
|
|
742
751
|
})
|
|
743
752
|
.catch((error) => {
|
|
744
|
-
logger$
|
|
753
|
+
logger$9('Error in dbInit:', error);
|
|
745
754
|
sendBack({
|
|
746
755
|
type: 'error',
|
|
747
756
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -749,7 +758,7 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
749
758
|
});
|
|
750
759
|
});
|
|
751
760
|
|
|
752
|
-
const logger$
|
|
761
|
+
const logger$8 = debug('seedSdk:client:actors:addModelsToStore');
|
|
753
762
|
const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
754
763
|
const _addModelsToStore = async () => {
|
|
755
764
|
let { models } = context;
|
|
@@ -763,7 +772,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
763
772
|
// Models are now Model instances, no registration needed
|
|
764
773
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
765
774
|
for (const [key] of Object.entries(allModels)) {
|
|
766
|
-
logger$
|
|
775
|
+
logger$8('model available:', key);
|
|
767
776
|
}
|
|
768
777
|
};
|
|
769
778
|
_addModelsToStore()
|
|
@@ -771,7 +780,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
771
780
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_STORE_SUCCESS });
|
|
772
781
|
})
|
|
773
782
|
.catch((error) => {
|
|
774
|
-
logger$
|
|
783
|
+
logger$8('[client/actors] [addModelsToStore] Error:', error);
|
|
775
784
|
sendBack({
|
|
776
785
|
type: 'error',
|
|
777
786
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -779,7 +788,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
779
788
|
});
|
|
780
789
|
});
|
|
781
790
|
|
|
782
|
-
const logger$
|
|
791
|
+
const logger$7 = debug('seedSdk:client:actors:addModelsToDb');
|
|
783
792
|
/**
|
|
784
793
|
* Returns every `models` row named in `modelNames`, inserting a null-schemaFileId stub for each name
|
|
785
794
|
* with no row yet (the schema import adopts stubs via findOrCreateModelRecord). Check-then-insert:
|
|
@@ -802,7 +811,7 @@ async function ensureModelStubs(appDb, modelNames, filesDir) {
|
|
|
802
811
|
.returning({ id: models$1.id, name: models$1.name, schemaFileId: models$1.schemaFileId }));
|
|
803
812
|
rows.push(...newlyInserted);
|
|
804
813
|
for (const name of modelsToInsert) {
|
|
805
|
-
logger$
|
|
814
|
+
logger$7('[client/actors] [addModelsToDb] inserted model:', name);
|
|
806
815
|
}
|
|
807
816
|
}
|
|
808
817
|
return rows;
|
|
@@ -839,7 +848,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
839
848
|
for (const modelName of modelNames) {
|
|
840
849
|
const foundModel = rowFor(modelName);
|
|
841
850
|
if (!foundModel) {
|
|
842
|
-
logger$
|
|
851
|
+
logger$7('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
|
|
843
852
|
hasModelsInDb = false;
|
|
844
853
|
continue;
|
|
845
854
|
}
|
|
@@ -851,7 +860,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
851
860
|
}
|
|
852
861
|
// If we have no models to process, still send success (empty models is valid)
|
|
853
862
|
if (schemaDefsByModelName.size === 0) {
|
|
854
|
-
logger$
|
|
863
|
+
logger$7('[client/actors] [addModelsToDb] No models to process, but continuing');
|
|
855
864
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
856
865
|
return;
|
|
857
866
|
}
|
|
@@ -894,15 +903,15 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
894
903
|
requestEasSyncFromModelsInit();
|
|
895
904
|
}
|
|
896
905
|
else {
|
|
897
|
-
logger$
|
|
906
|
+
logger$7('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
|
|
898
907
|
}
|
|
899
908
|
}
|
|
900
909
|
catch (error) {
|
|
901
910
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
902
|
-
logger$
|
|
911
|
+
logger$7('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
|
|
903
912
|
}
|
|
904
913
|
else {
|
|
905
|
-
logger$
|
|
914
|
+
logger$7('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
|
|
906
915
|
}
|
|
907
916
|
}
|
|
908
917
|
};
|
|
@@ -914,10 +923,10 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
914
923
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
915
924
|
})
|
|
916
925
|
.catch((error) => {
|
|
917
|
-
logger$
|
|
926
|
+
logger$7('[client/actors] [addModelsToDb] Error:', error);
|
|
918
927
|
// In test environments, still send success to allow initialization to complete
|
|
919
928
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
920
|
-
logger$
|
|
929
|
+
logger$7('[client/actors] [addModelsToDb] Continuing despite error in test environment');
|
|
921
930
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
922
931
|
}
|
|
923
932
|
else {
|
|
@@ -930,7 +939,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
930
939
|
return () => { };
|
|
931
940
|
});
|
|
932
941
|
|
|
933
|
-
const logger$
|
|
942
|
+
const logger$6 = debug('seedSdk:helpers:localDbChain');
|
|
934
943
|
/** appState key recording which EAS chain the local database holds attestations from. */
|
|
935
944
|
const EAS_CHAIN_ID_APP_STATE_KEY = 'easChainId';
|
|
936
945
|
/**
|
|
@@ -1000,7 +1009,7 @@ async function loadLocalDbChain() {
|
|
|
1000
1009
|
const localChainId = await resolveLocalDbChainId(appDb);
|
|
1001
1010
|
if (localChainId !== undefined) {
|
|
1002
1011
|
configureEasReadChain('localDb', { chainId: localChainId });
|
|
1003
|
-
logger$
|
|
1012
|
+
logger$6('local DB holds chain %d', localChainId);
|
|
1004
1013
|
return;
|
|
1005
1014
|
}
|
|
1006
1015
|
if (isEasReadChainConfigured()) {
|
|
@@ -1026,15 +1035,33 @@ async function assertLocalDbChain() {
|
|
|
1026
1035
|
configureEasReadChain('localDb', { chainId: localChainId ?? chainId });
|
|
1027
1036
|
}
|
|
1028
1037
|
|
|
1029
|
-
const logger$
|
|
1038
|
+
const logger$5 = debug('seedSdk:client:actors:saveConfig');
|
|
1039
|
+
let warnedKeptStoredAddresses = false;
|
|
1030
1040
|
/**
|
|
1031
|
-
* Saves the addresses passed to init.
|
|
1032
|
-
*
|
|
1033
|
-
*
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
1041
|
+
* Saves the addresses passed to init.
|
|
1042
|
+
*
|
|
1043
|
+
* - No `addresses` option (`addressesProvided: false`): stored addresses are kept, with a
|
|
1044
|
+
* one-time warning when there are any, since a forgotten option would otherwise act on
|
|
1045
|
+
* an earlier session's wallet.
|
|
1046
|
+
* - `addresses: []`: hosts pass this before a wallet connects. In the first (leader) tab it
|
|
1047
|
+
* clears stored addresses, so drafts made before the wallet reconnects stay editable. A tab
|
|
1048
|
+
* opened while another is running (`keepStoredWhenEmpty`) keeps them instead: they're the
|
|
1049
|
+
* other tab's connected wallet, which EAS sync, downloads and publishing read. See
|
|
1050
|
+
* docs/MULTI_TAB.md.
|
|
1036
1051
|
*/
|
|
1037
|
-
async function persistInitAddresses(appDb, { addresses, ownedAddresses, watchedAddresses }, { keepStoredWhenEmpty }) {
|
|
1052
|
+
async function persistInitAddresses(appDb, { addresses, addressesProvided, ownedAddresses, watchedAddresses, }, { keepStoredWhenEmpty }) {
|
|
1053
|
+
if (addressesProvided === false) {
|
|
1054
|
+
if (!warnedKeptStoredAddresses) {
|
|
1055
|
+
const rows = await appDb.select().from(appState).where(eq(appState.key, 'addresses')).limit(1);
|
|
1056
|
+
const stored = rows[0]?.value ? normalizeAddressConfig(JSON.parse(rows[0].value)) : undefined;
|
|
1057
|
+
if (stored && (stored.owned.length > 0 || stored.watched.length > 0)) {
|
|
1058
|
+
warnedKeptStoredAddresses = true;
|
|
1059
|
+
console.warn(`[seed] client.init was called without \`addresses\`, so the stored addresses are kept ` +
|
|
1060
|
+
`(${stored.owned.length} owned, ${stored.watched.length} watched). Pass \`addresses: []\` to clear them.`);
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1038
1065
|
const owned = normalizeAddressList(ownedAddresses ?? addresses ?? []);
|
|
1039
1066
|
const watched = normalizeAddressList(watchedAddresses ?? []);
|
|
1040
1067
|
if (owned.length === 0 && watched.length === 0 && keepStoredWhenEmpty)
|
|
@@ -1046,13 +1073,13 @@ async function persistInitAddresses(appDb, { addresses, ownedAddresses, watchedA
|
|
|
1046
1073
|
.onConflictDoUpdate({ target: appState.key, set: { value } });
|
|
1047
1074
|
}
|
|
1048
1075
|
const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
1049
|
-
logger$
|
|
1050
|
-
const { endpoints, addresses, ownedAddresses, watchedAddresses, arweaveDomain, uploadApiBaseUrl, gatewayTransport, gatewayHyperKey, gatewaySidecarHost, gatewaySidecarPort, gatewayProxyBaseUrl, } = context;
|
|
1076
|
+
logger$5('saveConfig starting');
|
|
1077
|
+
const { endpoints, addresses, addressesProvided, ownedAddresses, watchedAddresses, arweaveDomain, uploadApiBaseUrl, gatewayTransport, gatewayHyperKey, gatewaySidecarHost, gatewaySidecarPort, gatewayProxyBaseUrl, } = context;
|
|
1051
1078
|
// Validate endpoints - required for proper initialization
|
|
1052
1079
|
// If endpoints are missing or invalid, initialization should fail
|
|
1053
1080
|
if (!endpoints || !endpoints.filePaths || !endpoints.files) {
|
|
1054
1081
|
const error = new Error('saveConfig called with invalid endpoints: endpoints must include both filePaths and files');
|
|
1055
|
-
logger$
|
|
1082
|
+
logger$5('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
|
|
1056
1083
|
throw error;
|
|
1057
1084
|
}
|
|
1058
1085
|
const _saveConfig = async () => {
|
|
@@ -1061,7 +1088,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1061
1088
|
if (!appDb) {
|
|
1062
1089
|
// In test environments, continue anyway
|
|
1063
1090
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1064
|
-
logger$
|
|
1091
|
+
logger$5('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
|
|
1065
1092
|
return;
|
|
1066
1093
|
}
|
|
1067
1094
|
throw new Error('App DB not found');
|
|
@@ -1080,7 +1107,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1080
1107
|
value: endpointsValueString,
|
|
1081
1108
|
},
|
|
1082
1109
|
});
|
|
1083
|
-
await persistInitAddresses(appDb, { addresses, ownedAddresses, watchedAddresses }, { keepStoredWhenEmpty: !isLeaderTab() });
|
|
1110
|
+
await persistInitAddresses(appDb, { addresses, addressesProvided, ownedAddresses, watchedAddresses }, { keepStoredWhenEmpty: !isLeaderTab() });
|
|
1084
1111
|
await appDb
|
|
1085
1112
|
.insert(appState)
|
|
1086
1113
|
.values({
|
|
@@ -1116,10 +1143,10 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1116
1143
|
await loadLocalDbChain();
|
|
1117
1144
|
}
|
|
1118
1145
|
catch (error) {
|
|
1119
|
-
logger$
|
|
1146
|
+
logger$5('[internal/actors] [saveConfig] Error saving config:', error);
|
|
1120
1147
|
// In test environments, continue anyway
|
|
1121
1148
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1122
|
-
logger$
|
|
1149
|
+
logger$5('[internal/actors] [saveConfig] Continuing despite error in test environment');
|
|
1123
1150
|
return;
|
|
1124
1151
|
}
|
|
1125
1152
|
throw error;
|
|
@@ -1128,14 +1155,14 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1128
1155
|
// Init writes run one tab at a time (docs/MULTI_TAB.md).
|
|
1129
1156
|
withSeedDbLock('init', context.filesDir, _saveConfig)
|
|
1130
1157
|
.then(() => {
|
|
1131
|
-
logger$
|
|
1158
|
+
logger$5('[internal/actors] [saveConfig] saveConfig success');
|
|
1132
1159
|
return sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
|
|
1133
1160
|
})
|
|
1134
1161
|
.catch((error) => {
|
|
1135
|
-
logger$
|
|
1162
|
+
logger$5('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
|
|
1136
1163
|
// In test environments, still send success to allow state machine to progress
|
|
1137
1164
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1138
|
-
logger$
|
|
1165
|
+
logger$5('[internal/actors] [saveConfig] Sending success despite error in test environment');
|
|
1139
1166
|
sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
|
|
1140
1167
|
}
|
|
1141
1168
|
else {
|
|
@@ -1148,7 +1175,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1148
1175
|
return () => { };
|
|
1149
1176
|
});
|
|
1150
1177
|
|
|
1151
|
-
const logger$
|
|
1178
|
+
const logger$4 = debug('seedSdk:helpers:schema');
|
|
1152
1179
|
/**
|
|
1153
1180
|
* Sanitize a schema name to be filesystem-safe
|
|
1154
1181
|
* Replaces all special characters (except alphanumeric, hyphens, underscores) with underscores
|
|
@@ -1344,7 +1371,7 @@ async function listCompleteSchemaFiles() {
|
|
|
1344
1371
|
const dirExists = await BaseFileManager.pathExists(workingDir);
|
|
1345
1372
|
if (!dirExists) {
|
|
1346
1373
|
// Directory doesn't exist yet - return empty array (not an error condition)
|
|
1347
|
-
logger$
|
|
1374
|
+
logger$4(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
|
|
1348
1375
|
return [];
|
|
1349
1376
|
}
|
|
1350
1377
|
const files = await fs.promises.readdir(workingDir);
|
|
@@ -1480,7 +1507,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1480
1507
|
}
|
|
1481
1508
|
catch (error) {
|
|
1482
1509
|
// If we can't list schema files (e.g., directory doesn't exist yet), continue without file-based loading
|
|
1483
|
-
logger$
|
|
1510
|
+
logger$4(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
|
|
1484
1511
|
completeSchemaFiles = [];
|
|
1485
1512
|
}
|
|
1486
1513
|
}
|
|
@@ -1533,7 +1560,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1533
1560
|
continue;
|
|
1534
1561
|
}
|
|
1535
1562
|
catch (error) {
|
|
1536
|
-
logger$
|
|
1563
|
+
logger$4(`Error parsing schemaData for ${schemaName}:`, error);
|
|
1537
1564
|
// Fall through to file-based loading
|
|
1538
1565
|
}
|
|
1539
1566
|
}
|
|
@@ -1575,7 +1602,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1575
1602
|
continue;
|
|
1576
1603
|
}
|
|
1577
1604
|
catch (error) {
|
|
1578
|
-
logger$
|
|
1605
|
+
logger$4(`Error loading schema file for ${schemaName}:`, error);
|
|
1579
1606
|
// Fall through to try loading from schemaData if available
|
|
1580
1607
|
}
|
|
1581
1608
|
}
|
|
@@ -1619,7 +1646,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1619
1646
|
continue;
|
|
1620
1647
|
}
|
|
1621
1648
|
catch (error) {
|
|
1622
|
-
logger$
|
|
1649
|
+
logger$4(`Error parsing schemaData for ${schemaName}:`, error);
|
|
1623
1650
|
}
|
|
1624
1651
|
}
|
|
1625
1652
|
}
|
|
@@ -1630,11 +1657,11 @@ async function loadAllSchemasFromDb() {
|
|
|
1630
1657
|
// Only process if not already in result
|
|
1631
1658
|
if (!processedSchemaNames.has(schemaFileInfo.name)) {
|
|
1632
1659
|
if (isInternalSchema(schemaFileInfo.name, schemaFileInfo.schemaFileId)) {
|
|
1633
|
-
logger$
|
|
1660
|
+
logger$4(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
|
|
1634
1661
|
continue;
|
|
1635
1662
|
}
|
|
1636
1663
|
try {
|
|
1637
|
-
logger$
|
|
1664
|
+
logger$4(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
|
|
1638
1665
|
const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
|
|
1639
1666
|
const schemaFile = JSON.parse(content);
|
|
1640
1667
|
// Import this schema to database (mark as non-draft since it's in a file)
|
|
@@ -1654,7 +1681,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1654
1681
|
processedSchemaNames.add(schemaFileInfo.name);
|
|
1655
1682
|
}
|
|
1656
1683
|
catch (error) {
|
|
1657
|
-
logger$
|
|
1684
|
+
logger$4(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
|
|
1658
1685
|
}
|
|
1659
1686
|
}
|
|
1660
1687
|
}
|
|
@@ -1671,7 +1698,7 @@ async function migrateFileSchemasToDb() {
|
|
|
1671
1698
|
if (!db) {
|
|
1672
1699
|
throw new Error('Database not found');
|
|
1673
1700
|
}
|
|
1674
|
-
logger$
|
|
1701
|
+
logger$4('Starting migration of file-based schemas to database');
|
|
1675
1702
|
// Get all complete schema files
|
|
1676
1703
|
const completeSchemas = await listCompleteSchemaFiles();
|
|
1677
1704
|
let migratedCount = 0;
|
|
@@ -1681,7 +1708,7 @@ async function migrateFileSchemasToDb() {
|
|
|
1681
1708
|
const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
|
|
1682
1709
|
const schemaFile = JSON.parse(content);
|
|
1683
1710
|
if (!schemaFile.$schema || !schemaFile.metadata?.name) {
|
|
1684
|
-
logger$
|
|
1711
|
+
logger$4(`Skipping invalid schema file: ${schemaFileInfo.filePath}`);
|
|
1685
1712
|
continue;
|
|
1686
1713
|
}
|
|
1687
1714
|
const schemaName = schemaFile.metadata.name;
|
|
@@ -1703,17 +1730,17 @@ async function migrateFileSchemasToDb() {
|
|
|
1703
1730
|
JSON.stringify(schemaFile, null, 2), // schemaData
|
|
1704
1731
|
false);
|
|
1705
1732
|
migratedCount++;
|
|
1706
|
-
logger$
|
|
1733
|
+
logger$4(`Migrated schema: ${schemaName} v${schemaFile.version}`);
|
|
1707
1734
|
}
|
|
1708
1735
|
else {
|
|
1709
|
-
logger$
|
|
1736
|
+
logger$4(`Schema ${schemaName} already exists in database, skipping`);
|
|
1710
1737
|
}
|
|
1711
1738
|
}
|
|
1712
1739
|
catch (error) {
|
|
1713
|
-
logger$
|
|
1740
|
+
logger$4(`Error migrating schema file ${schemaFileInfo.filePath}:`, error);
|
|
1714
1741
|
}
|
|
1715
1742
|
}
|
|
1716
|
-
logger$
|
|
1743
|
+
logger$4(`Migration complete: ${migratedCount} schemas migrated`);
|
|
1717
1744
|
return migratedCount;
|
|
1718
1745
|
}
|
|
1719
1746
|
/**
|
|
@@ -1768,7 +1795,7 @@ const getDeterministicIdsWithPrefix = (prefix) => {
|
|
|
1768
1795
|
return (suffix) => bytesToHex(prefixHash.clone().update(utf8ToBytes(suffix)).digest()).slice(0, 10);
|
|
1769
1796
|
};
|
|
1770
1797
|
|
|
1771
|
-
const logger$
|
|
1798
|
+
const logger$3 = debug('seedSdk:imports:json');
|
|
1772
1799
|
/**
|
|
1773
1800
|
* Get refValueType from a property object with case-insensitive key lookup.
|
|
1774
1801
|
* Handles refValueType, refvaluetype, ref_value_type, elementType, and legacy items.type / items.Type.
|
|
@@ -1846,8 +1873,8 @@ function getRefValueType(prop) {
|
|
|
1846
1873
|
* @returns Promise that resolves when properties are found, or rejects if not found after max retries
|
|
1847
1874
|
*/
|
|
1848
1875
|
const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10, retryDelay = 100) => {
|
|
1849
|
-
const _mod_0 = await import('./BasePathResolver-
|
|
1850
|
-
const _ns_0 = _mod_0.
|
|
1876
|
+
const _mod_0 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
1877
|
+
const _ns_0 = _mod_0.aZ;
|
|
1851
1878
|
const modelSchemaMod = _ns_0;
|
|
1852
1879
|
const { properties: propertiesTable } = modelSchemaMod;
|
|
1853
1880
|
const drizzleMod = await import('drizzle-orm');
|
|
@@ -1859,11 +1886,11 @@ const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10
|
|
|
1859
1886
|
.where(eq(propertiesTable.modelId, modelId))
|
|
1860
1887
|
.limit(1);
|
|
1861
1888
|
if (props.length > 0) {
|
|
1862
|
-
logger$
|
|
1889
|
+
logger$3(`Verified properties exist for model "${modelName}" (modelId: ${modelId}) after ${attempt + 1} attempt(s)`);
|
|
1863
1890
|
return;
|
|
1864
1891
|
}
|
|
1865
1892
|
if (attempt < maxRetries - 1) {
|
|
1866
|
-
logger$
|
|
1893
|
+
logger$3(`Properties not yet visible for model "${modelName}" (modelId: ${modelId}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`);
|
|
1867
1894
|
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
1868
1895
|
}
|
|
1869
1896
|
}
|
|
@@ -2169,7 +2196,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2169
2196
|
if (parsed.$schema && parsed.metadata) {
|
|
2170
2197
|
// It's already a complete schema format - preserve it (id may be missing, will be generated)
|
|
2171
2198
|
originalSchemaFile = parsed;
|
|
2172
|
-
logger$
|
|
2199
|
+
logger$3(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
|
|
2173
2200
|
}
|
|
2174
2201
|
}
|
|
2175
2202
|
catch {
|
|
@@ -2194,8 +2221,8 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2194
2221
|
// Check DB for existing schema by name+version (same as minimal path)
|
|
2195
2222
|
const db = BaseDb.getAppDb();
|
|
2196
2223
|
if (db) {
|
|
2197
|
-
const _mod_1 = await import('./BasePathResolver-
|
|
2198
|
-
const _ns_1 = _mod_1.
|
|
2224
|
+
const _mod_1 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2225
|
+
const _ns_1 = _mod_1.a$;
|
|
2199
2226
|
const schemaSchemaMod = _ns_1;
|
|
2200
2227
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
2201
2228
|
const drizzleMod = await import('drizzle-orm');
|
|
@@ -2208,16 +2235,16 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2208
2235
|
.limit(1);
|
|
2209
2236
|
if (existingByName.length > 0 && existingByName[0].schemaData) {
|
|
2210
2237
|
const existing = existingByName[0];
|
|
2211
|
-
logger$
|
|
2238
|
+
logger$3(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
|
|
2212
2239
|
const existingSchema = JSON.parse(existing.schemaData);
|
|
2213
2240
|
const contentMatches = compareSchemaContent(schemaFile, existingSchema);
|
|
2214
|
-
logger$
|
|
2241
|
+
logger$3(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
|
|
2215
2242
|
if (contentMatches) {
|
|
2216
2243
|
if (existing.schemaFileId) {
|
|
2217
2244
|
const workingDir = BaseFileManager.getWorkingDir();
|
|
2218
2245
|
const existingFilePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, schemaFile.version ?? version, existing.schemaFileId);
|
|
2219
2246
|
if (await BaseFileManager.pathExists(existingFilePath)) {
|
|
2220
|
-
logger$
|
|
2247
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
|
|
2221
2248
|
return await loadSchemaFromFile(existingFilePath);
|
|
2222
2249
|
}
|
|
2223
2250
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
@@ -2225,7 +2252,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2225
2252
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2226
2253
|
return await loadSchemaFromFile(existingFilePath);
|
|
2227
2254
|
}
|
|
2228
|
-
logger$
|
|
2255
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
|
|
2229
2256
|
return '';
|
|
2230
2257
|
}
|
|
2231
2258
|
}
|
|
@@ -2241,7 +2268,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2241
2268
|
// processSchemaFiles runs multiple times (React StrictMode, app restarts).
|
|
2242
2269
|
if (!schemaFile.id) {
|
|
2243
2270
|
schemaFile.id = await getDeterministicSchemaFileId(schemaFile);
|
|
2244
|
-
logger$
|
|
2271
|
+
logger$3(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
|
|
2245
2272
|
}
|
|
2246
2273
|
// Before generating IDs, check if a file already exists with this schemaFileId
|
|
2247
2274
|
// This handles the case where the schema was already loaded via loadSchemaFromFile
|
|
@@ -2251,7 +2278,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2251
2278
|
const existingFileExists = await BaseFileManager.pathExists(existingFilePath);
|
|
2252
2279
|
if (existingFileExists) {
|
|
2253
2280
|
// File already exists with this schemaFileId - just load it instead of creating a new one
|
|
2254
|
-
logger$
|
|
2281
|
+
logger$3(`Schema file already exists with schemaFileId ${schemaFile.id}, loading it instead of creating new file`);
|
|
2255
2282
|
return await loadSchemaFromFile(existingFilePath);
|
|
2256
2283
|
}
|
|
2257
2284
|
// Generate missing model and property IDs.
|
|
@@ -2262,12 +2289,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2262
2289
|
for (const [modelName, model] of Object.entries(schemaFile.models || {})) {
|
|
2263
2290
|
if (!model.id) {
|
|
2264
2291
|
model.id = getDeterministicId(modelName);
|
|
2265
|
-
logger$
|
|
2292
|
+
logger$3(`Generated deterministic model ID for ${modelName}:`, model.id);
|
|
2266
2293
|
}
|
|
2267
2294
|
for (const [propName, prop] of Object.entries(model.properties || {})) {
|
|
2268
2295
|
if (!prop.id) {
|
|
2269
2296
|
prop.id = getDeterministicId(modelName + propName);
|
|
2270
|
-
logger$
|
|
2297
|
+
logger$3(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
|
|
2271
2298
|
}
|
|
2272
2299
|
}
|
|
2273
2300
|
}
|
|
@@ -2279,8 +2306,8 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2279
2306
|
// For minimal imports: check DB for existing schema before creating new file
|
|
2280
2307
|
const db = BaseDb.getAppDb();
|
|
2281
2308
|
if (db) {
|
|
2282
|
-
const _mod_2 = await import('./BasePathResolver-
|
|
2283
|
-
const _ns_2 = _mod_2.
|
|
2309
|
+
const _mod_2 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2310
|
+
const _ns_2 = _mod_2.a$;
|
|
2284
2311
|
const schemaSchemaMod = _ns_2;
|
|
2285
2312
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
2286
2313
|
const drizzleMod = await import('drizzle-orm');
|
|
@@ -2303,14 +2330,14 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2303
2330
|
const workingDir = BaseFileManager.getWorkingDir();
|
|
2304
2331
|
const existingFilePath = getSchemaFilePath(workingDir, importData.name, version, existing.schemaFileId);
|
|
2305
2332
|
if (await BaseFileManager.pathExists(existingFilePath)) {
|
|
2306
|
-
logger$
|
|
2333
|
+
logger$3(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
|
|
2307
2334
|
return await loadSchemaFromFile(existingFilePath);
|
|
2308
2335
|
}
|
|
2309
2336
|
// File missing but schemaData exists - restore file from schemaData
|
|
2310
2337
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
2311
2338
|
await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
|
|
2312
2339
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2313
|
-
logger$
|
|
2340
|
+
logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
|
|
2314
2341
|
return await loadSchemaFromFile(existingFilePath);
|
|
2315
2342
|
}
|
|
2316
2343
|
// No schemaFileId - restore file from schemaData using id from parsed schema
|
|
@@ -2321,10 +2348,10 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2321
2348
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
2322
2349
|
await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
|
|
2323
2350
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2324
|
-
logger$
|
|
2351
|
+
logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
|
|
2325
2352
|
return await loadSchemaFromFile(existingFilePath);
|
|
2326
2353
|
}
|
|
2327
|
-
logger$
|
|
2354
|
+
logger$3(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
|
|
2328
2355
|
return '';
|
|
2329
2356
|
}
|
|
2330
2357
|
// Content differs - create new version
|
|
@@ -2335,7 +2362,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2335
2362
|
.orderBy(desc(schemasTable.version))
|
|
2336
2363
|
.limit(1);
|
|
2337
2364
|
const newVersion = latestVersionRows.length > 0 ? latestVersionRows[0].version + 1 : version;
|
|
2338
|
-
logger$
|
|
2365
|
+
logger$3(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
|
|
2339
2366
|
schemaFile = transformImportToSchemaFile(importData, newVersion);
|
|
2340
2367
|
version = newVersion;
|
|
2341
2368
|
}
|
|
@@ -2359,7 +2386,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2359
2386
|
// Check if this is an internal SDK schema (should not create files in app directory)
|
|
2360
2387
|
const isInternal = isInternalSchema(schemaFile.metadata.name, schemaFile.id);
|
|
2361
2388
|
if (isInternal) {
|
|
2362
|
-
logger$
|
|
2389
|
+
logger$3(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
|
|
2363
2390
|
// For internal schemas, just load to database and store, don't create file
|
|
2364
2391
|
// Extract schema name and version
|
|
2365
2392
|
const schemaName = schemaFile.metadata?.name;
|
|
@@ -2416,7 +2443,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2416
2443
|
// Use fixed internal schema ID if missing (never generate for internal)
|
|
2417
2444
|
if (!schemaFile.id) {
|
|
2418
2445
|
schemaFile.id = INTERNAL_SCHEMA_IDS[0];
|
|
2419
|
-
logger$
|
|
2446
|
+
logger$3('Using fixed internal schema ID:', schemaFile.id);
|
|
2420
2447
|
}
|
|
2421
2448
|
// Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
|
|
2422
2449
|
// This ensures Model instances are created with correct IDs
|
|
@@ -2426,7 +2453,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2426
2453
|
// Generate model ID if missing
|
|
2427
2454
|
if (!model.id) {
|
|
2428
2455
|
model.id = generateId();
|
|
2429
|
-
logger$
|
|
2456
|
+
logger$3(`Generated model ID for ${modelName}:`, model.id);
|
|
2430
2457
|
// Update the schemaFile object so it's included in schemaData
|
|
2431
2458
|
schemaFile.models[modelName].id = model.id;
|
|
2432
2459
|
}
|
|
@@ -2436,7 +2463,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2436
2463
|
// Generate property ID if missing
|
|
2437
2464
|
if (!prop.id) {
|
|
2438
2465
|
prop.id = generateId();
|
|
2439
|
-
logger$
|
|
2466
|
+
logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
|
|
2440
2467
|
// Update the schemaFile object so it's included in schemaData
|
|
2441
2468
|
schemaFile.models[modelName].properties[propName].id = prop.id;
|
|
2442
2469
|
}
|
|
@@ -2448,7 +2475,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2448
2475
|
}
|
|
2449
2476
|
// Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
|
|
2450
2477
|
const modelDefinitions = await createModelsFromJson(importDataForInternal, modelFileIds, propertyFileIds);
|
|
2451
|
-
logger$
|
|
2478
|
+
logger$3('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
|
|
2452
2479
|
// Convert schema file metadata to schema input for database
|
|
2453
2480
|
const schemaInput = {
|
|
2454
2481
|
name: schemaName,
|
|
@@ -2458,8 +2485,8 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2458
2485
|
updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
|
|
2459
2486
|
};
|
|
2460
2487
|
// Use dynamic import to break circular dependency
|
|
2461
|
-
const _mod_3 = await import('./
|
|
2462
|
-
const _ns_3 = _mod_3.
|
|
2488
|
+
const _mod_3 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2489
|
+
const _ns_3 = _mod_3.b2;
|
|
2463
2490
|
const dbMod = _ns_3;
|
|
2464
2491
|
const { addSchemaToDb, addModelsToDb } = dbMod;
|
|
2465
2492
|
// Try to add schema and models to database if database is available
|
|
@@ -2480,12 +2507,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2480
2507
|
});
|
|
2481
2508
|
// Verify expected models are linked (single attempt - addModelsToDb already confirmed)
|
|
2482
2509
|
const expectedModelNames = Object.keys(schemaFile.models || {});
|
|
2483
|
-
const _mod_4 = await import('./BasePathResolver-
|
|
2484
|
-
const _ns_4 = _mod_4.
|
|
2510
|
+
const _mod_4 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2511
|
+
const _ns_4 = _mod_4.b0;
|
|
2485
2512
|
const modelSchemaSchemaMod = _ns_4;
|
|
2486
2513
|
const { modelSchemas } = modelSchemaSchemaMod;
|
|
2487
|
-
const _mod_5 = await import('./BasePathResolver-
|
|
2488
|
-
const _ns_5 = _mod_5.
|
|
2514
|
+
const _mod_5 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2515
|
+
const _ns_5 = _mod_5.aZ;
|
|
2489
2516
|
const modelSchemaMod = _ns_5;
|
|
2490
2517
|
const { models: modelsTable } = modelSchemaMod;
|
|
2491
2518
|
const drizzleMod = await import('drizzle-orm');
|
|
@@ -2574,12 +2601,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2574
2601
|
}
|
|
2575
2602
|
catch (dbError) {
|
|
2576
2603
|
// Database not available - log warning but continue
|
|
2577
|
-
logger$
|
|
2604
|
+
logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
|
|
2578
2605
|
}
|
|
2579
2606
|
// Models are now Model instances, no registration needed
|
|
2580
2607
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
2581
2608
|
for (const [modelName] of Object.entries(modelDefinitions)) {
|
|
2582
|
-
logger$
|
|
2609
|
+
logger$3('loadSchemaFromFile (internal) - model available:', modelName);
|
|
2583
2610
|
}
|
|
2584
2611
|
// Schema is now saved to database
|
|
2585
2612
|
// useSchemas hook will pick it up via database queries
|
|
@@ -2590,7 +2617,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2590
2617
|
// Ensure schema ID is defined (should always be set by this point, but check for safety)
|
|
2591
2618
|
if (!schemaFile.id) {
|
|
2592
2619
|
schemaFile.id = generateId();
|
|
2593
|
-
logger$
|
|
2620
|
+
logger$3('Generated schema ID before file path creation:', schemaFile.id);
|
|
2594
2621
|
}
|
|
2595
2622
|
// Get the target file path using ID-based naming (preferred)
|
|
2596
2623
|
const filePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, version, schemaFile.id);
|
|
@@ -2609,7 +2636,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2609
2636
|
const data = JSON.parse(content);
|
|
2610
2637
|
if (data.$schema) {
|
|
2611
2638
|
// File is already a complete schema, just load it
|
|
2612
|
-
logger$
|
|
2639
|
+
logger$3(`Schema file ${filePath} already exists and is complete, loading it`);
|
|
2613
2640
|
return await loadSchemaFromFile(filePath);
|
|
2614
2641
|
}
|
|
2615
2642
|
}
|
|
@@ -2627,7 +2654,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2627
2654
|
// Compare schemas structurally
|
|
2628
2655
|
if (compareSchemasStructurally(schemaFile, existingSchema)) {
|
|
2629
2656
|
// Schemas match - just load the existing file
|
|
2630
|
-
logger$
|
|
2657
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${version} already exists with matching content, loading it`);
|
|
2631
2658
|
return await loadSchemaFromFile(filePath);
|
|
2632
2659
|
}
|
|
2633
2660
|
else {
|
|
@@ -2670,7 +2697,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2670
2697
|
* Apply schema and models to the database. Shared by loadSchemaFromFile and syncSchemaFromSource.
|
|
2671
2698
|
* @internal
|
|
2672
2699
|
*/
|
|
2673
|
-
async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds) {
|
|
2700
|
+
async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds, propertyDefinitions) {
|
|
2674
2701
|
const schemaName = schemaFile.metadata?.name;
|
|
2675
2702
|
const version = schemaFile.version;
|
|
2676
2703
|
if (!schemaName) {
|
|
@@ -2683,8 +2710,8 @@ async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, prope
|
|
|
2683
2710
|
createdAt: new Date(schemaFile.metadata.createdAt).getTime(),
|
|
2684
2711
|
updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
|
|
2685
2712
|
};
|
|
2686
|
-
const _mod_6 = await import('./
|
|
2687
|
-
const _ns_6 = _mod_6.
|
|
2713
|
+
const _mod_6 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2714
|
+
const _ns_6 = _mod_6.b2;
|
|
2688
2715
|
const dbMod = _ns_6;
|
|
2689
2716
|
const { addSchemaToDb, addModelsToDb } = dbMod;
|
|
2690
2717
|
const db = BaseDb.getAppDb();
|
|
@@ -2698,6 +2725,7 @@ async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, prope
|
|
|
2698
2725
|
schemaFileId: schemaFile.id,
|
|
2699
2726
|
modelFileIds,
|
|
2700
2727
|
propertyFileIds,
|
|
2728
|
+
propertyDefinitions,
|
|
2701
2729
|
});
|
|
2702
2730
|
await new Promise(resolve => setTimeout(resolve, 200));
|
|
2703
2731
|
}
|
|
@@ -2804,7 +2832,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2804
2832
|
// Generate schema ID if missing (before creating schemaInput)
|
|
2805
2833
|
if (!schemaFile.id) {
|
|
2806
2834
|
schemaFile.id = generateId();
|
|
2807
|
-
logger$
|
|
2835
|
+
logger$3('Generated schema ID for schema file:', schemaFile.id);
|
|
2808
2836
|
}
|
|
2809
2837
|
// Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
|
|
2810
2838
|
// This ensures Model instances are created with correct IDs
|
|
@@ -2814,7 +2842,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2814
2842
|
// Generate model ID if missing
|
|
2815
2843
|
if (!model.id) {
|
|
2816
2844
|
model.id = generateId();
|
|
2817
|
-
logger$
|
|
2845
|
+
logger$3(`Generated model ID for ${modelName}:`, model.id);
|
|
2818
2846
|
// Update the schemaFile object so it's included in schemaData
|
|
2819
2847
|
schemaFile.models[modelName].id = model.id;
|
|
2820
2848
|
}
|
|
@@ -2824,7 +2852,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2824
2852
|
// Generate property ID if missing
|
|
2825
2853
|
if (!prop.id) {
|
|
2826
2854
|
prop.id = generateId();
|
|
2827
|
-
logger$
|
|
2855
|
+
logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
|
|
2828
2856
|
// Update the schemaFile object so it's included in schemaData
|
|
2829
2857
|
schemaFile.models[modelName].properties[propName].id = prop.id;
|
|
2830
2858
|
}
|
|
@@ -2836,19 +2864,26 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2836
2864
|
}
|
|
2837
2865
|
// Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
|
|
2838
2866
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
2839
|
-
logger$
|
|
2867
|
+
logger$3('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
|
|
2840
2868
|
// Try to add schema and models to database if database is available
|
|
2841
2869
|
try {
|
|
2842
2870
|
const db = BaseDb.getAppDb();
|
|
2843
2871
|
if (db) {
|
|
2844
|
-
|
|
2872
|
+
// A model already in the instance cache keeps its old properties (Model.create ignores the
|
|
2873
|
+
// ones passed), so give addModelsToDb this file's definitions: a renamed or changed property
|
|
2874
|
+
// must come from the file, not from the cached model.
|
|
2875
|
+
const propertyDefinitions = new Map(Object.entries(importData.models).map(([modelName, modelDef]) => [
|
|
2876
|
+
modelName,
|
|
2877
|
+
jsonPropertiesToSchemaProperties(modelName, modelDef, propertyFileIds.get(modelName)),
|
|
2878
|
+
]));
|
|
2879
|
+
const { schemaRecord } = await applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds, propertyDefinitions);
|
|
2845
2880
|
// Query the database to get model IDs that were just created
|
|
2846
|
-
const _mod_7 = await import('./BasePathResolver-
|
|
2847
|
-
const _ns_7 = _mod_7.
|
|
2881
|
+
const _mod_7 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2882
|
+
const _ns_7 = _mod_7.b0;
|
|
2848
2883
|
const modelSchemaSchemaMod = _ns_7;
|
|
2849
2884
|
const { modelSchemas } = modelSchemaSchemaMod;
|
|
2850
|
-
const _mod_8 = await import('./BasePathResolver-
|
|
2851
|
-
const _ns_8 = _mod_8.
|
|
2885
|
+
const _mod_8 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2886
|
+
const _ns_8 = _mod_8.aZ;
|
|
2852
2887
|
const modelSchemaMod = _ns_8;
|
|
2853
2888
|
const { models: modelsTable } = modelSchemaMod;
|
|
2854
2889
|
const drizzleMod = await import('drizzle-orm');
|
|
@@ -2895,17 +2930,17 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2895
2930
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
2896
2931
|
}
|
|
2897
2932
|
}
|
|
2898
|
-
logger$
|
|
2933
|
+
logger$3(`Verifying properties: found ${modelLinks.length} model links for schema ${schemaName} (id: ${schemaRecord.id})`);
|
|
2899
2934
|
// If we didn't verify via direct lookup, verify via join table
|
|
2900
2935
|
if (!seedModelId || (seedModel.length === 0 || !seedModel[0].id)) {
|
|
2901
2936
|
const seedModelLink = modelLinks.find((link) => link.modelName === 'Seed');
|
|
2902
2937
|
if (seedModelLink && seedModelLink.modelId) {
|
|
2903
|
-
logger$
|
|
2938
|
+
logger$3(`Verifying properties for Seed model via join table (modelId: ${seedModelLink.modelId})`);
|
|
2904
2939
|
await verifyPropertiesPersisted(db, seedModelLink.modelId, 'Seed', 10, 100);
|
|
2905
2940
|
}
|
|
2906
2941
|
else if (modelLinks.length > 0 && modelLinks[0].modelId) {
|
|
2907
2942
|
// Fallback to first model if Seed not found
|
|
2908
|
-
logger$
|
|
2943
|
+
logger$3(`Verifying properties for ${modelLinks[0].modelName} model via join table (modelId: ${modelLinks[0].modelId})`);
|
|
2909
2944
|
await verifyPropertiesPersisted(db, modelLinks[0].modelId, modelLinks[0].modelName || 'unknown', 10, 100);
|
|
2910
2945
|
}
|
|
2911
2946
|
}
|
|
@@ -2913,8 +2948,8 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2913
2948
|
// After properties are created (file path), ensure schemaFile has the correct IDs from database
|
|
2914
2949
|
// Query the database to get the actual schemaFileId values that were used
|
|
2915
2950
|
// This ensures schemaData matches what's actually in the database
|
|
2916
|
-
const _mod_9 = await import('./BasePathResolver-
|
|
2917
|
-
const _ns_9 = _mod_9.
|
|
2951
|
+
const _mod_9 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2952
|
+
const _ns_9 = _mod_9.aZ;
|
|
2918
2953
|
const modelSchemaMod2 = _ns_9;
|
|
2919
2954
|
const { properties: propertiesTable } = modelSchemaMod2;
|
|
2920
2955
|
let schemaFileUpdated = false;
|
|
@@ -2938,7 +2973,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2938
2973
|
const currentId = schemaFile.models[modelName].properties[propRecord.name].id;
|
|
2939
2974
|
if (currentId !== propRecord.schemaFileId) {
|
|
2940
2975
|
schemaFile.models[modelName].properties[propRecord.name].id = propRecord.schemaFileId;
|
|
2941
|
-
logger$
|
|
2976
|
+
logger$3(`Updated schemaFile property ID for ${modelName}.${propRecord.name} from ${currentId} to ${propRecord.schemaFileId}`);
|
|
2942
2977
|
schemaFileUpdated = true;
|
|
2943
2978
|
}
|
|
2944
2979
|
}
|
|
@@ -2949,8 +2984,8 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2949
2984
|
// This is important even if nothing changed, to ensure consistency
|
|
2950
2985
|
const updatedSchemaData = JSON.stringify(schemaFile, null, 2);
|
|
2951
2986
|
// Update the schema record in the database with current schemaData
|
|
2952
|
-
const _mod_10 = await import('./BasePathResolver-
|
|
2953
|
-
const _ns_10 = _mod_10.
|
|
2987
|
+
const _mod_10 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2988
|
+
const _ns_10 = _mod_10.a$;
|
|
2954
2989
|
const schemaSchemaMod = _ns_10;
|
|
2955
2990
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
2956
2991
|
await db
|
|
@@ -2958,21 +2993,21 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2958
2993
|
.set({ schemaData: updatedSchemaData })
|
|
2959
2994
|
.where(eq(schemasTable.id, schemaRecord.id));
|
|
2960
2995
|
if (schemaFileUpdated) {
|
|
2961
|
-
logger$
|
|
2996
|
+
logger$3(`Updated schemaData in database with actual property IDs for schema "${schemaName}"`);
|
|
2962
2997
|
}
|
|
2963
2998
|
else {
|
|
2964
|
-
logger$
|
|
2999
|
+
logger$3(`Verified schemaData in database matches schemaFile for schema "${schemaName}"`);
|
|
2965
3000
|
}
|
|
2966
3001
|
}
|
|
2967
3002
|
}
|
|
2968
3003
|
catch (dbError) {
|
|
2969
3004
|
// Database not available - log warning but continue
|
|
2970
|
-
logger$
|
|
3005
|
+
logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
|
|
2971
3006
|
}
|
|
2972
3007
|
// Models are now Model instances, no registration needed
|
|
2973
3008
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
2974
3009
|
for (const [modelName] of Object.entries(modelDefinitions)) {
|
|
2975
|
-
logger$
|
|
3010
|
+
logger$3('loadSchemaFromFile - model available:', modelName);
|
|
2976
3011
|
}
|
|
2977
3012
|
return schemaFilePath;
|
|
2978
3013
|
}
|
|
@@ -2984,19 +3019,12 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2984
3019
|
}
|
|
2985
3020
|
};
|
|
2986
3021
|
/**
|
|
2987
|
-
*
|
|
2988
|
-
* @param modelName - The name of the model
|
|
3022
|
+
* Convert a JSON model's properties to the schema property format Model.create and addModelsToDb take
|
|
3023
|
+
* @param modelName - The name of the model (for error messages)
|
|
2989
3024
|
* @param modelDef - The JSON model definition
|
|
2990
|
-
* @param
|
|
2991
|
-
* @returns A Model class that can be used with the SDK
|
|
3025
|
+
* @param propertyFileIds - Optional map of property names to their file IDs from the JSON file
|
|
2992
3026
|
*/
|
|
2993
|
-
const
|
|
2994
|
-
propertyFileIds) => {
|
|
2995
|
-
const _mod_11 = await import('./index-Xl1_4Lmb.js');
|
|
2996
|
-
const _ns_11 = _mod_11.f;
|
|
2997
|
-
const modelMod = _ns_11;
|
|
2998
|
-
const { Model } = modelMod;
|
|
2999
|
-
// Convert JSON properties to schema format
|
|
3027
|
+
const jsonPropertiesToSchemaProperties = (modelName, modelDef, propertyFileIds) => {
|
|
3000
3028
|
const convertedProperties = {};
|
|
3001
3029
|
if (modelDef.properties) {
|
|
3002
3030
|
for (const [propName, propDef] of Object.entries(modelDef.properties)) {
|
|
@@ -3055,14 +3083,30 @@ propertyFileIds) => {
|
|
|
3055
3083
|
convertedProperties[propName] = schemaProp;
|
|
3056
3084
|
}
|
|
3057
3085
|
}
|
|
3086
|
+
return convertedProperties;
|
|
3087
|
+
};
|
|
3088
|
+
/**
|
|
3089
|
+
* Create a Model class from a JSON model definition
|
|
3090
|
+
* @param modelName - The name of the model
|
|
3091
|
+
* @param modelDef - The JSON model definition
|
|
3092
|
+
* @param schemaName - The name of the schema this model belongs to
|
|
3093
|
+
* @returns A Model class that can be used with the SDK
|
|
3094
|
+
*/
|
|
3095
|
+
const createModelFromJson = async (modelName, modelDef, schemaName, modelFileId, // Optional modelFileId from JSON file
|
|
3096
|
+
propertyFileIds) => {
|
|
3097
|
+
const _mod_11 = await import('./index-8O3Uow-Y.js');
|
|
3098
|
+
const _ns_11 = _mod_11.f;
|
|
3099
|
+
const modelMod = _ns_11;
|
|
3100
|
+
const { Model } = modelMod;
|
|
3101
|
+
const convertedProperties = jsonPropertiesToSchemaProperties(modelName, modelDef, propertyFileIds);
|
|
3058
3102
|
// Create Model instance with the definition
|
|
3059
3103
|
// Pass id (schemaFileId) if provided to ensure Model instance uses correct ID
|
|
3060
3104
|
// Note: indexes and description are ignored - they remain in JSON for schema file format compliance but are not used by Model instances
|
|
3061
3105
|
if (modelFileId) {
|
|
3062
|
-
logger$
|
|
3106
|
+
logger$3(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
|
|
3063
3107
|
}
|
|
3064
3108
|
else {
|
|
3065
|
-
logger$
|
|
3109
|
+
logger$3(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
|
|
3066
3110
|
}
|
|
3067
3111
|
const modelInstance = Model.create(modelName, schemaName, {
|
|
3068
3112
|
modelFileId: modelFileId, // Pass modelFileId (preferred) as id (schemaFileId) from JSON file
|
|
@@ -3088,7 +3132,7 @@ const createModelsFromJson = async (importData, modelFileIds, propertyFileIds) =
|
|
|
3088
3132
|
// Use modelFileId from map (no fallback to modelDef.id as JsonImportSchema doesn't have id property)
|
|
3089
3133
|
const finalModelFileId = modelFileId;
|
|
3090
3134
|
if (!finalModelFileId) {
|
|
3091
|
-
logger$
|
|
3135
|
+
logger$3(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
|
|
3092
3136
|
}
|
|
3093
3137
|
// Get propertyFileIds for this model if available
|
|
3094
3138
|
const modelPropertyFileIds = propertyFileIds?.get(modelName);
|
|
@@ -3278,7 +3322,7 @@ var SEEDPROTOCOL_Seed_Protocol_v1 = /*#__PURE__*/Object.freeze({
|
|
|
3278
3322
|
version: version
|
|
3279
3323
|
});
|
|
3280
3324
|
|
|
3281
|
-
const logger$
|
|
3325
|
+
const logger$2 = debug('seedSdk:client:actors:processSchemaFiles');
|
|
3282
3326
|
let processSchemaFilesChain = Promise.resolve();
|
|
3283
3327
|
function resolveSchemaFilePath(schemaFile) {
|
|
3284
3328
|
const path = BaseFileManager.getPathModule();
|
|
@@ -3306,16 +3350,22 @@ async function resolveSchemaNameFromSource(source) {
|
|
|
3306
3350
|
}
|
|
3307
3351
|
}
|
|
3308
3352
|
catch (error) {
|
|
3309
|
-
logger$
|
|
3353
|
+
logger$2('Could not resolve schema name from path:', source, error);
|
|
3310
3354
|
}
|
|
3311
3355
|
}
|
|
3312
3356
|
return null;
|
|
3313
3357
|
}
|
|
3358
|
+
/** Error for a schema the app passed in config, so init fails with what went wrong and where. */
|
|
3359
|
+
function userSchemaLoadError(option, source, error) {
|
|
3360
|
+
const where = typeof source === 'string' ? ` from "${source}"` : '';
|
|
3361
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
3362
|
+
return new Error(`Could not load config.${option}${where}: ${reason}`, { cause: error });
|
|
3363
|
+
}
|
|
3314
3364
|
// Timeout for the entire schema processing operation (120 seconds)
|
|
3315
3365
|
// Schema processing can be slow with syncSchemaFromSource, loadAllSchemasFromDb, and OPFS file I/O
|
|
3316
3366
|
const PROCESS_SCHEMA_FILES_TIMEOUT_MS = 120000;
|
|
3317
3367
|
const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
3318
|
-
logger$
|
|
3368
|
+
logger$2('processSchemaFiles started');
|
|
3319
3369
|
let hasResponded = false;
|
|
3320
3370
|
let timeoutId = null;
|
|
3321
3371
|
const reportError = (error) => {
|
|
@@ -3325,7 +3375,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3325
3375
|
clearTimeout(timeoutId);
|
|
3326
3376
|
timeoutId = null;
|
|
3327
3377
|
}
|
|
3328
|
-
logger$
|
|
3378
|
+
logger$2('processSchemaFiles error:', error);
|
|
3329
3379
|
sendBack({
|
|
3330
3380
|
type: 'error',
|
|
3331
3381
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -3339,7 +3389,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3339
3389
|
clearTimeout(timeoutId);
|
|
3340
3390
|
timeoutId = null;
|
|
3341
3391
|
}
|
|
3342
|
-
logger$
|
|
3392
|
+
logger$2('processSchemaFiles completed');
|
|
3343
3393
|
sendBack({ type: ClientManagerEvents.PROCESS_SCHEMA_FILES_SUCCESS });
|
|
3344
3394
|
}
|
|
3345
3395
|
};
|
|
@@ -3351,7 +3401,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3351
3401
|
// Schemas written (or confirmed present) this run — skip redundant loadSchemaFromFile later
|
|
3352
3402
|
const schemasWrittenThisRun = new Set();
|
|
3353
3403
|
// First, load the internal seed-protocol schema
|
|
3354
|
-
logger$
|
|
3404
|
+
logger$2('Loading internal seed-protocol schema');
|
|
3355
3405
|
const internalSchemaData = internalSchema;
|
|
3356
3406
|
const db = BaseDb.getAppDb();
|
|
3357
3407
|
const internalSchemaExists = db
|
|
@@ -3360,21 +3410,21 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3360
3410
|
// Always mark internal schema as written so the DB/file loop does not re-apply it
|
|
3361
3411
|
schemasWrittenThisRun.add(SEED_PROTOCOL_SCHEMA_NAME);
|
|
3362
3412
|
if (internalSchemaExists) {
|
|
3363
|
-
logger$
|
|
3413
|
+
logger$2('Internal seed-protocol schema already in DB, skipping import');
|
|
3364
3414
|
}
|
|
3365
3415
|
else {
|
|
3366
3416
|
try {
|
|
3367
3417
|
// Import the internal schema to database (will create models and add to store)
|
|
3368
3418
|
await importJsonSchema({ contents: JSON.stringify(internalSchemaData) }, internalSchemaData.version);
|
|
3369
|
-
logger$
|
|
3419
|
+
logger$2(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
|
|
3370
3420
|
}
|
|
3371
3421
|
catch (error) {
|
|
3372
3422
|
// If schema already exists, that's fine - it means it was already loaded
|
|
3373
3423
|
if (error?.message?.includes('already exists')) {
|
|
3374
|
-
logger$
|
|
3424
|
+
logger$2('Internal seed-protocol schema already loaded');
|
|
3375
3425
|
}
|
|
3376
3426
|
else {
|
|
3377
|
-
logger$
|
|
3427
|
+
logger$2('Error loading internal seed-protocol schema:', error);
|
|
3378
3428
|
// Don't fail if internal schema can't be loaded - it might already be in DB
|
|
3379
3429
|
}
|
|
3380
3430
|
}
|
|
@@ -3387,7 +3437,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3387
3437
|
: '';
|
|
3388
3438
|
const schemaId = typeof context.schema === 'object' && context.schema?.id ? String(context.schema.id) : undefined;
|
|
3389
3439
|
if (isInternalSchema(schemaName, schemaId)) {
|
|
3390
|
-
logger$
|
|
3440
|
+
logger$2('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
|
|
3391
3441
|
}
|
|
3392
3442
|
else {
|
|
3393
3443
|
try {
|
|
@@ -3396,11 +3446,12 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3396
3446
|
if (syncedName) {
|
|
3397
3447
|
schemasWrittenThisRun.add(syncedName);
|
|
3398
3448
|
}
|
|
3399
|
-
logger$
|
|
3449
|
+
logger$2(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
|
|
3400
3450
|
}
|
|
3401
3451
|
catch (error) {
|
|
3402
|
-
|
|
3403
|
-
//
|
|
3452
|
+
// A schema the app passed in failed (missing file, bad JSON, DB write). Re-running an
|
|
3453
|
+
// unchanged schema does not throw, so this is not the already-loaded case: fail init.
|
|
3454
|
+
throw userSchemaLoadError('schema', context.schema, error);
|
|
3404
3455
|
}
|
|
3405
3456
|
}
|
|
3406
3457
|
}
|
|
@@ -3414,23 +3465,22 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3414
3465
|
if (parsed?.metadata?.name) {
|
|
3415
3466
|
schemasWrittenThisRun.add(String(parsed.metadata.name));
|
|
3416
3467
|
}
|
|
3417
|
-
logger$
|
|
3468
|
+
logger$2(`Loaded schema from ${resolvedPath}`);
|
|
3418
3469
|
}
|
|
3419
3470
|
catch (error) {
|
|
3420
|
-
|
|
3421
|
-
// Don't fail init - schema might already be in DB
|
|
3471
|
+
throw userSchemaLoadError('schemaFile', context.schemaFile, error);
|
|
3422
3472
|
}
|
|
3423
3473
|
}
|
|
3424
3474
|
// Process minimal import files (files without $schema) - skip when canonical schema is set
|
|
3425
3475
|
if (!context.schema) {
|
|
3426
|
-
logger$
|
|
3476
|
+
logger$2('Listing schema files');
|
|
3427
3477
|
let schemaFiles = [];
|
|
3428
3478
|
try {
|
|
3429
3479
|
schemaFiles = await listSchemaFiles();
|
|
3430
|
-
logger$
|
|
3480
|
+
logger$2(`Found ${schemaFiles.length} schema files to process`);
|
|
3431
3481
|
}
|
|
3432
3482
|
catch (error) {
|
|
3433
|
-
logger$
|
|
3483
|
+
logger$2('Error listing schema files (continuing anyway):', error);
|
|
3434
3484
|
schemaFiles = [];
|
|
3435
3485
|
}
|
|
3436
3486
|
for (const schemaFile of schemaFiles) {
|
|
@@ -3441,19 +3491,19 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3441
3491
|
}
|
|
3442
3492
|
}
|
|
3443
3493
|
catch (error) {
|
|
3444
|
-
logger$
|
|
3494
|
+
logger$2(`Error importing schema file ${schemaFile.filePath}:`, error);
|
|
3445
3495
|
}
|
|
3446
3496
|
}
|
|
3447
3497
|
}
|
|
3448
3498
|
// Then, load all schemas using the unified database-first approach
|
|
3449
|
-
logger$
|
|
3499
|
+
logger$2('Loading schemas from database and files');
|
|
3450
3500
|
let allSchemasData = [];
|
|
3451
3501
|
try {
|
|
3452
3502
|
allSchemasData = await loadAllSchemasFromDb();
|
|
3453
|
-
logger$
|
|
3503
|
+
logger$2(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
|
|
3454
3504
|
}
|
|
3455
3505
|
catch (error) {
|
|
3456
|
-
logger$
|
|
3506
|
+
logger$2('Error loading schemas from database (continuing anyway):', error);
|
|
3457
3507
|
// Continue with empty array - this is not critical for initialization
|
|
3458
3508
|
// Schemas can be loaded on-demand later
|
|
3459
3509
|
allSchemasData = [];
|
|
@@ -3474,13 +3524,13 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3474
3524
|
}
|
|
3475
3525
|
}
|
|
3476
3526
|
catch (error) {
|
|
3477
|
-
logger$
|
|
3527
|
+
logger$2('Error counting linked models (re-applying all schema files):', error);
|
|
3478
3528
|
}
|
|
3479
3529
|
}
|
|
3480
3530
|
for (const schemaData of allSchemasData) {
|
|
3481
3531
|
const schema = schemaData.schema;
|
|
3482
3532
|
const schemaName = schema.metadata?.name || 'unknown';
|
|
3483
|
-
logger$
|
|
3533
|
+
logger$2(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
|
|
3484
3534
|
// For published schemas (not drafts), load models from file if available
|
|
3485
3535
|
if (!schemaData.isDraft && schema.id) {
|
|
3486
3536
|
// loadAllSchemasFromDb already picked the latest file for this schema (and read it)
|
|
@@ -3510,7 +3560,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3510
3560
|
}
|
|
3511
3561
|
}
|
|
3512
3562
|
catch (error) {
|
|
3513
|
-
logger$
|
|
3563
|
+
logger$2(`Error loading schema file for ${schemaName}:`, error);
|
|
3514
3564
|
}
|
|
3515
3565
|
}
|
|
3516
3566
|
else {
|
|
@@ -3559,11 +3609,11 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3559
3609
|
};
|
|
3560
3610
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
3561
3611
|
Object.assign(allModels, modelDefinitions);
|
|
3562
|
-
logger$
|
|
3612
|
+
logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
|
|
3563
3613
|
}
|
|
3564
3614
|
}
|
|
3565
3615
|
catch (error) {
|
|
3566
|
-
logger$
|
|
3616
|
+
logger$2(`Error creating models from schema data for ${schemaName}:`, error);
|
|
3567
3617
|
}
|
|
3568
3618
|
}
|
|
3569
3619
|
}
|
|
@@ -3613,11 +3663,11 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3613
3663
|
};
|
|
3614
3664
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
3615
3665
|
Object.assign(allModels, modelDefinitions);
|
|
3616
|
-
logger$
|
|
3666
|
+
logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
|
|
3617
3667
|
}
|
|
3618
3668
|
}
|
|
3619
3669
|
catch (error) {
|
|
3620
|
-
logger$
|
|
3670
|
+
logger$2(`Error creating models from draft schema ${schemaName}:`, error);
|
|
3621
3671
|
}
|
|
3622
3672
|
}
|
|
3623
3673
|
// Schemas are now loaded on-demand via database queries (useSchemas hook uses loadAllSchemasFromDb)
|
|
@@ -3631,14 +3681,12 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3631
3681
|
}
|
|
3632
3682
|
});
|
|
3633
3683
|
};
|
|
3634
|
-
|
|
3684
|
+
const run = processSchemaFilesChain
|
|
3635
3685
|
// Its schema and model inserts check for rows first, so tabs take turns (docs/MULTI_TAB.md).
|
|
3636
|
-
.then(() => withSeedDbLock('init', context.filesDir, _processSchemaFiles))
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
});
|
|
3641
|
-
processSchemaFilesChain.then(reportSuccess).catch((error) => {
|
|
3686
|
+
.then(() => withSeedDbLock('init', context.filesDir, _processSchemaFiles));
|
|
3687
|
+
// The chain only orders runs; a failed run must not fail the next init too.
|
|
3688
|
+
processSchemaFilesChain = run.catch(() => { });
|
|
3689
|
+
run.then(reportSuccess).catch((error) => {
|
|
3642
3690
|
reportError(error instanceof Error ? error : new Error(String(error)));
|
|
3643
3691
|
});
|
|
3644
3692
|
// Cleanup function to clear timeout if actor is stopped
|
|
@@ -3650,6 +3698,285 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3650
3698
|
};
|
|
3651
3699
|
});
|
|
3652
3700
|
|
|
3701
|
+
/**
|
|
3702
|
+
* A legacy ItemStorage draft row: a local edit (no attestation uid, not derived from one) that holds
|
|
3703
|
+
* the content itself in property_value, with no file reference. Item.create / createNewItem stored
|
|
3704
|
+
* ItemStorage values like this before they went through the save pipeline.
|
|
3705
|
+
*/
|
|
3706
|
+
const isVerbatimItemStorageDraftRow = (row) => !row.uid &&
|
|
3707
|
+
row.derivedFromUid == null &&
|
|
3708
|
+
!row.refResolvedValue &&
|
|
3709
|
+
typeof row.propertyValue === 'string' &&
|
|
3710
|
+
row.propertyValue !== '';
|
|
3711
|
+
/**
|
|
3712
|
+
* Convert one legacy ItemStorage draft row (see {@link isVerbatimItemStorageDraftRow}) into the
|
|
3713
|
+
* shape saveItemStorage gives a row: the content goes to the file a save would write
|
|
3714
|
+
* (`<seedUid or seedLocalId><extension>` in the property's storage directory), and the row records
|
|
3715
|
+
* `refResolvedValue`, `localStorageDir` and `refValueType: 'file'` with property_value cleared.
|
|
3716
|
+
* Used by publish (resolveItemStorageChildFile) and the one-time migration (migrateLegacyItemStorageRows).
|
|
3717
|
+
*
|
|
3718
|
+
* Reading the row, writing the file and updating the row happen under the file's lock
|
|
3719
|
+
* ({@link withItemStorageFileLock}), which saveItemStorage holds too: a save in this or another tab
|
|
3720
|
+
* either finishes before (the row, read again once the lock is held, is no longer legacy and is
|
|
3721
|
+
* left alone) or starts after (and overwrites the file and row with its content). Without the lock
|
|
3722
|
+
* a save landing between the read and the file write would have its file overwritten with the old
|
|
3723
|
+
* content. The row update also stays conditional on the row being unchanged, for writers that
|
|
3724
|
+
* don't take the lock (a tab still running an older SDK).
|
|
3725
|
+
*
|
|
3726
|
+
* Returns undefined when there was nothing to convert. Throws when the file can't be written; the
|
|
3727
|
+
* row is then unchanged.
|
|
3728
|
+
*/
|
|
3729
|
+
const convertVerbatimItemStorageRow = async (localId, storage = {}) => {
|
|
3730
|
+
const appDb = BaseDb.getAppDb();
|
|
3731
|
+
if (!appDb || !localId)
|
|
3732
|
+
return undefined;
|
|
3733
|
+
const targetOf = (row) => {
|
|
3734
|
+
if (!isVerbatimItemStorageDraftRow(row))
|
|
3735
|
+
return undefined;
|
|
3736
|
+
const seedId = storage.seedId || row.seedUid || row.seedLocalId;
|
|
3737
|
+
if (!seedId)
|
|
3738
|
+
return undefined;
|
|
3739
|
+
return {
|
|
3740
|
+
seedId,
|
|
3741
|
+
localStorageDir: storage.localStorageDir || row.localStorageDir,
|
|
3742
|
+
filenameSuffix: storage.filenameSuffix,
|
|
3743
|
+
};
|
|
3744
|
+
};
|
|
3745
|
+
return withLockedItemStorageRow(localId, (row) => {
|
|
3746
|
+
const target = targetOf(row);
|
|
3747
|
+
return target && getItemStorageFilePath(target);
|
|
3748
|
+
}, async (row) => {
|
|
3749
|
+
const content = row.propertyValue;
|
|
3750
|
+
const { fileName, filePath, localStorageDir } = await writeItemStorageFile(targetOf(row), content);
|
|
3751
|
+
await appDb
|
|
3752
|
+
.update(metadata$1)
|
|
3753
|
+
.set({ refResolvedValue: fileName, localStorageDir, refValueType: 'file', propertyValue: null })
|
|
3754
|
+
.where(and(eq(metadata$1.localId, localId), isNull(metadata$1.refResolvedValue), eq(metadata$1.propertyValue, content)));
|
|
3755
|
+
// Changed between the read and the update by a writer outside the lock: that change stands.
|
|
3756
|
+
const after = await appDb
|
|
3757
|
+
.select({ refResolvedValue: metadata$1.refResolvedValue, propertyValue: metadata$1.propertyValue })
|
|
3758
|
+
.from(metadata$1)
|
|
3759
|
+
.where(eq(metadata$1.localId, localId))
|
|
3760
|
+
.limit(1);
|
|
3761
|
+
if (after[0]?.refResolvedValue !== fileName || after[0]?.propertyValue != null)
|
|
3762
|
+
return undefined;
|
|
3763
|
+
return { fileName, filePath, localStorageDir, content };
|
|
3764
|
+
});
|
|
3765
|
+
};
|
|
3766
|
+
|
|
3767
|
+
const logger$1 = debug('seedSdk:db:migrateLegacyItemStorageRows');
|
|
3768
|
+
/** appState key recording that legacy ItemStorage rows have been written to their files. */
|
|
3769
|
+
const LEGACY_ITEM_STORAGE_MIGRATION_KEY = 'legacyItemStorageFiles:v1';
|
|
3770
|
+
/** Runs in a row that left rows unconverted because a file write failed, before giving up. */
|
|
3771
|
+
const LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS = 3;
|
|
3772
|
+
const readMarker = async () => {
|
|
3773
|
+
const db = BaseDb.getAppDb();
|
|
3774
|
+
const rows = await db
|
|
3775
|
+
.select({ value: appState.value })
|
|
3776
|
+
.from(appState)
|
|
3777
|
+
.where(eq(appState.key, LEGACY_ITEM_STORAGE_MIGRATION_KEY))
|
|
3778
|
+
.limit(1);
|
|
3779
|
+
if (!rows.length)
|
|
3780
|
+
return undefined;
|
|
3781
|
+
try {
|
|
3782
|
+
return JSON.parse(rows[0].value ?? '');
|
|
3783
|
+
}
|
|
3784
|
+
catch {
|
|
3785
|
+
return null;
|
|
3786
|
+
}
|
|
3787
|
+
};
|
|
3788
|
+
const writeMarker = async (marker) => {
|
|
3789
|
+
const db = BaseDb.getAppDb();
|
|
3790
|
+
const now = Date.now();
|
|
3791
|
+
const value = JSON.stringify(marker);
|
|
3792
|
+
await db
|
|
3793
|
+
.insert(appState)
|
|
3794
|
+
.values({ key: LEGACY_ITEM_STORAGE_MIGRATION_KEY, value, createdAt: now, updatedAt: now })
|
|
3795
|
+
.onConflictDoUpdate({ target: appState.key, set: { value, updatedAt: now } });
|
|
3796
|
+
};
|
|
3797
|
+
/**
|
|
3798
|
+
* The storage settings of a metadata row's property: by its property_id, else by name in the
|
|
3799
|
+
* seed's own model (model names are only unique per schema). Undefined when it can't be told.
|
|
3800
|
+
*/
|
|
3801
|
+
const createStorageResolver = () => {
|
|
3802
|
+
const db = BaseDb.getAppDb();
|
|
3803
|
+
const byPropertyId = new Map();
|
|
3804
|
+
const byModelAndName = new Map();
|
|
3805
|
+
return async (row) => {
|
|
3806
|
+
if (row.propertyId != null) {
|
|
3807
|
+
if (!byPropertyId.has(row.propertyId)) {
|
|
3808
|
+
const found = await db
|
|
3809
|
+
.select({
|
|
3810
|
+
storageType: properties.storageType,
|
|
3811
|
+
localStorageDir: properties.localStorageDir,
|
|
3812
|
+
filenameSuffix: properties.filenameSuffix,
|
|
3813
|
+
})
|
|
3814
|
+
.from(properties)
|
|
3815
|
+
.where(eq(properties.id, row.propertyId))
|
|
3816
|
+
.limit(1);
|
|
3817
|
+
byPropertyId.set(row.propertyId, found[0]);
|
|
3818
|
+
}
|
|
3819
|
+
const fromId = byPropertyId.get(row.propertyId);
|
|
3820
|
+
if (fromId)
|
|
3821
|
+
return fromId;
|
|
3822
|
+
}
|
|
3823
|
+
const modelFileId = await resolveItemModelFileId({ seedLocalId: row.seedLocalId, seedUid: row.seedUid });
|
|
3824
|
+
if (!modelFileId || !row.propertyName)
|
|
3825
|
+
return undefined;
|
|
3826
|
+
const key = `${modelFileId}\u0000${row.propertyName}`;
|
|
3827
|
+
if (!byModelAndName.has(key)) {
|
|
3828
|
+
const found = await db
|
|
3829
|
+
.select({
|
|
3830
|
+
storageType: properties.storageType,
|
|
3831
|
+
localStorageDir: properties.localStorageDir,
|
|
3832
|
+
filenameSuffix: properties.filenameSuffix,
|
|
3833
|
+
})
|
|
3834
|
+
.from(properties)
|
|
3835
|
+
.innerJoin(models$1, eq(properties.modelId, models$1.id))
|
|
3836
|
+
.where(and(eq(models$1.schemaFileId, modelFileId), eq(properties.name, row.propertyName)))
|
|
3837
|
+
.limit(1);
|
|
3838
|
+
byModelAndName.set(key, found[0]);
|
|
3839
|
+
}
|
|
3840
|
+
return byModelAndName.get(key);
|
|
3841
|
+
};
|
|
3842
|
+
};
|
|
3843
|
+
/** True if `row` is the row readers show for its property: the newest of its seed's rows by that name. */
|
|
3844
|
+
const isNewestRowOfProperty = async (row) => {
|
|
3845
|
+
if (!row.seedLocalId || !row.propertyName)
|
|
3846
|
+
return false;
|
|
3847
|
+
const db = BaseDb.getAppDb();
|
|
3848
|
+
const siblings = await db
|
|
3849
|
+
.select()
|
|
3850
|
+
.from(metadata$1)
|
|
3851
|
+
.where(and(eq(metadata$1.seedLocalId, row.seedLocalId), eq(metadata$1.propertyName, row.propertyName)));
|
|
3852
|
+
return [...siblings].sort(compareMetadataRowsLatestFirst)[0]?.localId === row.localId;
|
|
3853
|
+
};
|
|
3854
|
+
/**
|
|
3855
|
+
* One-time data migration: writes the content of legacy ItemStorage draft rows to their files.
|
|
3856
|
+
*
|
|
3857
|
+
* Before Item.create / createNewItem saved ItemStorage values through the save pipeline, a value
|
|
3858
|
+
* given at creation was stored verbatim in metadata.property_value with no file. Publish converts
|
|
3859
|
+
* such a row lazily (resolveItemStorageChildFile); this converts them all up front, with the same
|
|
3860
|
+
* code ({@link convertVerbatimItemStorageRow}), so every ItemStorage draft has the shape a save
|
|
3861
|
+
* gives it: the content in `<seedUid or seedLocalId><extension>`, the row holding
|
|
3862
|
+
* refResolvedValue / localStorageDir / refValueType 'file' and no property_value.
|
|
3863
|
+
*
|
|
3864
|
+
* Only local drafts (no uid, not derived from an attestation) of properties whose properties row
|
|
3865
|
+
* says `storage_type = 'ItemStorage'` are touched, and of those only the newest row of each
|
|
3866
|
+
* seed's property: that is the row reads show and saves write to, and older rows sharing the one
|
|
3867
|
+
* file name would overwrite it with older content. Published and synced rows are never changed.
|
|
3868
|
+
*
|
|
3869
|
+
* A row that fails is logged and left as it was (publish still converts it). The run is recorded
|
|
3870
|
+
* in appState under {@link LEGACY_ITEM_STORAGE_MIGRATION_KEY}; a run with failed rows is retried
|
|
3871
|
+
* on the next start, up to {@link LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS} runs. Safe to run
|
|
3872
|
+
* again regardless: a converted row no longer matches.
|
|
3873
|
+
*
|
|
3874
|
+
* @param options.force run even when the marker says it is done
|
|
3875
|
+
*/
|
|
3876
|
+
async function migrateLegacyItemStorageRows(options = {}) {
|
|
3877
|
+
const result = {
|
|
3878
|
+
alreadyDone: false,
|
|
3879
|
+
candidates: 0,
|
|
3880
|
+
converted: 0,
|
|
3881
|
+
failed: 0,
|
|
3882
|
+
skipped: 0,
|
|
3883
|
+
};
|
|
3884
|
+
const db = BaseDb.getAppDb();
|
|
3885
|
+
if (!db)
|
|
3886
|
+
return { ...result, alreadyDone: true };
|
|
3887
|
+
const marker = await readMarker();
|
|
3888
|
+
const previousAttempts = marker?.status === 'retry' ? marker.attempts : 0;
|
|
3889
|
+
if (!options.force && marker && marker.status === 'done') {
|
|
3890
|
+
return { ...result, alreadyDone: true };
|
|
3891
|
+
}
|
|
3892
|
+
const itemStorageNames = (await db
|
|
3893
|
+
.selectDistinct({ name: properties.name })
|
|
3894
|
+
.from(properties)
|
|
3895
|
+
.where(eq(properties.storageType, 'ItemStorage'))).map((r) => r.name);
|
|
3896
|
+
const candidates = itemStorageNames.length
|
|
3897
|
+
? await db
|
|
3898
|
+
.select()
|
|
3899
|
+
.from(metadata$1)
|
|
3900
|
+
.where(and(inArray(metadata$1.propertyName, itemStorageNames), or(isNull(metadata$1.uid), eq(metadata$1.uid, '')), isNull(metadata$1.derivedFromUid), isNull(metadata$1.refResolvedValue), isNotNull(metadata$1.propertyValue), ne(metadata$1.propertyValue, '')))
|
|
3901
|
+
: [];
|
|
3902
|
+
const resolveStorage = createStorageResolver();
|
|
3903
|
+
for (const row of candidates) {
|
|
3904
|
+
if (!row.localId || !isVerbatimItemStorageDraftRow(row))
|
|
3905
|
+
continue;
|
|
3906
|
+
try {
|
|
3907
|
+
const storage = await resolveStorage(row);
|
|
3908
|
+
if (storage?.storageType !== 'ItemStorage')
|
|
3909
|
+
continue;
|
|
3910
|
+
result.candidates++;
|
|
3911
|
+
if (!(await isNewestRowOfProperty(row))) {
|
|
3912
|
+
result.skipped++;
|
|
3913
|
+
continue;
|
|
3914
|
+
}
|
|
3915
|
+
const converted = await convertVerbatimItemStorageRow(row.localId, {
|
|
3916
|
+
localStorageDir: storage.localStorageDir,
|
|
3917
|
+
filenameSuffix: storage.filenameSuffix,
|
|
3918
|
+
});
|
|
3919
|
+
if (converted) {
|
|
3920
|
+
result.converted++;
|
|
3921
|
+
logger$1(`wrote ${row.propertyName} of ${row.seedLocalId} to ${converted.filePath}`);
|
|
3922
|
+
}
|
|
3923
|
+
else {
|
|
3924
|
+
result.skipped++;
|
|
3925
|
+
}
|
|
3926
|
+
}
|
|
3927
|
+
catch (error) {
|
|
3928
|
+
result.failed++;
|
|
3929
|
+
logger$1(`converting ${row.propertyName} of ${row.seedLocalId} (${row.localId}) failed; left as is`, error);
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
const attempts = previousAttempts + 1;
|
|
3933
|
+
await writeMarker({
|
|
3934
|
+
status: result.failed > 0 && attempts < LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS ? 'retry' : 'done',
|
|
3935
|
+
attempts,
|
|
3936
|
+
converted: result.converted,
|
|
3937
|
+
failed: result.failed,
|
|
3938
|
+
at: Date.now(),
|
|
3939
|
+
});
|
|
3940
|
+
if (result.candidates > 0) {
|
|
3941
|
+
logger$1(`legacy ItemStorage rows: ${result.converted} converted, ${result.failed} failed, ` +
|
|
3942
|
+
`${result.skipped} skipped of ${result.candidates}`);
|
|
3943
|
+
}
|
|
3944
|
+
return result;
|
|
3945
|
+
}
|
|
3946
|
+
let running;
|
|
3947
|
+
let deferredUntilLeader = false;
|
|
3948
|
+
const runInBackground = () => {
|
|
3949
|
+
running ?? (running = withDbTabLock('item-storage-migration', () => migrateLegacyItemStorageRows())
|
|
3950
|
+
.then(() => undefined)
|
|
3951
|
+
.catch((error) => {
|
|
3952
|
+
// Never fails init: rows stay as they were and publish converts them lazily.
|
|
3953
|
+
logger$1('legacy ItemStorage migration failed', error);
|
|
3954
|
+
})
|
|
3955
|
+
.finally(() => {
|
|
3956
|
+
running = undefined;
|
|
3957
|
+
}));
|
|
3958
|
+
return running;
|
|
3959
|
+
};
|
|
3960
|
+
/**
|
|
3961
|
+
* Starts {@link migrateLegacyItemStorageRows} in the background once client init has finished
|
|
3962
|
+
* (the properties table then holds the current storage settings). It runs in the leader tab only
|
|
3963
|
+
* (docs/MULTI_TAB.md), under a `seed:item-storage-migration:<db>` lock in case several tabs lead
|
|
3964
|
+
* (`multiTab: 'off'`); a tab that isn't leader runs it if it takes over. Never throws.
|
|
3965
|
+
*/
|
|
3966
|
+
function startLegacyItemStorageMigration() {
|
|
3967
|
+
if (isLeaderTab()) {
|
|
3968
|
+
void runInBackground();
|
|
3969
|
+
return;
|
|
3970
|
+
}
|
|
3971
|
+
if (deferredUntilLeader)
|
|
3972
|
+
return;
|
|
3973
|
+
deferredUntilLeader = true;
|
|
3974
|
+
void whenLeaderTab().then(() => {
|
|
3975
|
+
deferredUntilLeader = false;
|
|
3976
|
+
void runInBackground();
|
|
3977
|
+
});
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3653
3980
|
const { UNINITIALIZED, PLATFORM_CLASSES_INIT, FILE_SYSTEM_INIT, DB_INIT, SAVE_CONFIG, PROCESS_SCHEMA_FILES, ADD_MODELS_TO_STORE, ADD_MODELS_TO_DB, IDLE, INIT_FAILED, } = ClientManagerState;
|
|
3654
3981
|
const { UPDATE_CONTEXT, PLATFORM_CLASSES_READY, FILE_SYSTEM_READY, DB_READY, SAVE_CONFIG_SUCCESS, SAVE_APP_STATE_SUCCESS, SAVE_APP_STATE_ERROR, SET_ADDRESSES, ADD_MODELS_TO_STORE_SUCCESS, ADD_MODELS_TO_DB_SUCCESS, PROCESS_SCHEMA_FILES_SUCCESS, } = ClientManagerEvents;
|
|
3655
3982
|
const logSyncAfterAddressSave = debug("seedSdk:client:clientManagerMachine:syncAfterAddressSave");
|
|
@@ -3870,9 +4197,15 @@ const clientManagerMachine = setup({
|
|
|
3870
4197
|
},
|
|
3871
4198
|
},
|
|
3872
4199
|
[IDLE]: {
|
|
3873
|
-
entry:
|
|
3874
|
-
|
|
3875
|
-
|
|
4200
|
+
entry: [
|
|
4201
|
+
assign({
|
|
4202
|
+
isInitialized: true,
|
|
4203
|
+
}),
|
|
4204
|
+
// One-time data migration that writes files, so it can't be a SQL migration in prepareDb.
|
|
4205
|
+
// In the background after init: the app is usable at once, the properties table holds the
|
|
4206
|
+
// current storage settings by now, and a failure never fails init.
|
|
4207
|
+
() => startLegacyItemStorageMigration(),
|
|
4208
|
+
],
|
|
3876
4209
|
on: {
|
|
3877
4210
|
[SAVE_APP_STATE_SUCCESS]: {
|
|
3878
4211
|
actions: [
|
|
@@ -4486,6 +4819,7 @@ const emptyResult = () => ({
|
|
|
4486
4819
|
seeds: 0,
|
|
4487
4820
|
versions: 0,
|
|
4488
4821
|
metadata: 0,
|
|
4822
|
+
seedLocalIds: [],
|
|
4489
4823
|
});
|
|
4490
4824
|
/**
|
|
4491
4825
|
* Stamp local seeds/versions/metadata that have no publisher and no real uid.
|
|
@@ -4514,22 +4848,23 @@ async function claimUnpublishedDrafts(publisher) {
|
|
|
4514
4848
|
isLocalUnsealedDraft(row))
|
|
4515
4849
|
.map((row) => row.localId);
|
|
4516
4850
|
if (ids.length === 0)
|
|
4517
|
-
return
|
|
4851
|
+
return [];
|
|
4518
4852
|
await appDb
|
|
4519
4853
|
.update(table)
|
|
4520
4854
|
.set({ publisher: normalized, updatedAt: now })
|
|
4521
4855
|
.where(inArray(table.localId, ids));
|
|
4522
|
-
return ids
|
|
4856
|
+
return ids;
|
|
4523
4857
|
};
|
|
4524
|
-
const [
|
|
4858
|
+
const [seedIds, versionIds, metadataIds] = await Promise.all([
|
|
4525
4859
|
claimTable(seeds),
|
|
4526
4860
|
claimTable(versions),
|
|
4527
4861
|
claimTable(metadata$1),
|
|
4528
4862
|
]);
|
|
4529
4863
|
return {
|
|
4530
|
-
seeds:
|
|
4531
|
-
versions:
|
|
4532
|
-
metadata:
|
|
4864
|
+
seeds: seedIds.length,
|
|
4865
|
+
versions: versionIds.length,
|
|
4866
|
+
metadata: metadataIds.length,
|
|
4867
|
+
seedLocalIds: seedIds,
|
|
4533
4868
|
};
|
|
4534
4869
|
}
|
|
4535
4870
|
|
|
@@ -4547,11 +4882,97 @@ const subscription = clientManager.subscribe((snapshot) => {
|
|
|
4547
4882
|
logger('ClientManager snapshot.context.isInitialized:', snapshot.context.isInitialized);
|
|
4548
4883
|
});
|
|
4549
4884
|
clientManager.start();
|
|
4885
|
+
/** Config of the init that is running or has succeeded; cleared when init fails or the client stops. */
|
|
4886
|
+
let activeInitConfig;
|
|
4887
|
+
const INIT_CONFIG_CONFLICT_MESSAGE = 'client.init was already called with a different config. The SDK keeps the config it was ' +
|
|
4888
|
+
'initialised with: pass the same config, or call client.stop() before initialising with a new one. ' +
|
|
4889
|
+
'To change addresses, use client.setAddresses() (or call init again with the same config and new addresses).';
|
|
4550
4890
|
const ensureInitialized = () => {
|
|
4551
4891
|
if (!clientManager.getSnapshot().context.isInitialized) {
|
|
4552
4892
|
throw new Error(CLIENT_NOT_INITIALIZED);
|
|
4553
4893
|
}
|
|
4554
4894
|
};
|
|
4895
|
+
const coalescedInit = createCoalescedAsync(async (options) => {
|
|
4896
|
+
// If the actor is stopped (e.g., from a previous failed test), restart it
|
|
4897
|
+
const snapshot = clientManager.getSnapshot();
|
|
4898
|
+
const currentState = snapshot.value;
|
|
4899
|
+
const isStopped = snapshot.status === 'stopped';
|
|
4900
|
+
if (isStopped) {
|
|
4901
|
+
logger('Client manager was stopped, restarting...');
|
|
4902
|
+
clientManager.start();
|
|
4903
|
+
// Wait for the actor to be ready
|
|
4904
|
+
try {
|
|
4905
|
+
await waitFor(clientManager, (snapshot) => snapshot.status !== 'stopped', { timeout: 1000 });
|
|
4906
|
+
}
|
|
4907
|
+
catch (e) {
|
|
4908
|
+
logger('Timeout waiting for actor to restart, continuing anyway...');
|
|
4909
|
+
}
|
|
4910
|
+
}
|
|
4911
|
+
// Clear any stale context from previous failed initializations
|
|
4912
|
+
// This ensures we start with a clean slate before the new init updates it
|
|
4913
|
+
if (currentState !== 'uninitialized') {
|
|
4914
|
+
logger(`Client manager is in state ${currentState}, clearing stale context before re-init...`);
|
|
4915
|
+
clientManager.send({
|
|
4916
|
+
type: 'updateContext',
|
|
4917
|
+
context: {
|
|
4918
|
+
isInitialized: false,
|
|
4919
|
+
addressesSet: false,
|
|
4920
|
+
isSaving: false,
|
|
4921
|
+
syncFromEasOnAddressChange: false,
|
|
4922
|
+
endpoints: undefined,
|
|
4923
|
+
addresses: undefined,
|
|
4924
|
+
ownedAddresses: undefined,
|
|
4925
|
+
watchedAddresses: undefined,
|
|
4926
|
+
models: undefined,
|
|
4927
|
+
arweaveDomain: undefined,
|
|
4928
|
+
filesDir: undefined,
|
|
4929
|
+
dbConfig: undefined,
|
|
4930
|
+
initError: undefined,
|
|
4931
|
+
saveError: undefined,
|
|
4932
|
+
}
|
|
4933
|
+
});
|
|
4934
|
+
// Wait a moment for the context update to be processed
|
|
4935
|
+
await new Promise(resolve => setTimeout(resolve, 10));
|
|
4936
|
+
}
|
|
4937
|
+
// Send init event - the root-level handler will transition to PLATFORM_CLASSES_INIT
|
|
4938
|
+
// which will stop any running actors and start fresh with the new options
|
|
4939
|
+
// The platformClassesInit actor will update the context with the correct endpoints from options
|
|
4940
|
+
clientManager.send({ type: 'init', options });
|
|
4941
|
+
// Wait for the state machine to transition to PLATFORM_CLASSES_INIT to ensure
|
|
4942
|
+
// any old actors are stopped and the new initialization flow begins
|
|
4943
|
+
try {
|
|
4944
|
+
await waitFor(clientManager, (snapshot) => {
|
|
4945
|
+
return snapshot.value === 'platformClassesInit' || snapshot.context.isInitialized;
|
|
4946
|
+
}, { timeout: 1000 });
|
|
4947
|
+
}
|
|
4948
|
+
catch (e) {
|
|
4949
|
+
// If we can't transition, continue anyway - the waitFor below will catch any errors
|
|
4950
|
+
logger('Timeout waiting for state transition, continuing...');
|
|
4951
|
+
}
|
|
4952
|
+
try {
|
|
4953
|
+
await waitFor(clientManager, (snapshot) => {
|
|
4954
|
+
return snapshot.context.isInitialized || snapshot.context.initError != null;
|
|
4955
|
+
}, { timeout: 120000 });
|
|
4956
|
+
const initError = clientManager.getSnapshot().context.initError;
|
|
4957
|
+
if (initError) {
|
|
4958
|
+
throw initError instanceof Error ? initError : new Error(String(initError));
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
catch (error) {
|
|
4962
|
+
// Ensure we never throw undefined
|
|
4963
|
+
if (error === undefined || error === null) {
|
|
4964
|
+
throw new Error('Initialization failed with undefined error');
|
|
4965
|
+
}
|
|
4966
|
+
throw error;
|
|
4967
|
+
}
|
|
4968
|
+
// Wire `@seedprotocol/query` local source once DB is ready
|
|
4969
|
+
registerSeedQueryLocalSource({ force: true });
|
|
4970
|
+
}, () => {
|
|
4971
|
+
const snapshot = clientManager.getSnapshot();
|
|
4972
|
+
return (snapshot.value === ClientManagerState.IDLE &&
|
|
4973
|
+
snapshot.context.isInitialized === true &&
|
|
4974
|
+
!snapshot.context.initError);
|
|
4975
|
+
});
|
|
4555
4976
|
// Singleton instance - created once at module load time
|
|
4556
4977
|
// ES modules cache exports, ensuring all imports get the same instance
|
|
4557
4978
|
const clientInstance = {
|
|
@@ -4562,87 +4983,32 @@ const clientInstance = {
|
|
|
4562
4983
|
// ensureInitialized();
|
|
4563
4984
|
return clientManager;
|
|
4564
4985
|
},
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
// Wait for the actor to be ready
|
|
4574
|
-
try {
|
|
4575
|
-
await waitFor(clientManager, (snapshot) => snapshot.status !== 'stopped', { timeout: 1000 });
|
|
4576
|
-
}
|
|
4577
|
-
catch (e) {
|
|
4578
|
-
logger('Timeout waiting for actor to restart, continuing anyway...');
|
|
4579
|
-
}
|
|
4580
|
-
}
|
|
4581
|
-
// Clear any stale context from previous failed initializations
|
|
4582
|
-
// This ensures we start with a clean slate before the new init updates it
|
|
4583
|
-
if (currentState !== 'uninitialized') {
|
|
4584
|
-
logger(`Client manager is in state ${currentState}, clearing stale context before re-init...`);
|
|
4585
|
-
clientManager.send({
|
|
4586
|
-
type: 'updateContext',
|
|
4587
|
-
context: {
|
|
4588
|
-
isInitialized: false,
|
|
4589
|
-
addressesSet: false,
|
|
4590
|
-
isSaving: false,
|
|
4591
|
-
syncFromEasOnAddressChange: false,
|
|
4592
|
-
endpoints: undefined,
|
|
4593
|
-
addresses: undefined,
|
|
4594
|
-
ownedAddresses: undefined,
|
|
4595
|
-
watchedAddresses: undefined,
|
|
4596
|
-
models: undefined,
|
|
4597
|
-
arweaveDomain: undefined,
|
|
4598
|
-
filesDir: undefined,
|
|
4599
|
-
dbConfig: undefined,
|
|
4600
|
-
initError: undefined,
|
|
4601
|
-
saveError: undefined,
|
|
4602
|
-
}
|
|
4603
|
-
});
|
|
4604
|
-
// Wait a moment for the context update to be processed
|
|
4605
|
-
await new Promise(resolve => setTimeout(resolve, 10));
|
|
4606
|
-
}
|
|
4607
|
-
// Send init event - the root-level handler will transition to PLATFORM_CLASSES_INIT
|
|
4608
|
-
// which will stop any running actors and start fresh with the new options
|
|
4609
|
-
// The platformClassesInit actor will update the context with the correct endpoints from options
|
|
4610
|
-
clientManager.send({ type: 'init', options });
|
|
4611
|
-
// Wait for the state machine to transition to PLATFORM_CLASSES_INIT to ensure
|
|
4612
|
-
// any old actors are stopped and the new initialization flow begins
|
|
4613
|
-
try {
|
|
4614
|
-
await waitFor(clientManager, (snapshot) => {
|
|
4615
|
-
return snapshot.value === 'platformClassesInit' || snapshot.context.isInitialized;
|
|
4616
|
-
}, { timeout: 1000 });
|
|
4617
|
-
}
|
|
4618
|
-
catch (e) {
|
|
4619
|
-
// If we can't transition, continue anyway - the waitFor below will catch any errors
|
|
4620
|
-
logger('Timeout waiting for state transition, continuing...');
|
|
4986
|
+
/**
|
|
4987
|
+
* Initialise the SDK. Calls made while an init is running share it. Once initialised, a
|
|
4988
|
+
* call with the same config resolves at once and applies any change in `addresses`; a
|
|
4989
|
+
* call with a different config throws INIT_CONFIG_CONFLICT_MESSAGE (call stop() first).
|
|
4990
|
+
*/
|
|
4991
|
+
init: async (options) => {
|
|
4992
|
+
if (activeInitConfig !== undefined && !isEqual(activeInitConfig, options?.config)) {
|
|
4993
|
+
throw new Error(INIT_CONFIG_CONFLICT_MESSAGE);
|
|
4621
4994
|
}
|
|
4995
|
+
const isRepeat = activeInitConfig !== undefined;
|
|
4996
|
+
activeInitConfig = options?.config;
|
|
4622
4997
|
try {
|
|
4623
|
-
await
|
|
4624
|
-
return snapshot.context.isInitialized || snapshot.context.initError != null;
|
|
4625
|
-
}, { timeout: 120000 });
|
|
4626
|
-
const initError = clientManager.getSnapshot().context.initError;
|
|
4627
|
-
if (initError) {
|
|
4628
|
-
throw initError instanceof Error ? initError : new Error(String(initError));
|
|
4629
|
-
}
|
|
4998
|
+
await coalescedInit(options);
|
|
4630
4999
|
}
|
|
4631
5000
|
catch (error) {
|
|
4632
|
-
|
|
4633
|
-
if (error === undefined || error === null) {
|
|
4634
|
-
throw new Error('Initialization failed with undefined error');
|
|
4635
|
-
}
|
|
5001
|
+
activeInitConfig = undefined;
|
|
4636
5002
|
throw error;
|
|
4637
5003
|
}
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
}
|
|
5004
|
+
if (isRepeat && options?.addresses !== undefined) {
|
|
5005
|
+
const wanted = normalizeAddressConfig(options.addresses);
|
|
5006
|
+
const current = { owned: await getOwnedAddressesFromDb(), watched: await getWatchedAddressesFromDb() };
|
|
5007
|
+
if (!isEqual(wanted, current)) {
|
|
5008
|
+
await clientInstance.setAddresses(wanted);
|
|
5009
|
+
}
|
|
5010
|
+
}
|
|
5011
|
+
},
|
|
4646
5012
|
setAddresses: async (addresses) => {
|
|
4647
5013
|
ensureInitialized();
|
|
4648
5014
|
logger('setAddresses', addresses);
|
|
@@ -4675,7 +5041,10 @@ const clientInstance = {
|
|
|
4675
5041
|
*/
|
|
4676
5042
|
claimUnpublishedDrafts: async (publisher) => {
|
|
4677
5043
|
ensureInitialized();
|
|
4678
|
-
|
|
5044
|
+
const result = await claimUnpublishedDrafts(publisher);
|
|
5045
|
+
// Loaded Items read publisher from their context; give the claimed ones the new value.
|
|
5046
|
+
Item.setPublisherForCachedSeeds(result.seedLocalIds, publisher);
|
|
5047
|
+
return result;
|
|
4679
5048
|
},
|
|
4680
5049
|
/**
|
|
4681
5050
|
* Hard-delete local on-chain seed copies for the given publisher addresses.
|
|
@@ -4730,21 +5099,38 @@ const clientInstance = {
|
|
|
4730
5099
|
// Global service removed - model registration is now handled by ClientManager
|
|
4731
5100
|
// Models are added to DB during the ADD_MODELS_TO_DB state
|
|
4732
5101
|
},
|
|
5102
|
+
/**
|
|
5103
|
+
* Calls `callback` once the client is initialised, or on the next microtask if it already
|
|
5104
|
+
* is. Returns a function that cancels the callback.
|
|
5105
|
+
*/
|
|
4733
5106
|
onReady: (callback) => {
|
|
5107
|
+
if (clientManager.getSnapshot().context.isInitialized) {
|
|
5108
|
+
let cancelled = false;
|
|
5109
|
+
queueMicrotask(() => {
|
|
5110
|
+
if (!cancelled)
|
|
5111
|
+
callback();
|
|
5112
|
+
});
|
|
5113
|
+
return () => {
|
|
5114
|
+
cancelled = true;
|
|
5115
|
+
};
|
|
5116
|
+
}
|
|
4734
5117
|
const subscription = clientManager.subscribe((snapshot) => {
|
|
4735
5118
|
if (snapshot.context.isInitialized) {
|
|
4736
5119
|
subscription.unsubscribe();
|
|
4737
5120
|
callback();
|
|
4738
5121
|
}
|
|
4739
5122
|
});
|
|
5123
|
+
return () => subscription.unsubscribe();
|
|
4740
5124
|
},
|
|
4741
5125
|
stop: () => {
|
|
4742
5126
|
ensureInitialized();
|
|
5127
|
+
activeInitConfig = undefined;
|
|
4743
5128
|
unregisterSeedQueryLocalSource();
|
|
4744
5129
|
clientManager.stop();
|
|
4745
5130
|
},
|
|
4746
5131
|
unload: () => {
|
|
4747
5132
|
ensureInitialized();
|
|
5133
|
+
activeInitConfig = undefined;
|
|
4748
5134
|
unregisterSeedQueryLocalSource();
|
|
4749
5135
|
clientManager.stop();
|
|
4750
5136
|
subscription.unsubscribe();
|
|
@@ -4760,9 +5146,10 @@ const getClient = () => {
|
|
|
4760
5146
|
var ClientManager$1 = /*#__PURE__*/Object.freeze({
|
|
4761
5147
|
__proto__: null,
|
|
4762
5148
|
ClientManager: ClientManager,
|
|
5149
|
+
INIT_CONFIG_CONFLICT_MESSAGE: INIT_CONFIG_CONFLICT_MESSAGE,
|
|
4763
5150
|
clientManager: clientManager,
|
|
4764
5151
|
getClient: getClient
|
|
4765
5152
|
});
|
|
4766
5153
|
|
|
4767
|
-
export {
|
|
4768
|
-
//# sourceMappingURL=ClientManager-
|
|
5154
|
+
export { requestEasSyncFromModelsInit as A, sendEasSyncClientRequest as B, ClientManager as C, startEasSyncActor as D, EAS_CHAIN_ID_APP_STATE_KEY as E, unregisterSeedQueryLocalSource as F, createModelsFromJson as G, getLatestSchemaVersion as H, INIT_CONFIG_CONFLICT_MESSAGE as I, jsonPropertiesToSchemaProperties as J, schema as K, ClientManager$1 as L, SEEDPROTOCOL_Seed_Protocol_v1 as S, assertLocalDbChain as a, importJsonSchema as b, convertVerbatimItemStorageRow as c, getContentHash as d, claimUnpublishedDrafts as e, createLocalQueryDataSource as f, getRefValueType as g, createSchema as h, isVerbatimItemStorageDraftRow as i, easSyncActor as j, getClient as k, loadSchemaFromFile as l, getPublishedSeedRecord as m, getSchemaNameFromId as n, isSeedQueryLocalSourceRegistered as o, listCompleteSchemaFiles as p, loadAllSchemasFromDb as q, readJsonImportFile as r, syncSchemaFromSource as s, transformImportToSchemaFile as t, mergeEasSyncRequestIntents as u, readSchema as v, waitForEasReadChain as w, registerSeedQueryLocalSource as x, requestEasSyncFromAddressChange as y, requestEasSyncFromEventBus as z };
|
|
5155
|
+
//# sourceMappingURL=ClientManager-i3nJASkg.js.map
|