@seedprotocol/sdk 0.7.3-next.613.g79a8dfd → 0.7.3-next.654.g52217f6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BasePathResolver-BdxCSIzn.js → BasePathResolver-CfSfMW5_.js} +7 -10
- package/dist/BasePathResolver-CfSfMW5_.js.map +1 -0
- package/dist/{ClientManager-DDA9956Y.js → ClientManager-C-QXqUK9.js} +438 -153
- package/dist/ClientManager-C-QXqUK9.js.map +1 -0
- package/dist/{Item-D4FigtYS.js → Item-C7sUUu2B.js} +291 -105
- package/dist/Item-C7sUUu2B.js.map +1 -0
- package/dist/{ModelProperty-BDt6AU2h.js → ModelProperty-DJxeOOrc.js} +28 -27
- package/dist/ModelProperty-DJxeOOrc.js.map +1 -0
- package/dist/{Schema-B8xqLWkL.js → Schema-fXtvd-yL.js} +30 -30
- package/dist/{Schema-B8xqLWkL.js.map → Schema-fXtvd-yL.js.map} +1 -1
- package/dist/{SchemaValidationService-BPxkfDLU.js → SchemaValidationService-CvRS2HSO.js} +10 -9
- package/dist/{SchemaValidationService-BPxkfDLU.js.map → SchemaValidationService-CvRS2HSO.js.map} +1 -1
- package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js → backfillMetadataPropertyIds-SXW-8C64.js} +4 -4
- package/dist/{backfillMetadataPropertyIds-DuTPcv8t.js.map → backfillMetadataPropertyIds-SXW-8C64.js.map} +1 -1
- package/dist/cjs/{ModelProperty-B-cZm1yU.js → ModelProperty-DXZ39Wyv.js} +24 -23
- package/dist/cjs/{ModelProperty-B-cZm1yU.js.map → ModelProperty-DXZ39Wyv.js.map} +1 -1
- package/dist/cjs/{Schema-STP972Xw.js → Schema-DdP109QD.js} +26 -25
- package/dist/cjs/{Schema-STP972Xw.js.map → Schema-DdP109QD.js.map} +1 -1
- package/dist/cjs/{SchemaValidationService-CKNW1bKg.js → SchemaValidationService-CSXxx7sQ.js} +5 -4
- package/dist/cjs/{SchemaValidationService-CKNW1bKg.js.map → SchemaValidationService-CSXxx7sQ.js.map} +1 -1
- package/dist/cjs/{backfillMetadataPropertyIds-CP3y1skt.js → backfillMetadataPropertyIds-CPYoaMl4.js} +6 -5
- package/dist/cjs/{backfillMetadataPropertyIds-CP3y1skt.js.map → backfillMetadataPropertyIds-CPYoaMl4.js.map} +1 -1
- package/dist/cjs/{eas-CAnUC4wd.js → eas-B2YDQssV.js} +6 -5
- package/dist/cjs/{eas-CAnUC4wd.js.map → eas-B2YDQssV.js.map} +1 -1
- package/dist/cjs/{getItem-CWgb3e9G.js → getItem-DgnaQzbE.js} +5 -4
- package/dist/cjs/{getItem-CWgb3e9G.js.map → getItem-DgnaQzbE.js.map} +1 -1
- package/dist/cjs/{getPublishPayload-BsZWiJ03.js → getPublishPayload-CqlqRdot.js} +12 -11
- package/dist/cjs/{getPublishPayload-BsZWiJ03.js.map → getPublishPayload-CqlqRdot.js.map} +1 -1
- package/dist/cjs/getPublishUploads-DsXY9S4U.js +872 -0
- package/dist/cjs/getPublishUploads-DsXY9S4U.js.map +1 -0
- package/dist/cjs/{index-nA5PxBSs.js → index-BHaWOwNF.js} +6 -5
- package/dist/cjs/index-BHaWOwNF.js.map +1 -0
- package/dist/cjs/{index-usKaANAq.js → index-C4XlgCJ4.js} +1156 -526
- package/dist/cjs/index-C4XlgCJ4.js.map +1 -0
- package/dist/cjs/{property-xMwPhQ5N.js → property-fa0iju0J.js} +8 -7
- package/dist/cjs/{property-xMwPhQ5N.js.map → property-fa0iju0J.js.map} +1 -1
- package/dist/cjs/{publishDraftGraph-BRWlR1KO.js → publishDraftGraph-3ASwAlD7.js} +4 -4
- package/dist/cjs/{publishDraftGraph-BRWlR1KO.js.map → publishDraftGraph-3ASwAlD7.js.map} +1 -1
- package/dist/cjs/{resetAmbiguousLegacyItemData-8nfkj9rz.js → resetAmbiguousLegacyItemData-Bu_MBBYt.js} +5 -4
- package/dist/cjs/{resetAmbiguousLegacyItemData-8nfkj9rz.js.map → resetAmbiguousLegacyItemData-Bu_MBBYt.js.map} +1 -1
- package/dist/cjs/{resolveModelForSyncedSeed-kYRuDWYw.js → resolveModelForSyncedSeed-BANIiuFU.js} +2 -2
- package/dist/cjs/{resolveModelForSyncedSeed-kYRuDWYw.js.map → resolveModelForSyncedSeed-BANIiuFU.js.map} +1 -1
- package/dist/cjs/{syncDbWithEas-DqRhV8o2.js → syncDbWithEas-CrmxxmUW.js} +10 -9
- package/dist/cjs/{syncDbWithEas-DqRhV8o2.js.map → syncDbWithEas-CrmxxmUW.js.map} +1 -1
- package/dist/{configurePlatform-YcOiDQBZ.js → configurePlatform-BRw2j0ZN.js} +7 -4
- package/dist/{configurePlatform-YcOiDQBZ.js.map → configurePlatform-BRw2j0ZN.js.map} +1 -1
- package/dist/{db-CQt-gcAl.js → db-D9K_f5cF.js} +14 -14
- package/dist/{db-CQt-gcAl.js.map → db-D9K_f5cF.js.map} +1 -1
- package/dist/{eas-CpOD74Ke.js → eas-DHxfswCt.js} +8 -5
- package/dist/eas-DHxfswCt.js.map +1 -0
- package/dist/{getItem-B_OoFkd7.js → getItem-d6N_aM6S.js} +8 -5
- package/dist/{getItem-B_OoFkd7.js.map → getItem-d6N_aM6S.js.map} +1 -1
- package/dist/{getPublishPayload-Xl3sRkR-.js → getPublishPayload-BHrxVtzY.js} +16 -16
- package/dist/{getPublishPayload-Xl3sRkR-.js.map → getPublishPayload-BHrxVtzY.js.map} +1 -1
- package/dist/getPublishUploads-BEqRiKIS.js +657 -0
- package/dist/getPublishUploads-BEqRiKIS.js.map +1 -0
- package/dist/{index-BGt4_oPO.js → index-CiMEoGu3.js} +12 -11
- package/dist/index-CiMEoGu3.js.map +1 -0
- package/dist/{index-CSOQFAOn.js → index-DglvthOk.js} +2 -2
- package/dist/index-DglvthOk.js.map +1 -0
- package/dist/{index-Xl1_4Lmb.js → index-s15q14rm.js} +29 -29
- package/dist/{index-Xl1_4Lmb.js.map → index-s15q14rm.js.map} +1 -1
- package/dist/{index.browser-CjTe0vt1.js → index.browser-Cm06tP4X.js} +553 -165
- package/dist/index.browser-Cm06tP4X.js.map +1 -0
- package/dist/{index.node-Cfa7npS6.js → index.node-C30dmFgn.js} +5 -5
- package/dist/{index.node-Cfa7npS6.js.map → index.node-C30dmFgn.js.map} +1 -1
- package/dist/main.cjs +4 -3
- package/dist/main.cjs.map +1 -1
- package/dist/main.js +32 -44
- 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 +13 -12
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +9 -7
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.node.js +3 -3
- package/dist/{property-BrXkY1Rg.js → property-DhmmYAvQ.js} +12 -9
- package/dist/property-DhmmYAvQ.js.map +1 -0
- package/dist/{publishDraftGraph-X0Wr9txE.js → publishDraftGraph-yYP74WRt.js} +8 -8
- package/dist/{publishDraftGraph-X0Wr9txE.js.map → publishDraftGraph-yYP74WRt.js.map} +1 -1
- package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js → resetAmbiguousLegacyItemData-Bk0QyDW8.js} +2 -2
- package/dist/{resetAmbiguousLegacyItemData-Ci6PM_vC.js.map → resetAmbiguousLegacyItemData-Bk0QyDW8.js.map} +1 -1
- package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js → resolveModelForSyncedSeed-8cAzvUFd.js} +2 -2
- package/dist/{resolveModelForSyncedSeed-DFVdnYq8.js.map → resolveModelForSyncedSeed-8cAzvUFd.js.map} +1 -1
- package/dist/src/Item/Item.d.ts +1 -1
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.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/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/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/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/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/compositeUpload.d.ts +28 -0
- package/dist/src/helpers/compositeUpload.d.ts.map +1 -0
- 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 +19 -3
- package/dist/src/helpers/ownership.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/index.d.ts +6 -4
- package/dist/src/index.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/publish.d.ts +14 -0
- package/dist/src/types/publish.d.ts.map +1 -1
- package/dist/{syncDbWithEas-BU-jZ5bJ.js → syncDbWithEas--HUA9WNb.js} +15 -14
- package/dist/syncDbWithEas--HUA9WNb.js.map +1 -0
- package/dist/{tabEvents-BZJMY5uK.js → tabEvents-DguZpCCv.js} +294 -58
- package/dist/tabEvents-DguZpCCv.js.map +1 -0
- package/dist/tolerantWebAccess-BZYWt09Y.js +551 -0
- package/dist/tolerantWebAccess-BZYWt09Y.js.map +1 -0
- package/dist/{updateSeedRevokedAt-iLpzae1i.js → updateSeedRevokedAt-D_EG-q3b.js} +3 -3
- package/dist/{updateSeedRevokedAt-iLpzae1i.js.map → updateSeedRevokedAt-D_EG-q3b.js.map} +1 -1
- package/package.json +5 -5
- 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/cjs/getPublishUploads-BQr8aMVP.js +0 -495
- package/dist/cjs/getPublishUploads-BQr8aMVP.js.map +0 -1
- package/dist/cjs/index-nA5PxBSs.js.map +0 -1
- package/dist/cjs/index-usKaANAq.js.map +0 -1
- package/dist/eas-CpOD74Ke.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.map +0 -1
- package/dist/index-CSOQFAOn.js.map +0 -1
- package/dist/index.browser-CjTe0vt1.js.map +0 -1
- package/dist/property-BrXkY1Rg.js.map +0 -1
- package/dist/syncDbWithEas-BU-jZ5bJ.js.map +0 -1
- 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,15 +1,15 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
2
|
import { createActor, setup, assign, fromPromise, fromCallback, waitFor } from 'xstate';
|
|
3
|
-
import { m as eventEmitter, C as normalizeAddressConfig, E as normalizeAddressList, S as loadModelsFromDbForSchema, O as addSchemaToDb, n as normalizeDataType, U as linkModelToSchema, s as normalizePublisher, V as getWatchedAddressesFromDb, W as getOwnedAddressesFromDb } from './db-
|
|
4
|
-
import { u as MachineIds,
|
|
5
|
-
import {
|
|
6
|
-
import { eq, inArray, and, isNotNull, ne, desc, countDistinct,
|
|
7
|
-
import {
|
|
3
|
+
import { m as eventEmitter, C as normalizeAddressConfig, E as normalizeAddressList, S as loadModelsFromDbForSchema, O as addSchemaToDb, n as normalizeDataType, U as linkModelToSchema, r as resolveItemModelFileId, s as normalizePublisher, V as getWatchedAddressesFromDb, W as getOwnedAddressesFromDb } from './db-D9K_f5cF.js';
|
|
4
|
+
import { u as MachineIds, Y as ClientManagerEvents, Z as withLockedItemStorageRow, _ as getItemStorageFilePath, $ as writeItemStorageFile, c as compareMetadataRowsLatestFirst, C as ClientManagerState, a0 as resolvePublisherFromSeedRow, F as isLocalUnsealedDraft, I as Item } from './Item-C7sUUu2B.js';
|
|
5
|
+
import { B as BaseDb, e as easSyncProcesses, r as BasePathResolver, a as appState, t as BaseFileManager, i as models$1, g as modelUids, q as seeds, s as schemas, K as isInternalSchema, L as INTERNAL_SCHEMA_IDS, F as SEED_PROTOCOL_SCHEMA_NAME, f as modelSchemas, m as metadata$1, p as properties, v as versions, h as htmlEmbeddedImageCoPublish, b as arweaveL1FinalizeJobs, o as publishProcesses, M as CLIENT_NOT_INITIALIZED } from './BasePathResolver-CfSfMW5_.js';
|
|
6
|
+
import { eq, inArray, and, isNotNull, ne, desc, countDistinct, isNull, or, like } from 'drizzle-orm';
|
|
7
|
+
import { D as withDbTabLock, v as isLeaderTab, H as postTabMessage, I as onTabMessage, B as whenLeaderTab, J as listenForOtherTabsEvents, K as isNode, M as isBrowser, N as startTabCoordination, O as downloadAllFilesRequestHandler, P as downloadAllFilesBinaryRequestHandler, t as toSnakeCase, G as withSeedDbLock, j as generateId, y as parseAddressesPersistedPayload, h as emitAcrossTabs, A as ADDRESSES_PERSISTED_EVENT, L as LOCAL_COPIES_REMOVED_EVENT } from './tabEvents-DguZpCCv.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
14
|
import { startCase } from 'lodash-es';
|
|
15
15
|
|
|
@@ -109,7 +109,7 @@ const runEasSync = fromPromise(async ({ input, }) => {
|
|
|
109
109
|
requestPayload: input.requestPayload,
|
|
110
110
|
persistedSnapshot: input.runningSnapshot,
|
|
111
111
|
});
|
|
112
|
-
const { runSyncFromEas } = await import('./syncDbWithEas
|
|
112
|
+
const { runSyncFromEas } = await import('./syncDbWithEas--HUA9WNb.js');
|
|
113
113
|
try {
|
|
114
114
|
// Sync checks for rows and then inserts the rest (no unique index on uids), so syncs in
|
|
115
115
|
// different tabs take turns. A sync can run for minutes, so wait without a timeout.
|
|
@@ -285,7 +285,7 @@ function newCorrelationId() {
|
|
|
285
285
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
286
286
|
}
|
|
287
287
|
/** Requests deferred in this tab until it leads, by source; each runs once on takeover. */
|
|
288
|
-
const deferredUntilLeader = new Set();
|
|
288
|
+
const deferredUntilLeader$1 = new Set();
|
|
289
289
|
/**
|
|
290
290
|
* Automatic syncs run in the leader tab only (docs/MULTI_TAB.md). A tab that skips one runs it if
|
|
291
291
|
* it later becomes leader, so closing the leader doesn't lose the catch-up sync.
|
|
@@ -296,11 +296,11 @@ function runInLeaderTab(source, request) {
|
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
298
|
log(`${source} sync skipped: another tab leads`);
|
|
299
|
-
if (deferredUntilLeader.has(source))
|
|
299
|
+
if (deferredUntilLeader$1.has(source))
|
|
300
300
|
return;
|
|
301
|
-
deferredUntilLeader.add(source);
|
|
301
|
+
deferredUntilLeader$1.add(source);
|
|
302
302
|
void whenLeaderTab().then(() => {
|
|
303
|
-
deferredUntilLeader.delete(source);
|
|
303
|
+
deferredUntilLeader$1.delete(source);
|
|
304
304
|
request();
|
|
305
305
|
});
|
|
306
306
|
}
|
|
@@ -374,10 +374,10 @@ var easSyncManager = /*#__PURE__*/Object.freeze({
|
|
|
374
374
|
startEasSyncActor: startEasSyncActor
|
|
375
375
|
});
|
|
376
376
|
|
|
377
|
-
const logger$
|
|
377
|
+
const logger$c = debug('seedSdk:services:events');
|
|
378
378
|
const handleServiceSaveState = (event) => {
|
|
379
379
|
const { state, serviceId } = event;
|
|
380
|
-
logger$
|
|
380
|
+
logger$c(`[browser] [service.saveState.request] serviceId: ${serviceId}`);
|
|
381
381
|
// TODO: This is called from Node as well. Do we need it? If so, need to generalize this to all platforms.
|
|
382
382
|
// localStorage.setItem(`seed_sdk_service_${serviceId}`, JSON.stringify(state))
|
|
383
383
|
};
|
|
@@ -428,9 +428,9 @@ function normalizeSeedConfigEndpoints(config) {
|
|
|
428
428
|
return { ...config, endpoints: next };
|
|
429
429
|
}
|
|
430
430
|
|
|
431
|
-
const logger$
|
|
431
|
+
const logger$b = debug('seedSdk:ClientManager:initialize');
|
|
432
432
|
const platformClassesInit = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
433
|
-
logger$
|
|
433
|
+
logger$b('initialize from ClientManager');
|
|
434
434
|
const { isInitialized } = context;
|
|
435
435
|
if (!event || !('options' in event)) {
|
|
436
436
|
throw new Error('Initialize event must include options');
|
|
@@ -463,7 +463,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
463
463
|
}
|
|
464
464
|
// Prefer the condition-resolved factory when available; fall back to explicit
|
|
465
465
|
// platform imports so source/vitest resolution stays reliable.
|
|
466
|
-
const { configurePlatform } = await import('./configurePlatform-
|
|
466
|
+
const { configurePlatform } = await import('./configurePlatform-BRw2j0ZN.js');
|
|
467
467
|
if (isBrowser()) {
|
|
468
468
|
const { createPlatformServices } = await import('./platform.browser.js');
|
|
469
469
|
configurePlatform(createPlatformServices());
|
|
@@ -602,7 +602,7 @@ const platformClassesInit = fromCallback(({ sendBack, input: { context, event }
|
|
|
602
602
|
};
|
|
603
603
|
});
|
|
604
604
|
|
|
605
|
-
const logger$
|
|
605
|
+
const logger$a = debug('seedSdk:client:writeToDb');
|
|
606
606
|
const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
607
607
|
const _saveAppState = async () => {
|
|
608
608
|
try {
|
|
@@ -610,7 +610,7 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
610
610
|
if (!appDb) {
|
|
611
611
|
// In test environments, continue anyway
|
|
612
612
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
613
|
-
logger$
|
|
613
|
+
logger$a('[client/actors] [saveAppState] App DB not found, but continuing in test environment');
|
|
614
614
|
return;
|
|
615
615
|
}
|
|
616
616
|
throw new Error('App DB not found');
|
|
@@ -626,13 +626,13 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
626
626
|
value: JSON.stringify(value),
|
|
627
627
|
},
|
|
628
628
|
});
|
|
629
|
-
logger$
|
|
629
|
+
logger$a('result', result);
|
|
630
630
|
}
|
|
631
631
|
catch (error) {
|
|
632
|
-
logger$
|
|
632
|
+
logger$a('[client/actors] [saveAppState] Error saving app state:', error);
|
|
633
633
|
// In test environments, continue anyway
|
|
634
634
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
635
|
-
logger$
|
|
635
|
+
logger$a('[client/actors] [saveAppState] Continuing despite error in test environment');
|
|
636
636
|
return;
|
|
637
637
|
}
|
|
638
638
|
throw error;
|
|
@@ -647,10 +647,10 @@ const saveAppState = fromCallback(({ sendBack, input: { key, value } }) => {
|
|
|
647
647
|
});
|
|
648
648
|
})
|
|
649
649
|
.catch((error) => {
|
|
650
|
-
logger$
|
|
650
|
+
logger$a('[client/actors] [saveAppState] Error in promise chain:', error);
|
|
651
651
|
// In test environments, still send success to allow state machine to progress
|
|
652
652
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
653
|
-
logger$
|
|
653
|
+
logger$a('[client/actors] [saveAppState] Sending success despite error in test environment');
|
|
654
654
|
sendBack({
|
|
655
655
|
type: 'saveAppStateSuccess',
|
|
656
656
|
key,
|
|
@@ -720,7 +720,7 @@ const fileSystemInit = fromCallback(({ sendBack, input: { context }, }) => {
|
|
|
720
720
|
};
|
|
721
721
|
});
|
|
722
722
|
|
|
723
|
-
const logger$
|
|
723
|
+
const logger$9 = debug('seedSdk:client:actors:dbInit');
|
|
724
724
|
const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
725
725
|
const _dbInit = async () => {
|
|
726
726
|
const { filesDir } = context;
|
|
@@ -734,14 +734,14 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
734
734
|
if (!appDb) {
|
|
735
735
|
throw new Error('Database not available after preparation');
|
|
736
736
|
}
|
|
737
|
-
logger$
|
|
737
|
+
logger$9('[client/actors] [dbInit] Database prepared and ready');
|
|
738
738
|
};
|
|
739
739
|
_dbInit()
|
|
740
740
|
.then(() => {
|
|
741
741
|
sendBack({ type: ClientManagerEvents.DB_READY });
|
|
742
742
|
})
|
|
743
743
|
.catch((error) => {
|
|
744
|
-
logger$
|
|
744
|
+
logger$9('Error in dbInit:', error);
|
|
745
745
|
sendBack({
|
|
746
746
|
type: 'error',
|
|
747
747
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -749,7 +749,7 @@ const dbInit = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
749
749
|
});
|
|
750
750
|
});
|
|
751
751
|
|
|
752
|
-
const logger$
|
|
752
|
+
const logger$8 = debug('seedSdk:client:actors:addModelsToStore');
|
|
753
753
|
const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
754
754
|
const _addModelsToStore = async () => {
|
|
755
755
|
let { models } = context;
|
|
@@ -763,7 +763,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
763
763
|
// Models are now Model instances, no registration needed
|
|
764
764
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
765
765
|
for (const [key] of Object.entries(allModels)) {
|
|
766
|
-
logger$
|
|
766
|
+
logger$8('model available:', key);
|
|
767
767
|
}
|
|
768
768
|
};
|
|
769
769
|
_addModelsToStore()
|
|
@@ -771,7 +771,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
771
771
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_STORE_SUCCESS });
|
|
772
772
|
})
|
|
773
773
|
.catch((error) => {
|
|
774
|
-
logger$
|
|
774
|
+
logger$8('[client/actors] [addModelsToStore] Error:', error);
|
|
775
775
|
sendBack({
|
|
776
776
|
type: 'error',
|
|
777
777
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
@@ -779,7 +779,7 @@ const addModelsToStore = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
779
779
|
});
|
|
780
780
|
});
|
|
781
781
|
|
|
782
|
-
const logger$
|
|
782
|
+
const logger$7 = debug('seedSdk:client:actors:addModelsToDb');
|
|
783
783
|
/**
|
|
784
784
|
* Returns every `models` row named in `modelNames`, inserting a null-schemaFileId stub for each name
|
|
785
785
|
* with no row yet (the schema import adopts stubs via findOrCreateModelRecord). Check-then-insert:
|
|
@@ -802,7 +802,7 @@ async function ensureModelStubs(appDb, modelNames, filesDir) {
|
|
|
802
802
|
.returning({ id: models$1.id, name: models$1.name, schemaFileId: models$1.schemaFileId }));
|
|
803
803
|
rows.push(...newlyInserted);
|
|
804
804
|
for (const name of modelsToInsert) {
|
|
805
|
-
logger$
|
|
805
|
+
logger$7('[client/actors] [addModelsToDb] inserted model:', name);
|
|
806
806
|
}
|
|
807
807
|
}
|
|
808
808
|
return rows;
|
|
@@ -839,7 +839,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
839
839
|
for (const modelName of modelNames) {
|
|
840
840
|
const foundModel = rowFor(modelName);
|
|
841
841
|
if (!foundModel) {
|
|
842
|
-
logger$
|
|
842
|
+
logger$7('[client/actors] [addModelsToDb] Warning: Could not find or create model:', modelName);
|
|
843
843
|
hasModelsInDb = false;
|
|
844
844
|
continue;
|
|
845
845
|
}
|
|
@@ -851,7 +851,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
851
851
|
}
|
|
852
852
|
// If we have no models to process, still send success (empty models is valid)
|
|
853
853
|
if (schemaDefsByModelName.size === 0) {
|
|
854
|
-
logger$
|
|
854
|
+
logger$7('[client/actors] [addModelsToDb] No models to process, but continuing');
|
|
855
855
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
856
856
|
return;
|
|
857
857
|
}
|
|
@@ -894,15 +894,15 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
894
894
|
requestEasSyncFromModelsInit();
|
|
895
895
|
}
|
|
896
896
|
else {
|
|
897
|
-
logger$
|
|
897
|
+
logger$7('[client/actors] [addModelsToDb] No schemas found from EAS, but continuing');
|
|
898
898
|
}
|
|
899
899
|
}
|
|
900
900
|
catch (error) {
|
|
901
901
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
902
|
-
logger$
|
|
902
|
+
logger$7('[client/actors] [addModelsToDb] Warning: Could not fetch schemas from EAS (background):', error.message);
|
|
903
903
|
}
|
|
904
904
|
else {
|
|
905
|
-
logger$
|
|
905
|
+
logger$7('[client/actors] [addModelsToDb] Error fetching schemas (background):', error.message);
|
|
906
906
|
}
|
|
907
907
|
}
|
|
908
908
|
};
|
|
@@ -914,10 +914,10 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
914
914
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
915
915
|
})
|
|
916
916
|
.catch((error) => {
|
|
917
|
-
logger$
|
|
917
|
+
logger$7('[client/actors] [addModelsToDb] Error:', error);
|
|
918
918
|
// In test environments, still send success to allow initialization to complete
|
|
919
919
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
920
|
-
logger$
|
|
920
|
+
logger$7('[client/actors] [addModelsToDb] Continuing despite error in test environment');
|
|
921
921
|
sendBack({ type: ClientManagerEvents.ADD_MODELS_TO_DB_SUCCESS });
|
|
922
922
|
}
|
|
923
923
|
else {
|
|
@@ -930,7 +930,7 @@ const addModelsToDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
930
930
|
return () => { };
|
|
931
931
|
});
|
|
932
932
|
|
|
933
|
-
const logger$
|
|
933
|
+
const logger$6 = debug('seedSdk:helpers:localDbChain');
|
|
934
934
|
/** appState key recording which EAS chain the local database holds attestations from. */
|
|
935
935
|
const EAS_CHAIN_ID_APP_STATE_KEY = 'easChainId';
|
|
936
936
|
/**
|
|
@@ -1000,7 +1000,7 @@ async function loadLocalDbChain() {
|
|
|
1000
1000
|
const localChainId = await resolveLocalDbChainId(appDb);
|
|
1001
1001
|
if (localChainId !== undefined) {
|
|
1002
1002
|
configureEasReadChain('localDb', { chainId: localChainId });
|
|
1003
|
-
logger$
|
|
1003
|
+
logger$6('local DB holds chain %d', localChainId);
|
|
1004
1004
|
return;
|
|
1005
1005
|
}
|
|
1006
1006
|
if (isEasReadChainConfigured()) {
|
|
@@ -1026,7 +1026,7 @@ async function assertLocalDbChain() {
|
|
|
1026
1026
|
configureEasReadChain('localDb', { chainId: localChainId ?? chainId });
|
|
1027
1027
|
}
|
|
1028
1028
|
|
|
1029
|
-
const logger$
|
|
1029
|
+
const logger$5 = debug('seedSdk:client:actors:saveConfig');
|
|
1030
1030
|
/**
|
|
1031
1031
|
* Saves the addresses passed to init. Hosts pass `addresses: []` before a wallet connects. In the
|
|
1032
1032
|
* first (leader) tab that clears stored addresses, as it always has, so drafts made before the
|
|
@@ -1046,13 +1046,13 @@ async function persistInitAddresses(appDb, { addresses, ownedAddresses, watchedA
|
|
|
1046
1046
|
.onConflictDoUpdate({ target: appState.key, set: { value } });
|
|
1047
1047
|
}
|
|
1048
1048
|
const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
1049
|
-
logger$
|
|
1049
|
+
logger$5('saveConfig starting');
|
|
1050
1050
|
const { endpoints, addresses, ownedAddresses, watchedAddresses, arweaveDomain, uploadApiBaseUrl, gatewayTransport, gatewayHyperKey, gatewaySidecarHost, gatewaySidecarPort, gatewayProxyBaseUrl, } = context;
|
|
1051
1051
|
// Validate endpoints - required for proper initialization
|
|
1052
1052
|
// If endpoints are missing or invalid, initialization should fail
|
|
1053
1053
|
if (!endpoints || !endpoints.filePaths || !endpoints.files) {
|
|
1054
1054
|
const error = new Error('saveConfig called with invalid endpoints: endpoints must include both filePaths and files');
|
|
1055
|
-
logger$
|
|
1055
|
+
logger$5('[internal/actors] [saveConfig] Invalid endpoints:', { endpoints });
|
|
1056
1056
|
throw error;
|
|
1057
1057
|
}
|
|
1058
1058
|
const _saveConfig = async () => {
|
|
@@ -1061,7 +1061,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1061
1061
|
if (!appDb) {
|
|
1062
1062
|
// In test environments, continue anyway
|
|
1063
1063
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1064
|
-
logger$
|
|
1064
|
+
logger$5('[internal/actors] [saveConfig] App DB not found, but continuing in test environment');
|
|
1065
1065
|
return;
|
|
1066
1066
|
}
|
|
1067
1067
|
throw new Error('App DB not found');
|
|
@@ -1116,10 +1116,10 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1116
1116
|
await loadLocalDbChain();
|
|
1117
1117
|
}
|
|
1118
1118
|
catch (error) {
|
|
1119
|
-
logger$
|
|
1119
|
+
logger$5('[internal/actors] [saveConfig] Error saving config:', error);
|
|
1120
1120
|
// In test environments, continue anyway
|
|
1121
1121
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1122
|
-
logger$
|
|
1122
|
+
logger$5('[internal/actors] [saveConfig] Continuing despite error in test environment');
|
|
1123
1123
|
return;
|
|
1124
1124
|
}
|
|
1125
1125
|
throw error;
|
|
@@ -1128,14 +1128,14 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1128
1128
|
// Init writes run one tab at a time (docs/MULTI_TAB.md).
|
|
1129
1129
|
withSeedDbLock('init', context.filesDir, _saveConfig)
|
|
1130
1130
|
.then(() => {
|
|
1131
|
-
logger$
|
|
1131
|
+
logger$5('[internal/actors] [saveConfig] saveConfig success');
|
|
1132
1132
|
return sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
|
|
1133
1133
|
})
|
|
1134
1134
|
.catch((error) => {
|
|
1135
|
-
logger$
|
|
1135
|
+
logger$5('[internal/actors] [saveConfig] Error in saveConfig promise chain:', error);
|
|
1136
1136
|
// In test environments, still send success to allow state machine to progress
|
|
1137
1137
|
if (process.env.NODE_ENV === 'test' || process.env.IS_SEED_DEV) {
|
|
1138
|
-
logger$
|
|
1138
|
+
logger$5('[internal/actors] [saveConfig] Sending success despite error in test environment');
|
|
1139
1139
|
sendBack({ type: ClientManagerEvents.SAVE_CONFIG_SUCCESS });
|
|
1140
1140
|
}
|
|
1141
1141
|
else {
|
|
@@ -1148,7 +1148,7 @@ const saveConfig = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1148
1148
|
return () => { };
|
|
1149
1149
|
});
|
|
1150
1150
|
|
|
1151
|
-
const logger$
|
|
1151
|
+
const logger$4 = debug('seedSdk:helpers:schema');
|
|
1152
1152
|
/**
|
|
1153
1153
|
* Sanitize a schema name to be filesystem-safe
|
|
1154
1154
|
* Replaces all special characters (except alphanumeric, hyphens, underscores) with underscores
|
|
@@ -1344,7 +1344,7 @@ async function listCompleteSchemaFiles() {
|
|
|
1344
1344
|
const dirExists = await BaseFileManager.pathExists(workingDir);
|
|
1345
1345
|
if (!dirExists) {
|
|
1346
1346
|
// Directory doesn't exist yet - return empty array (not an error condition)
|
|
1347
|
-
logger$
|
|
1347
|
+
logger$4(`Working directory does not exist yet: ${workingDir}, returning empty schema list`);
|
|
1348
1348
|
return [];
|
|
1349
1349
|
}
|
|
1350
1350
|
const files = await fs.promises.readdir(workingDir);
|
|
@@ -1480,7 +1480,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1480
1480
|
}
|
|
1481
1481
|
catch (error) {
|
|
1482
1482
|
// If we can't list schema files (e.g., directory doesn't exist yet), continue without file-based loading
|
|
1483
|
-
logger$
|
|
1483
|
+
logger$4(`Error listing complete schema files (continuing with DB data): ${error instanceof Error ? error.message : String(error)}`);
|
|
1484
1484
|
completeSchemaFiles = [];
|
|
1485
1485
|
}
|
|
1486
1486
|
}
|
|
@@ -1533,7 +1533,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1533
1533
|
continue;
|
|
1534
1534
|
}
|
|
1535
1535
|
catch (error) {
|
|
1536
|
-
logger$
|
|
1536
|
+
logger$4(`Error parsing schemaData for ${schemaName}:`, error);
|
|
1537
1537
|
// Fall through to file-based loading
|
|
1538
1538
|
}
|
|
1539
1539
|
}
|
|
@@ -1575,7 +1575,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1575
1575
|
continue;
|
|
1576
1576
|
}
|
|
1577
1577
|
catch (error) {
|
|
1578
|
-
logger$
|
|
1578
|
+
logger$4(`Error loading schema file for ${schemaName}:`, error);
|
|
1579
1579
|
// Fall through to try loading from schemaData if available
|
|
1580
1580
|
}
|
|
1581
1581
|
}
|
|
@@ -1619,7 +1619,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1619
1619
|
continue;
|
|
1620
1620
|
}
|
|
1621
1621
|
catch (error) {
|
|
1622
|
-
logger$
|
|
1622
|
+
logger$4(`Error parsing schemaData for ${schemaName}:`, error);
|
|
1623
1623
|
}
|
|
1624
1624
|
}
|
|
1625
1625
|
}
|
|
@@ -1630,11 +1630,11 @@ async function loadAllSchemasFromDb() {
|
|
|
1630
1630
|
// Only process if not already in result
|
|
1631
1631
|
if (!processedSchemaNames.has(schemaFileInfo.name)) {
|
|
1632
1632
|
if (isInternalSchema(schemaFileInfo.name, schemaFileInfo.schemaFileId)) {
|
|
1633
|
-
logger$
|
|
1633
|
+
logger$4(`STEP 3: skipping internal schema file: ${schemaFileInfo.filePath}`);
|
|
1634
1634
|
continue;
|
|
1635
1635
|
}
|
|
1636
1636
|
try {
|
|
1637
|
-
logger$
|
|
1637
|
+
logger$4(`STEP 3: processing schema file: ${schemaFileInfo.name} from ${schemaFileInfo.filePath}`);
|
|
1638
1638
|
const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
|
|
1639
1639
|
const schemaFile = JSON.parse(content);
|
|
1640
1640
|
// Import this schema to database (mark as non-draft since it's in a file)
|
|
@@ -1654,7 +1654,7 @@ async function loadAllSchemasFromDb() {
|
|
|
1654
1654
|
processedSchemaNames.add(schemaFileInfo.name);
|
|
1655
1655
|
}
|
|
1656
1656
|
catch (error) {
|
|
1657
|
-
logger$
|
|
1657
|
+
logger$4(`Error loading schema file ${schemaFileInfo.filePath}:`, error);
|
|
1658
1658
|
}
|
|
1659
1659
|
}
|
|
1660
1660
|
}
|
|
@@ -1671,7 +1671,7 @@ async function migrateFileSchemasToDb() {
|
|
|
1671
1671
|
if (!db) {
|
|
1672
1672
|
throw new Error('Database not found');
|
|
1673
1673
|
}
|
|
1674
|
-
logger$
|
|
1674
|
+
logger$4('Starting migration of file-based schemas to database');
|
|
1675
1675
|
// Get all complete schema files
|
|
1676
1676
|
const completeSchemas = await listCompleteSchemaFiles();
|
|
1677
1677
|
let migratedCount = 0;
|
|
@@ -1681,7 +1681,7 @@ async function migrateFileSchemasToDb() {
|
|
|
1681
1681
|
const content = await BaseFileManager.readFileAsString(schemaFileInfo.filePath);
|
|
1682
1682
|
const schemaFile = JSON.parse(content);
|
|
1683
1683
|
if (!schemaFile.$schema || !schemaFile.metadata?.name) {
|
|
1684
|
-
logger$
|
|
1684
|
+
logger$4(`Skipping invalid schema file: ${schemaFileInfo.filePath}`);
|
|
1685
1685
|
continue;
|
|
1686
1686
|
}
|
|
1687
1687
|
const schemaName = schemaFile.metadata.name;
|
|
@@ -1703,17 +1703,17 @@ async function migrateFileSchemasToDb() {
|
|
|
1703
1703
|
JSON.stringify(schemaFile, null, 2), // schemaData
|
|
1704
1704
|
false);
|
|
1705
1705
|
migratedCount++;
|
|
1706
|
-
logger$
|
|
1706
|
+
logger$4(`Migrated schema: ${schemaName} v${schemaFile.version}`);
|
|
1707
1707
|
}
|
|
1708
1708
|
else {
|
|
1709
|
-
logger$
|
|
1709
|
+
logger$4(`Schema ${schemaName} already exists in database, skipping`);
|
|
1710
1710
|
}
|
|
1711
1711
|
}
|
|
1712
1712
|
catch (error) {
|
|
1713
|
-
logger$
|
|
1713
|
+
logger$4(`Error migrating schema file ${schemaFileInfo.filePath}:`, error);
|
|
1714
1714
|
}
|
|
1715
1715
|
}
|
|
1716
|
-
logger$
|
|
1716
|
+
logger$4(`Migration complete: ${migratedCount} schemas migrated`);
|
|
1717
1717
|
return migratedCount;
|
|
1718
1718
|
}
|
|
1719
1719
|
/**
|
|
@@ -1768,7 +1768,7 @@ const getDeterministicIdsWithPrefix = (prefix) => {
|
|
|
1768
1768
|
return (suffix) => bytesToHex(prefixHash.clone().update(utf8ToBytes(suffix)).digest()).slice(0, 10);
|
|
1769
1769
|
};
|
|
1770
1770
|
|
|
1771
|
-
const logger$
|
|
1771
|
+
const logger$3 = debug('seedSdk:imports:json');
|
|
1772
1772
|
/**
|
|
1773
1773
|
* Get refValueType from a property object with case-insensitive key lookup.
|
|
1774
1774
|
* Handles refValueType, refvaluetype, ref_value_type, elementType, and legacy items.type / items.Type.
|
|
@@ -1846,7 +1846,7 @@ function getRefValueType(prop) {
|
|
|
1846
1846
|
* @returns Promise that resolves when properties are found, or rejects if not found after max retries
|
|
1847
1847
|
*/
|
|
1848
1848
|
const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10, retryDelay = 100) => {
|
|
1849
|
-
const _mod_0 = await import('./BasePathResolver-
|
|
1849
|
+
const _mod_0 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
1850
1850
|
const _ns_0 = _mod_0.N;
|
|
1851
1851
|
const modelSchemaMod = _ns_0;
|
|
1852
1852
|
const { properties: propertiesTable } = modelSchemaMod;
|
|
@@ -1859,11 +1859,11 @@ const verifyPropertiesPersisted = async (db, modelId, modelName, maxRetries = 10
|
|
|
1859
1859
|
.where(eq(propertiesTable.modelId, modelId))
|
|
1860
1860
|
.limit(1);
|
|
1861
1861
|
if (props.length > 0) {
|
|
1862
|
-
logger$
|
|
1862
|
+
logger$3(`Verified properties exist for model "${modelName}" (modelId: ${modelId}) after ${attempt + 1} attempt(s)`);
|
|
1863
1863
|
return;
|
|
1864
1864
|
}
|
|
1865
1865
|
if (attempt < maxRetries - 1) {
|
|
1866
|
-
logger$
|
|
1866
|
+
logger$3(`Properties not yet visible for model "${modelName}" (modelId: ${modelId}), retrying in ${retryDelay}ms (attempt ${attempt + 1}/${maxRetries})`);
|
|
1867
1867
|
await new Promise(resolve => setTimeout(resolve, retryDelay));
|
|
1868
1868
|
}
|
|
1869
1869
|
}
|
|
@@ -2169,7 +2169,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2169
2169
|
if (parsed.$schema && parsed.metadata) {
|
|
2170
2170
|
// It's already a complete schema format - preserve it (id may be missing, will be generated)
|
|
2171
2171
|
originalSchemaFile = parsed;
|
|
2172
|
-
logger$
|
|
2172
|
+
logger$3(`Input is complete schema format (${originalSchemaFile.id ? `preserving ID: ${originalSchemaFile.id}` : 'id will be generated'})`);
|
|
2173
2173
|
}
|
|
2174
2174
|
}
|
|
2175
2175
|
catch {
|
|
@@ -2194,7 +2194,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2194
2194
|
// Check DB for existing schema by name+version (same as minimal path)
|
|
2195
2195
|
const db = BaseDb.getAppDb();
|
|
2196
2196
|
if (db) {
|
|
2197
|
-
const _mod_1 = await import('./BasePathResolver-
|
|
2197
|
+
const _mod_1 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2198
2198
|
const _ns_1 = _mod_1.Q;
|
|
2199
2199
|
const schemaSchemaMod = _ns_1;
|
|
2200
2200
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
@@ -2208,16 +2208,16 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2208
2208
|
.limit(1);
|
|
2209
2209
|
if (existingByName.length > 0 && existingByName[0].schemaData) {
|
|
2210
2210
|
const existing = existingByName[0];
|
|
2211
|
-
logger$
|
|
2211
|
+
logger$3(`Idempotency: found existing schema by name+version: ${schemaFile.metadata.name} v${schemaFile.version ?? version}`);
|
|
2212
2212
|
const existingSchema = JSON.parse(existing.schemaData);
|
|
2213
2213
|
const contentMatches = compareSchemaContent(schemaFile, existingSchema);
|
|
2214
|
-
logger$
|
|
2214
|
+
logger$3(`Idempotency: compareSchemaContent=${contentMatches} for ${schemaFile.metadata.name}`);
|
|
2215
2215
|
if (contentMatches) {
|
|
2216
2216
|
if (existing.schemaFileId) {
|
|
2217
2217
|
const workingDir = BaseFileManager.getWorkingDir();
|
|
2218
2218
|
const existingFilePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, schemaFile.version ?? version, existing.schemaFileId);
|
|
2219
2219
|
if (await BaseFileManager.pathExists(existingFilePath)) {
|
|
2220
|
-
logger$
|
|
2220
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content, loading existing file`);
|
|
2221
2221
|
return await loadSchemaFromFile(existingFilePath);
|
|
2222
2222
|
}
|
|
2223
2223
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
@@ -2225,7 +2225,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2225
2225
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2226
2226
|
return await loadSchemaFromFile(existingFilePath);
|
|
2227
2227
|
}
|
|
2228
|
-
logger$
|
|
2228
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${schemaFile.version} already exists with same content (no schemaFileId), using DB`);
|
|
2229
2229
|
return '';
|
|
2230
2230
|
}
|
|
2231
2231
|
}
|
|
@@ -2241,7 +2241,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2241
2241
|
// processSchemaFiles runs multiple times (React StrictMode, app restarts).
|
|
2242
2242
|
if (!schemaFile.id) {
|
|
2243
2243
|
schemaFile.id = await getDeterministicSchemaFileId(schemaFile);
|
|
2244
|
-
logger$
|
|
2244
|
+
logger$3(`Generated deterministic schema ID for ${schemaFile.metadata.name}:`, schemaFile.id);
|
|
2245
2245
|
}
|
|
2246
2246
|
// Before generating IDs, check if a file already exists with this schemaFileId
|
|
2247
2247
|
// This handles the case where the schema was already loaded via loadSchemaFromFile
|
|
@@ -2251,7 +2251,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2251
2251
|
const existingFileExists = await BaseFileManager.pathExists(existingFilePath);
|
|
2252
2252
|
if (existingFileExists) {
|
|
2253
2253
|
// File already exists with this schemaFileId - just load it instead of creating a new one
|
|
2254
|
-
logger$
|
|
2254
|
+
logger$3(`Schema file already exists with schemaFileId ${schemaFile.id}, loading it instead of creating new file`);
|
|
2255
2255
|
return await loadSchemaFromFile(existingFilePath);
|
|
2256
2256
|
}
|
|
2257
2257
|
// Generate missing model and property IDs.
|
|
@@ -2262,12 +2262,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2262
2262
|
for (const [modelName, model] of Object.entries(schemaFile.models || {})) {
|
|
2263
2263
|
if (!model.id) {
|
|
2264
2264
|
model.id = getDeterministicId(modelName);
|
|
2265
|
-
logger$
|
|
2265
|
+
logger$3(`Generated deterministic model ID for ${modelName}:`, model.id);
|
|
2266
2266
|
}
|
|
2267
2267
|
for (const [propName, prop] of Object.entries(model.properties || {})) {
|
|
2268
2268
|
if (!prop.id) {
|
|
2269
2269
|
prop.id = getDeterministicId(modelName + propName);
|
|
2270
|
-
logger$
|
|
2270
|
+
logger$3(`Generated deterministic property ID for ${modelName}.${propName}:`, prop.id);
|
|
2271
2271
|
}
|
|
2272
2272
|
}
|
|
2273
2273
|
}
|
|
@@ -2279,7 +2279,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2279
2279
|
// For minimal imports: check DB for existing schema before creating new file
|
|
2280
2280
|
const db = BaseDb.getAppDb();
|
|
2281
2281
|
if (db) {
|
|
2282
|
-
const _mod_2 = await import('./BasePathResolver-
|
|
2282
|
+
const _mod_2 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2283
2283
|
const _ns_2 = _mod_2.Q;
|
|
2284
2284
|
const schemaSchemaMod = _ns_2;
|
|
2285
2285
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
@@ -2303,14 +2303,14 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2303
2303
|
const workingDir = BaseFileManager.getWorkingDir();
|
|
2304
2304
|
const existingFilePath = getSchemaFilePath(workingDir, importData.name, version, existing.schemaFileId);
|
|
2305
2305
|
if (await BaseFileManager.pathExists(existingFilePath)) {
|
|
2306
|
-
logger$
|
|
2306
|
+
logger$3(`Schema ${importData.name} v${version} already exists with same content, loading existing file`);
|
|
2307
2307
|
return await loadSchemaFromFile(existingFilePath);
|
|
2308
2308
|
}
|
|
2309
2309
|
// File missing but schemaData exists - restore file from schemaData
|
|
2310
2310
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
2311
2311
|
await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
|
|
2312
2312
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2313
|
-
logger$
|
|
2313
|
+
logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
|
|
2314
2314
|
return await loadSchemaFromFile(existingFilePath);
|
|
2315
2315
|
}
|
|
2316
2316
|
// No schemaFileId - restore file from schemaData using id from parsed schema
|
|
@@ -2321,10 +2321,10 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2321
2321
|
await BaseFileManager.createDirIfNotExists(workingDir);
|
|
2322
2322
|
await BaseFileManager.saveFile(existingFilePath, existing.schemaData);
|
|
2323
2323
|
await BaseFileManager.waitForFileWithContent(existingFilePath, 100, 5000);
|
|
2324
|
-
logger$
|
|
2324
|
+
logger$3(`Restored schema file from schemaData for ${importData.name} v${version}`);
|
|
2325
2325
|
return await loadSchemaFromFile(existingFilePath);
|
|
2326
2326
|
}
|
|
2327
|
-
logger$
|
|
2327
|
+
logger$3(`Schema ${importData.name} v${version} already exists with same content (no id), using DB`);
|
|
2328
2328
|
return '';
|
|
2329
2329
|
}
|
|
2330
2330
|
// Content differs - create new version
|
|
@@ -2335,7 +2335,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2335
2335
|
.orderBy(desc(schemasTable.version))
|
|
2336
2336
|
.limit(1);
|
|
2337
2337
|
const newVersion = latestVersionRows.length > 0 ? latestVersionRows[0].version + 1 : version;
|
|
2338
|
-
logger$
|
|
2338
|
+
logger$3(`Schema ${importData.name} content changed, creating new version v${newVersion}`);
|
|
2339
2339
|
schemaFile = transformImportToSchemaFile(importData, newVersion);
|
|
2340
2340
|
version = newVersion;
|
|
2341
2341
|
}
|
|
@@ -2359,7 +2359,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2359
2359
|
// Check if this is an internal SDK schema (should not create files in app directory)
|
|
2360
2360
|
const isInternal = isInternalSchema(schemaFile.metadata.name, schemaFile.id);
|
|
2361
2361
|
if (isInternal) {
|
|
2362
|
-
logger$
|
|
2362
|
+
logger$3(`Skipping file creation for internal schema: ${schemaFile.metadata.name}`);
|
|
2363
2363
|
// For internal schemas, just load to database and store, don't create file
|
|
2364
2364
|
// Extract schema name and version
|
|
2365
2365
|
const schemaName = schemaFile.metadata?.name;
|
|
@@ -2416,7 +2416,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2416
2416
|
// Use fixed internal schema ID if missing (never generate for internal)
|
|
2417
2417
|
if (!schemaFile.id) {
|
|
2418
2418
|
schemaFile.id = INTERNAL_SCHEMA_IDS[0];
|
|
2419
|
-
logger$
|
|
2419
|
+
logger$3('Using fixed internal schema ID:', schemaFile.id);
|
|
2420
2420
|
}
|
|
2421
2421
|
// Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
|
|
2422
2422
|
// This ensures Model instances are created with correct IDs
|
|
@@ -2426,7 +2426,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2426
2426
|
// Generate model ID if missing
|
|
2427
2427
|
if (!model.id) {
|
|
2428
2428
|
model.id = generateId();
|
|
2429
|
-
logger$
|
|
2429
|
+
logger$3(`Generated model ID for ${modelName}:`, model.id);
|
|
2430
2430
|
// Update the schemaFile object so it's included in schemaData
|
|
2431
2431
|
schemaFile.models[modelName].id = model.id;
|
|
2432
2432
|
}
|
|
@@ -2436,7 +2436,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2436
2436
|
// Generate property ID if missing
|
|
2437
2437
|
if (!prop.id) {
|
|
2438
2438
|
prop.id = generateId();
|
|
2439
|
-
logger$
|
|
2439
|
+
logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
|
|
2440
2440
|
// Update the schemaFile object so it's included in schemaData
|
|
2441
2441
|
schemaFile.models[modelName].properties[propName].id = prop.id;
|
|
2442
2442
|
}
|
|
@@ -2448,7 +2448,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2448
2448
|
}
|
|
2449
2449
|
// Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
|
|
2450
2450
|
const modelDefinitions = await createModelsFromJson(importDataForInternal, modelFileIds, propertyFileIds);
|
|
2451
|
-
logger$
|
|
2451
|
+
logger$3('loadSchemaFromFile (internal) - modelDefinitions length:', Object.keys(modelDefinitions).length);
|
|
2452
2452
|
// Convert schema file metadata to schema input for database
|
|
2453
2453
|
const schemaInput = {
|
|
2454
2454
|
name: schemaName,
|
|
@@ -2458,7 +2458,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2458
2458
|
updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
|
|
2459
2459
|
};
|
|
2460
2460
|
// Use dynamic import to break circular dependency
|
|
2461
|
-
const _mod_3 = await import('./db-
|
|
2461
|
+
const _mod_3 = await import('./db-D9K_f5cF.js');
|
|
2462
2462
|
const _ns_3 = _mod_3.Z;
|
|
2463
2463
|
const dbMod = _ns_3;
|
|
2464
2464
|
const { addSchemaToDb, addModelsToDb } = dbMod;
|
|
@@ -2480,11 +2480,11 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2480
2480
|
});
|
|
2481
2481
|
// Verify expected models are linked (single attempt - addModelsToDb already confirmed)
|
|
2482
2482
|
const expectedModelNames = Object.keys(schemaFile.models || {});
|
|
2483
|
-
const _mod_4 = await import('./BasePathResolver-
|
|
2483
|
+
const _mod_4 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2484
2484
|
const _ns_4 = _mod_4.R;
|
|
2485
2485
|
const modelSchemaSchemaMod = _ns_4;
|
|
2486
2486
|
const { modelSchemas } = modelSchemaSchemaMod;
|
|
2487
|
-
const _mod_5 = await import('./BasePathResolver-
|
|
2487
|
+
const _mod_5 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2488
2488
|
const _ns_5 = _mod_5.N;
|
|
2489
2489
|
const modelSchemaMod = _ns_5;
|
|
2490
2490
|
const { models: modelsTable } = modelSchemaMod;
|
|
@@ -2574,12 +2574,12 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2574
2574
|
}
|
|
2575
2575
|
catch (dbError) {
|
|
2576
2576
|
// Database not available - log warning but continue
|
|
2577
|
-
logger$
|
|
2577
|
+
logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
|
|
2578
2578
|
}
|
|
2579
2579
|
// Models are now Model instances, no registration needed
|
|
2580
2580
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
2581
2581
|
for (const [modelName] of Object.entries(modelDefinitions)) {
|
|
2582
|
-
logger$
|
|
2582
|
+
logger$3('loadSchemaFromFile (internal) - model available:', modelName);
|
|
2583
2583
|
}
|
|
2584
2584
|
// Schema is now saved to database
|
|
2585
2585
|
// useSchemas hook will pick it up via database queries
|
|
@@ -2590,7 +2590,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2590
2590
|
// Ensure schema ID is defined (should always be set by this point, but check for safety)
|
|
2591
2591
|
if (!schemaFile.id) {
|
|
2592
2592
|
schemaFile.id = generateId();
|
|
2593
|
-
logger$
|
|
2593
|
+
logger$3('Generated schema ID before file path creation:', schemaFile.id);
|
|
2594
2594
|
}
|
|
2595
2595
|
// Get the target file path using ID-based naming (preferred)
|
|
2596
2596
|
const filePath = getSchemaFilePath(workingDir, schemaFile.metadata.name, version, schemaFile.id);
|
|
@@ -2609,7 +2609,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2609
2609
|
const data = JSON.parse(content);
|
|
2610
2610
|
if (data.$schema) {
|
|
2611
2611
|
// File is already a complete schema, just load it
|
|
2612
|
-
logger$
|
|
2612
|
+
logger$3(`Schema file ${filePath} already exists and is complete, loading it`);
|
|
2613
2613
|
return await loadSchemaFromFile(filePath);
|
|
2614
2614
|
}
|
|
2615
2615
|
}
|
|
@@ -2627,7 +2627,7 @@ async function importJsonSchema(importFilePathOrContents, version = 1) {
|
|
|
2627
2627
|
// Compare schemas structurally
|
|
2628
2628
|
if (compareSchemasStructurally(schemaFile, existingSchema)) {
|
|
2629
2629
|
// Schemas match - just load the existing file
|
|
2630
|
-
logger$
|
|
2630
|
+
logger$3(`Schema ${schemaFile.metadata.name} v${version} already exists with matching content, loading it`);
|
|
2631
2631
|
return await loadSchemaFromFile(filePath);
|
|
2632
2632
|
}
|
|
2633
2633
|
else {
|
|
@@ -2683,7 +2683,7 @@ async function applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, prope
|
|
|
2683
2683
|
createdAt: new Date(schemaFile.metadata.createdAt).getTime(),
|
|
2684
2684
|
updatedAt: new Date(schemaFile.metadata.updatedAt).getTime(),
|
|
2685
2685
|
};
|
|
2686
|
-
const _mod_6 = await import('./db-
|
|
2686
|
+
const _mod_6 = await import('./db-D9K_f5cF.js');
|
|
2687
2687
|
const _ns_6 = _mod_6.Z;
|
|
2688
2688
|
const dbMod = _ns_6;
|
|
2689
2689
|
const { addSchemaToDb, addModelsToDb } = dbMod;
|
|
@@ -2804,7 +2804,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2804
2804
|
// Generate schema ID if missing (before creating schemaInput)
|
|
2805
2805
|
if (!schemaFile.id) {
|
|
2806
2806
|
schemaFile.id = generateId();
|
|
2807
|
-
logger$
|
|
2807
|
+
logger$3('Generated schema ID for schema file:', schemaFile.id);
|
|
2808
2808
|
}
|
|
2809
2809
|
// Extract schemaFileIds from JSON file and generate missing ones BEFORE creating models
|
|
2810
2810
|
// This ensures Model instances are created with correct IDs
|
|
@@ -2814,7 +2814,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2814
2814
|
// Generate model ID if missing
|
|
2815
2815
|
if (!model.id) {
|
|
2816
2816
|
model.id = generateId();
|
|
2817
|
-
logger$
|
|
2817
|
+
logger$3(`Generated model ID for ${modelName}:`, model.id);
|
|
2818
2818
|
// Update the schemaFile object so it's included in schemaData
|
|
2819
2819
|
schemaFile.models[modelName].id = model.id;
|
|
2820
2820
|
}
|
|
@@ -2824,7 +2824,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2824
2824
|
// Generate property ID if missing
|
|
2825
2825
|
if (!prop.id) {
|
|
2826
2826
|
prop.id = generateId();
|
|
2827
|
-
logger$
|
|
2827
|
+
logger$3(`Generated property ID for ${modelName}.${propName}:`, prop.id);
|
|
2828
2828
|
// Update the schemaFile object so it's included in schemaData
|
|
2829
2829
|
schemaFile.models[modelName].properties[propName].id = prop.id;
|
|
2830
2830
|
}
|
|
@@ -2836,18 +2836,18 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2836
2836
|
}
|
|
2837
2837
|
// Convert JSON models to Model classes, passing modelFileIds and propertyFileIds so Model instances use correct IDs
|
|
2838
2838
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
2839
|
-
logger$
|
|
2839
|
+
logger$3('loadSchemaFromFile - modelDefinitions length:', Object.keys(modelDefinitions).length);
|
|
2840
2840
|
// Try to add schema and models to database if database is available
|
|
2841
2841
|
try {
|
|
2842
2842
|
const db = BaseDb.getAppDb();
|
|
2843
2843
|
if (db) {
|
|
2844
2844
|
const { schemaRecord } = await applySchemaToDb(schemaFile, modelDefinitions, modelFileIds, propertyFileIds);
|
|
2845
2845
|
// Query the database to get model IDs that were just created
|
|
2846
|
-
const _mod_7 = await import('./BasePathResolver-
|
|
2846
|
+
const _mod_7 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2847
2847
|
const _ns_7 = _mod_7.R;
|
|
2848
2848
|
const modelSchemaSchemaMod = _ns_7;
|
|
2849
2849
|
const { modelSchemas } = modelSchemaSchemaMod;
|
|
2850
|
-
const _mod_8 = await import('./BasePathResolver-
|
|
2850
|
+
const _mod_8 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2851
2851
|
const _ns_8 = _mod_8.N;
|
|
2852
2852
|
const modelSchemaMod = _ns_8;
|
|
2853
2853
|
const { models: modelsTable } = modelSchemaMod;
|
|
@@ -2895,17 +2895,17 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2895
2895
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
2896
2896
|
}
|
|
2897
2897
|
}
|
|
2898
|
-
logger$
|
|
2898
|
+
logger$3(`Verifying properties: found ${modelLinks.length} model links for schema ${schemaName} (id: ${schemaRecord.id})`);
|
|
2899
2899
|
// If we didn't verify via direct lookup, verify via join table
|
|
2900
2900
|
if (!seedModelId || (seedModel.length === 0 || !seedModel[0].id)) {
|
|
2901
2901
|
const seedModelLink = modelLinks.find((link) => link.modelName === 'Seed');
|
|
2902
2902
|
if (seedModelLink && seedModelLink.modelId) {
|
|
2903
|
-
logger$
|
|
2903
|
+
logger$3(`Verifying properties for Seed model via join table (modelId: ${seedModelLink.modelId})`);
|
|
2904
2904
|
await verifyPropertiesPersisted(db, seedModelLink.modelId, 'Seed', 10, 100);
|
|
2905
2905
|
}
|
|
2906
2906
|
else if (modelLinks.length > 0 && modelLinks[0].modelId) {
|
|
2907
2907
|
// Fallback to first model if Seed not found
|
|
2908
|
-
logger$
|
|
2908
|
+
logger$3(`Verifying properties for ${modelLinks[0].modelName} model via join table (modelId: ${modelLinks[0].modelId})`);
|
|
2909
2909
|
await verifyPropertiesPersisted(db, modelLinks[0].modelId, modelLinks[0].modelName || 'unknown', 10, 100);
|
|
2910
2910
|
}
|
|
2911
2911
|
}
|
|
@@ -2913,7 +2913,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2913
2913
|
// After properties are created (file path), ensure schemaFile has the correct IDs from database
|
|
2914
2914
|
// Query the database to get the actual schemaFileId values that were used
|
|
2915
2915
|
// This ensures schemaData matches what's actually in the database
|
|
2916
|
-
const _mod_9 = await import('./BasePathResolver-
|
|
2916
|
+
const _mod_9 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2917
2917
|
const _ns_9 = _mod_9.N;
|
|
2918
2918
|
const modelSchemaMod2 = _ns_9;
|
|
2919
2919
|
const { properties: propertiesTable } = modelSchemaMod2;
|
|
@@ -2938,7 +2938,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2938
2938
|
const currentId = schemaFile.models[modelName].properties[propRecord.name].id;
|
|
2939
2939
|
if (currentId !== propRecord.schemaFileId) {
|
|
2940
2940
|
schemaFile.models[modelName].properties[propRecord.name].id = propRecord.schemaFileId;
|
|
2941
|
-
logger$
|
|
2941
|
+
logger$3(`Updated schemaFile property ID for ${modelName}.${propRecord.name} from ${currentId} to ${propRecord.schemaFileId}`);
|
|
2942
2942
|
schemaFileUpdated = true;
|
|
2943
2943
|
}
|
|
2944
2944
|
}
|
|
@@ -2949,7 +2949,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2949
2949
|
// This is important even if nothing changed, to ensure consistency
|
|
2950
2950
|
const updatedSchemaData = JSON.stringify(schemaFile, null, 2);
|
|
2951
2951
|
// Update the schema record in the database with current schemaData
|
|
2952
|
-
const _mod_10 = await import('./BasePathResolver-
|
|
2952
|
+
const _mod_10 = await import('./BasePathResolver-CfSfMW5_.js');
|
|
2953
2953
|
const _ns_10 = _mod_10.Q;
|
|
2954
2954
|
const schemaSchemaMod = _ns_10;
|
|
2955
2955
|
const { schemas: schemasTable } = schemaSchemaMod;
|
|
@@ -2958,21 +2958,21 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2958
2958
|
.set({ schemaData: updatedSchemaData })
|
|
2959
2959
|
.where(eq(schemasTable.id, schemaRecord.id));
|
|
2960
2960
|
if (schemaFileUpdated) {
|
|
2961
|
-
logger$
|
|
2961
|
+
logger$3(`Updated schemaData in database with actual property IDs for schema "${schemaName}"`);
|
|
2962
2962
|
}
|
|
2963
2963
|
else {
|
|
2964
|
-
logger$
|
|
2964
|
+
logger$3(`Verified schemaData in database matches schemaFile for schema "${schemaName}"`);
|
|
2965
2965
|
}
|
|
2966
2966
|
}
|
|
2967
2967
|
}
|
|
2968
2968
|
catch (dbError) {
|
|
2969
2969
|
// Database not available - log warning but continue
|
|
2970
|
-
logger$
|
|
2970
|
+
logger$3('Database not available, skipping database operations:', dbError instanceof Error ? dbError.message : String(dbError));
|
|
2971
2971
|
}
|
|
2972
2972
|
// Models are now Model instances, no registration needed
|
|
2973
2973
|
// They should be created via Model.create() and are accessible via Model static methods
|
|
2974
2974
|
for (const [modelName] of Object.entries(modelDefinitions)) {
|
|
2975
|
-
logger$
|
|
2975
|
+
logger$3('loadSchemaFromFile - model available:', modelName);
|
|
2976
2976
|
}
|
|
2977
2977
|
return schemaFilePath;
|
|
2978
2978
|
}
|
|
@@ -2992,7 +2992,7 @@ const loadSchemaFromFile = async (schemaFilePath) => {
|
|
|
2992
2992
|
*/
|
|
2993
2993
|
const createModelFromJson = async (modelName, modelDef, schemaName, modelFileId, // Optional modelFileId from JSON file
|
|
2994
2994
|
propertyFileIds) => {
|
|
2995
|
-
const _mod_11 = await import('./index-
|
|
2995
|
+
const _mod_11 = await import('./index-s15q14rm.js');
|
|
2996
2996
|
const _ns_11 = _mod_11.f;
|
|
2997
2997
|
const modelMod = _ns_11;
|
|
2998
2998
|
const { Model } = modelMod;
|
|
@@ -3059,10 +3059,10 @@ propertyFileIds) => {
|
|
|
3059
3059
|
// Pass id (schemaFileId) if provided to ensure Model instance uses correct ID
|
|
3060
3060
|
// Note: indexes and description are ignored - they remain in JSON for schema file format compliance but are not used by Model instances
|
|
3061
3061
|
if (modelFileId) {
|
|
3062
|
-
logger$
|
|
3062
|
+
logger$3(`Creating schema model "${modelName}" with modelFileId: ${modelFileId}`);
|
|
3063
3063
|
}
|
|
3064
3064
|
else {
|
|
3065
|
-
logger$
|
|
3065
|
+
logger$3(`Warning: Creating schema model "${modelName}" without modelFileId - it will be renamed if duplicates exist`);
|
|
3066
3066
|
}
|
|
3067
3067
|
const modelInstance = Model.create(modelName, schemaName, {
|
|
3068
3068
|
modelFileId: modelFileId, // Pass modelFileId (preferred) as id (schemaFileId) from JSON file
|
|
@@ -3088,7 +3088,7 @@ const createModelsFromJson = async (importData, modelFileIds, propertyFileIds) =
|
|
|
3088
3088
|
// Use modelFileId from map (no fallback to modelDef.id as JsonImportSchema doesn't have id property)
|
|
3089
3089
|
const finalModelFileId = modelFileId;
|
|
3090
3090
|
if (!finalModelFileId) {
|
|
3091
|
-
logger$
|
|
3091
|
+
logger$3(`Warning: No modelFileId found for model "${modelName}" - model will be created without ID`);
|
|
3092
3092
|
}
|
|
3093
3093
|
// Get propertyFileIds for this model if available
|
|
3094
3094
|
const modelPropertyFileIds = propertyFileIds?.get(modelName);
|
|
@@ -3278,7 +3278,7 @@ var SEEDPROTOCOL_Seed_Protocol_v1 = /*#__PURE__*/Object.freeze({
|
|
|
3278
3278
|
version: version
|
|
3279
3279
|
});
|
|
3280
3280
|
|
|
3281
|
-
const logger$
|
|
3281
|
+
const logger$2 = debug('seedSdk:client:actors:processSchemaFiles');
|
|
3282
3282
|
let processSchemaFilesChain = Promise.resolve();
|
|
3283
3283
|
function resolveSchemaFilePath(schemaFile) {
|
|
3284
3284
|
const path = BaseFileManager.getPathModule();
|
|
@@ -3306,7 +3306,7 @@ async function resolveSchemaNameFromSource(source) {
|
|
|
3306
3306
|
}
|
|
3307
3307
|
}
|
|
3308
3308
|
catch (error) {
|
|
3309
|
-
logger$
|
|
3309
|
+
logger$2('Could not resolve schema name from path:', source, error);
|
|
3310
3310
|
}
|
|
3311
3311
|
}
|
|
3312
3312
|
return null;
|
|
@@ -3315,7 +3315,7 @@ async function resolveSchemaNameFromSource(source) {
|
|
|
3315
3315
|
// Schema processing can be slow with syncSchemaFromSource, loadAllSchemasFromDb, and OPFS file I/O
|
|
3316
3316
|
const PROCESS_SCHEMA_FILES_TIMEOUT_MS = 120000;
|
|
3317
3317
|
const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
3318
|
-
logger$
|
|
3318
|
+
logger$2('processSchemaFiles started');
|
|
3319
3319
|
let hasResponded = false;
|
|
3320
3320
|
let timeoutId = null;
|
|
3321
3321
|
const reportError = (error) => {
|
|
@@ -3325,7 +3325,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3325
3325
|
clearTimeout(timeoutId);
|
|
3326
3326
|
timeoutId = null;
|
|
3327
3327
|
}
|
|
3328
|
-
logger$
|
|
3328
|
+
logger$2('processSchemaFiles error:', error);
|
|
3329
3329
|
sendBack({
|
|
3330
3330
|
type: 'error',
|
|
3331
3331
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -3339,7 +3339,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3339
3339
|
clearTimeout(timeoutId);
|
|
3340
3340
|
timeoutId = null;
|
|
3341
3341
|
}
|
|
3342
|
-
logger$
|
|
3342
|
+
logger$2('processSchemaFiles completed');
|
|
3343
3343
|
sendBack({ type: ClientManagerEvents.PROCESS_SCHEMA_FILES_SUCCESS });
|
|
3344
3344
|
}
|
|
3345
3345
|
};
|
|
@@ -3351,7 +3351,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3351
3351
|
// Schemas written (or confirmed present) this run — skip redundant loadSchemaFromFile later
|
|
3352
3352
|
const schemasWrittenThisRun = new Set();
|
|
3353
3353
|
// First, load the internal seed-protocol schema
|
|
3354
|
-
logger$
|
|
3354
|
+
logger$2('Loading internal seed-protocol schema');
|
|
3355
3355
|
const internalSchemaData = internalSchema;
|
|
3356
3356
|
const db = BaseDb.getAppDb();
|
|
3357
3357
|
const internalSchemaExists = db
|
|
@@ -3360,21 +3360,21 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3360
3360
|
// Always mark internal schema as written so the DB/file loop does not re-apply it
|
|
3361
3361
|
schemasWrittenThisRun.add(SEED_PROTOCOL_SCHEMA_NAME);
|
|
3362
3362
|
if (internalSchemaExists) {
|
|
3363
|
-
logger$
|
|
3363
|
+
logger$2('Internal seed-protocol schema already in DB, skipping import');
|
|
3364
3364
|
}
|
|
3365
3365
|
else {
|
|
3366
3366
|
try {
|
|
3367
3367
|
// Import the internal schema to database (will create models and add to store)
|
|
3368
3368
|
await importJsonSchema({ contents: JSON.stringify(internalSchemaData) }, internalSchemaData.version);
|
|
3369
|
-
logger$
|
|
3369
|
+
logger$2(`Loaded internal seed-protocol schema v${internalSchemaData.version}`);
|
|
3370
3370
|
}
|
|
3371
3371
|
catch (error) {
|
|
3372
3372
|
// If schema already exists, that's fine - it means it was already loaded
|
|
3373
3373
|
if (error?.message?.includes('already exists')) {
|
|
3374
|
-
logger$
|
|
3374
|
+
logger$2('Internal seed-protocol schema already loaded');
|
|
3375
3375
|
}
|
|
3376
3376
|
else {
|
|
3377
|
-
logger$
|
|
3377
|
+
logger$2('Error loading internal seed-protocol schema:', error);
|
|
3378
3378
|
// Don't fail if internal schema can't be loaded - it might already be in DB
|
|
3379
3379
|
}
|
|
3380
3380
|
}
|
|
@@ -3387,7 +3387,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3387
3387
|
: '';
|
|
3388
3388
|
const schemaId = typeof context.schema === 'object' && context.schema?.id ? String(context.schema.id) : undefined;
|
|
3389
3389
|
if (isInternalSchema(schemaName, schemaId)) {
|
|
3390
|
-
logger$
|
|
3390
|
+
logger$2('Schema is internal (Seed Protocol), already loaded - skipping syncSchemaFromSource');
|
|
3391
3391
|
}
|
|
3392
3392
|
else {
|
|
3393
3393
|
try {
|
|
@@ -3396,10 +3396,10 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3396
3396
|
if (syncedName) {
|
|
3397
3397
|
schemasWrittenThisRun.add(syncedName);
|
|
3398
3398
|
}
|
|
3399
|
-
logger$
|
|
3399
|
+
logger$2(`Synced canonical schema from ${typeof context.schema === 'string' ? context.schema : 'object'}`);
|
|
3400
3400
|
}
|
|
3401
3401
|
catch (error) {
|
|
3402
|
-
logger$
|
|
3402
|
+
logger$2(`Error syncing canonical schema:`, error);
|
|
3403
3403
|
// Don't fail init - schema might already be in DB
|
|
3404
3404
|
}
|
|
3405
3405
|
}
|
|
@@ -3414,23 +3414,23 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3414
3414
|
if (parsed?.metadata?.name) {
|
|
3415
3415
|
schemasWrittenThisRun.add(String(parsed.metadata.name));
|
|
3416
3416
|
}
|
|
3417
|
-
logger$
|
|
3417
|
+
logger$2(`Loaded schema from ${resolvedPath}`);
|
|
3418
3418
|
}
|
|
3419
3419
|
catch (error) {
|
|
3420
|
-
logger$
|
|
3420
|
+
logger$2(`Error loading schema file ${context.schemaFile}:`, error);
|
|
3421
3421
|
// Don't fail init - schema might already be in DB
|
|
3422
3422
|
}
|
|
3423
3423
|
}
|
|
3424
3424
|
// Process minimal import files (files without $schema) - skip when canonical schema is set
|
|
3425
3425
|
if (!context.schema) {
|
|
3426
|
-
logger$
|
|
3426
|
+
logger$2('Listing schema files');
|
|
3427
3427
|
let schemaFiles = [];
|
|
3428
3428
|
try {
|
|
3429
3429
|
schemaFiles = await listSchemaFiles();
|
|
3430
|
-
logger$
|
|
3430
|
+
logger$2(`Found ${schemaFiles.length} schema files to process`);
|
|
3431
3431
|
}
|
|
3432
3432
|
catch (error) {
|
|
3433
|
-
logger$
|
|
3433
|
+
logger$2('Error listing schema files (continuing anyway):', error);
|
|
3434
3434
|
schemaFiles = [];
|
|
3435
3435
|
}
|
|
3436
3436
|
for (const schemaFile of schemaFiles) {
|
|
@@ -3441,19 +3441,19 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3441
3441
|
}
|
|
3442
3442
|
}
|
|
3443
3443
|
catch (error) {
|
|
3444
|
-
logger$
|
|
3444
|
+
logger$2(`Error importing schema file ${schemaFile.filePath}:`, error);
|
|
3445
3445
|
}
|
|
3446
3446
|
}
|
|
3447
3447
|
}
|
|
3448
3448
|
// Then, load all schemas using the unified database-first approach
|
|
3449
|
-
logger$
|
|
3449
|
+
logger$2('Loading schemas from database and files');
|
|
3450
3450
|
let allSchemasData = [];
|
|
3451
3451
|
try {
|
|
3452
3452
|
allSchemasData = await loadAllSchemasFromDb();
|
|
3453
|
-
logger$
|
|
3453
|
+
logger$2(`Loaded ${allSchemasData.length} schemas (${allSchemasData.filter(s => s.isDraft).length} drafts, ${allSchemasData.filter(s => !s.isDraft).length} published)`);
|
|
3454
3454
|
}
|
|
3455
3455
|
catch (error) {
|
|
3456
|
-
logger$
|
|
3456
|
+
logger$2('Error loading schemas from database (continuing anyway):', error);
|
|
3457
3457
|
// Continue with empty array - this is not critical for initialization
|
|
3458
3458
|
// Schemas can be loaded on-demand later
|
|
3459
3459
|
allSchemasData = [];
|
|
@@ -3474,13 +3474,13 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3474
3474
|
}
|
|
3475
3475
|
}
|
|
3476
3476
|
catch (error) {
|
|
3477
|
-
logger$
|
|
3477
|
+
logger$2('Error counting linked models (re-applying all schema files):', error);
|
|
3478
3478
|
}
|
|
3479
3479
|
}
|
|
3480
3480
|
for (const schemaData of allSchemasData) {
|
|
3481
3481
|
const schema = schemaData.schema;
|
|
3482
3482
|
const schemaName = schema.metadata?.name || 'unknown';
|
|
3483
|
-
logger$
|
|
3483
|
+
logger$2(`Processing schema: ${schemaName} v${schema.version} (${schemaData.isDraft ? 'draft' : 'published'}, source: ${schemaData.source})`);
|
|
3484
3484
|
// For published schemas (not drafts), load models from file if available
|
|
3485
3485
|
if (!schemaData.isDraft && schema.id) {
|
|
3486
3486
|
// loadAllSchemasFromDb already picked the latest file for this schema (and read it)
|
|
@@ -3510,7 +3510,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3510
3510
|
}
|
|
3511
3511
|
}
|
|
3512
3512
|
catch (error) {
|
|
3513
|
-
logger$
|
|
3513
|
+
logger$2(`Error loading schema file for ${schemaName}:`, error);
|
|
3514
3514
|
}
|
|
3515
3515
|
}
|
|
3516
3516
|
else {
|
|
@@ -3559,11 +3559,11 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3559
3559
|
};
|
|
3560
3560
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
3561
3561
|
Object.assign(allModels, modelDefinitions);
|
|
3562
|
-
logger$
|
|
3562
|
+
logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from schema data for ${schemaName}`);
|
|
3563
3563
|
}
|
|
3564
3564
|
}
|
|
3565
3565
|
catch (error) {
|
|
3566
|
-
logger$
|
|
3566
|
+
logger$2(`Error creating models from schema data for ${schemaName}:`, error);
|
|
3567
3567
|
}
|
|
3568
3568
|
}
|
|
3569
3569
|
}
|
|
@@ -3613,11 +3613,11 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3613
3613
|
};
|
|
3614
3614
|
const modelDefinitions = await createModelsFromJson(importData, modelFileIds, propertyFileIds);
|
|
3615
3615
|
Object.assign(allModels, modelDefinitions);
|
|
3616
|
-
logger$
|
|
3616
|
+
logger$2(`Loaded ${Object.keys(modelDefinitions).length} models from draft schema ${schemaName}`);
|
|
3617
3617
|
}
|
|
3618
3618
|
}
|
|
3619
3619
|
catch (error) {
|
|
3620
|
-
logger$
|
|
3620
|
+
logger$2(`Error creating models from draft schema ${schemaName}:`, error);
|
|
3621
3621
|
}
|
|
3622
3622
|
}
|
|
3623
3623
|
// Schemas are now loaded on-demand via database queries (useSchemas hook uses loadAllSchemasFromDb)
|
|
@@ -3635,7 +3635,7 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3635
3635
|
// Its schema and model inserts check for rows first, so tabs take turns (docs/MULTI_TAB.md).
|
|
3636
3636
|
.then(() => withSeedDbLock('init', context.filesDir, _processSchemaFiles))
|
|
3637
3637
|
.catch((err) => {
|
|
3638
|
-
logger$
|
|
3638
|
+
logger$2('processSchemaFiles chain error:', err);
|
|
3639
3639
|
throw err;
|
|
3640
3640
|
});
|
|
3641
3641
|
processSchemaFilesChain.then(reportSuccess).catch((error) => {
|
|
@@ -3650,6 +3650,285 @@ const processSchemaFiles = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3650
3650
|
};
|
|
3651
3651
|
});
|
|
3652
3652
|
|
|
3653
|
+
/**
|
|
3654
|
+
* A legacy ItemStorage draft row: a local edit (no attestation uid, not derived from one) that holds
|
|
3655
|
+
* the content itself in property_value, with no file reference. Item.create / createNewItem stored
|
|
3656
|
+
* ItemStorage values like this before they went through the save pipeline.
|
|
3657
|
+
*/
|
|
3658
|
+
const isVerbatimItemStorageDraftRow = (row) => !row.uid &&
|
|
3659
|
+
row.derivedFromUid == null &&
|
|
3660
|
+
!row.refResolvedValue &&
|
|
3661
|
+
typeof row.propertyValue === 'string' &&
|
|
3662
|
+
row.propertyValue !== '';
|
|
3663
|
+
/**
|
|
3664
|
+
* Convert one legacy ItemStorage draft row (see {@link isVerbatimItemStorageDraftRow}) into the
|
|
3665
|
+
* shape saveItemStorage gives a row: the content goes to the file a save would write
|
|
3666
|
+
* (`<seedUid or seedLocalId><extension>` in the property's storage directory), and the row records
|
|
3667
|
+
* `refResolvedValue`, `localStorageDir` and `refValueType: 'file'` with property_value cleared.
|
|
3668
|
+
* Used by publish (resolveItemStorageChildFile) and the one-time migration (migrateLegacyItemStorageRows).
|
|
3669
|
+
*
|
|
3670
|
+
* Reading the row, writing the file and updating the row happen under the file's lock
|
|
3671
|
+
* ({@link withItemStorageFileLock}), which saveItemStorage holds too: a save in this or another tab
|
|
3672
|
+
* either finishes before (the row, read again once the lock is held, is no longer legacy and is
|
|
3673
|
+
* left alone) or starts after (and overwrites the file and row with its content). Without the lock
|
|
3674
|
+
* a save landing between the read and the file write would have its file overwritten with the old
|
|
3675
|
+
* content. The row update also stays conditional on the row being unchanged, for writers that
|
|
3676
|
+
* don't take the lock (a tab still running an older SDK).
|
|
3677
|
+
*
|
|
3678
|
+
* Returns undefined when there was nothing to convert. Throws when the file can't be written; the
|
|
3679
|
+
* row is then unchanged.
|
|
3680
|
+
*/
|
|
3681
|
+
const convertVerbatimItemStorageRow = async (localId, storage = {}) => {
|
|
3682
|
+
const appDb = BaseDb.getAppDb();
|
|
3683
|
+
if (!appDb || !localId)
|
|
3684
|
+
return undefined;
|
|
3685
|
+
const targetOf = (row) => {
|
|
3686
|
+
if (!isVerbatimItemStorageDraftRow(row))
|
|
3687
|
+
return undefined;
|
|
3688
|
+
const seedId = storage.seedId || row.seedUid || row.seedLocalId;
|
|
3689
|
+
if (!seedId)
|
|
3690
|
+
return undefined;
|
|
3691
|
+
return {
|
|
3692
|
+
seedId,
|
|
3693
|
+
localStorageDir: storage.localStorageDir || row.localStorageDir,
|
|
3694
|
+
filenameSuffix: storage.filenameSuffix,
|
|
3695
|
+
};
|
|
3696
|
+
};
|
|
3697
|
+
return withLockedItemStorageRow(localId, (row) => {
|
|
3698
|
+
const target = targetOf(row);
|
|
3699
|
+
return target && getItemStorageFilePath(target);
|
|
3700
|
+
}, async (row) => {
|
|
3701
|
+
const content = row.propertyValue;
|
|
3702
|
+
const { fileName, filePath, localStorageDir } = await writeItemStorageFile(targetOf(row), content);
|
|
3703
|
+
await appDb
|
|
3704
|
+
.update(metadata$1)
|
|
3705
|
+
.set({ refResolvedValue: fileName, localStorageDir, refValueType: 'file', propertyValue: null })
|
|
3706
|
+
.where(and(eq(metadata$1.localId, localId), isNull(metadata$1.refResolvedValue), eq(metadata$1.propertyValue, content)));
|
|
3707
|
+
// Changed between the read and the update by a writer outside the lock: that change stands.
|
|
3708
|
+
const after = await appDb
|
|
3709
|
+
.select({ refResolvedValue: metadata$1.refResolvedValue, propertyValue: metadata$1.propertyValue })
|
|
3710
|
+
.from(metadata$1)
|
|
3711
|
+
.where(eq(metadata$1.localId, localId))
|
|
3712
|
+
.limit(1);
|
|
3713
|
+
if (after[0]?.refResolvedValue !== fileName || after[0]?.propertyValue != null)
|
|
3714
|
+
return undefined;
|
|
3715
|
+
return { fileName, filePath, localStorageDir, content };
|
|
3716
|
+
});
|
|
3717
|
+
};
|
|
3718
|
+
|
|
3719
|
+
const logger$1 = debug('seedSdk:db:migrateLegacyItemStorageRows');
|
|
3720
|
+
/** appState key recording that legacy ItemStorage rows have been written to their files. */
|
|
3721
|
+
const LEGACY_ITEM_STORAGE_MIGRATION_KEY = 'legacyItemStorageFiles:v1';
|
|
3722
|
+
/** Runs in a row that left rows unconverted because a file write failed, before giving up. */
|
|
3723
|
+
const LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS = 3;
|
|
3724
|
+
const readMarker = async () => {
|
|
3725
|
+
const db = BaseDb.getAppDb();
|
|
3726
|
+
const rows = await db
|
|
3727
|
+
.select({ value: appState.value })
|
|
3728
|
+
.from(appState)
|
|
3729
|
+
.where(eq(appState.key, LEGACY_ITEM_STORAGE_MIGRATION_KEY))
|
|
3730
|
+
.limit(1);
|
|
3731
|
+
if (!rows.length)
|
|
3732
|
+
return undefined;
|
|
3733
|
+
try {
|
|
3734
|
+
return JSON.parse(rows[0].value ?? '');
|
|
3735
|
+
}
|
|
3736
|
+
catch {
|
|
3737
|
+
return null;
|
|
3738
|
+
}
|
|
3739
|
+
};
|
|
3740
|
+
const writeMarker = async (marker) => {
|
|
3741
|
+
const db = BaseDb.getAppDb();
|
|
3742
|
+
const now = Date.now();
|
|
3743
|
+
const value = JSON.stringify(marker);
|
|
3744
|
+
await db
|
|
3745
|
+
.insert(appState)
|
|
3746
|
+
.values({ key: LEGACY_ITEM_STORAGE_MIGRATION_KEY, value, createdAt: now, updatedAt: now })
|
|
3747
|
+
.onConflictDoUpdate({ target: appState.key, set: { value, updatedAt: now } });
|
|
3748
|
+
};
|
|
3749
|
+
/**
|
|
3750
|
+
* The storage settings of a metadata row's property: by its property_id, else by name in the
|
|
3751
|
+
* seed's own model (model names are only unique per schema). Undefined when it can't be told.
|
|
3752
|
+
*/
|
|
3753
|
+
const createStorageResolver = () => {
|
|
3754
|
+
const db = BaseDb.getAppDb();
|
|
3755
|
+
const byPropertyId = new Map();
|
|
3756
|
+
const byModelAndName = new Map();
|
|
3757
|
+
return async (row) => {
|
|
3758
|
+
if (row.propertyId != null) {
|
|
3759
|
+
if (!byPropertyId.has(row.propertyId)) {
|
|
3760
|
+
const found = await db
|
|
3761
|
+
.select({
|
|
3762
|
+
storageType: properties.storageType,
|
|
3763
|
+
localStorageDir: properties.localStorageDir,
|
|
3764
|
+
filenameSuffix: properties.filenameSuffix,
|
|
3765
|
+
})
|
|
3766
|
+
.from(properties)
|
|
3767
|
+
.where(eq(properties.id, row.propertyId))
|
|
3768
|
+
.limit(1);
|
|
3769
|
+
byPropertyId.set(row.propertyId, found[0]);
|
|
3770
|
+
}
|
|
3771
|
+
const fromId = byPropertyId.get(row.propertyId);
|
|
3772
|
+
if (fromId)
|
|
3773
|
+
return fromId;
|
|
3774
|
+
}
|
|
3775
|
+
const modelFileId = await resolveItemModelFileId({ seedLocalId: row.seedLocalId, seedUid: row.seedUid });
|
|
3776
|
+
if (!modelFileId || !row.propertyName)
|
|
3777
|
+
return undefined;
|
|
3778
|
+
const key = `${modelFileId}\u0000${row.propertyName}`;
|
|
3779
|
+
if (!byModelAndName.has(key)) {
|
|
3780
|
+
const found = await db
|
|
3781
|
+
.select({
|
|
3782
|
+
storageType: properties.storageType,
|
|
3783
|
+
localStorageDir: properties.localStorageDir,
|
|
3784
|
+
filenameSuffix: properties.filenameSuffix,
|
|
3785
|
+
})
|
|
3786
|
+
.from(properties)
|
|
3787
|
+
.innerJoin(models$1, eq(properties.modelId, models$1.id))
|
|
3788
|
+
.where(and(eq(models$1.schemaFileId, modelFileId), eq(properties.name, row.propertyName)))
|
|
3789
|
+
.limit(1);
|
|
3790
|
+
byModelAndName.set(key, found[0]);
|
|
3791
|
+
}
|
|
3792
|
+
return byModelAndName.get(key);
|
|
3793
|
+
};
|
|
3794
|
+
};
|
|
3795
|
+
/** True if `row` is the row readers show for its property: the newest of its seed's rows by that name. */
|
|
3796
|
+
const isNewestRowOfProperty = async (row) => {
|
|
3797
|
+
if (!row.seedLocalId || !row.propertyName)
|
|
3798
|
+
return false;
|
|
3799
|
+
const db = BaseDb.getAppDb();
|
|
3800
|
+
const siblings = await db
|
|
3801
|
+
.select()
|
|
3802
|
+
.from(metadata$1)
|
|
3803
|
+
.where(and(eq(metadata$1.seedLocalId, row.seedLocalId), eq(metadata$1.propertyName, row.propertyName)));
|
|
3804
|
+
return [...siblings].sort(compareMetadataRowsLatestFirst)[0]?.localId === row.localId;
|
|
3805
|
+
};
|
|
3806
|
+
/**
|
|
3807
|
+
* One-time data migration: writes the content of legacy ItemStorage draft rows to their files.
|
|
3808
|
+
*
|
|
3809
|
+
* Before Item.create / createNewItem saved ItemStorage values through the save pipeline, a value
|
|
3810
|
+
* given at creation was stored verbatim in metadata.property_value with no file. Publish converts
|
|
3811
|
+
* such a row lazily (resolveItemStorageChildFile); this converts them all up front, with the same
|
|
3812
|
+
* code ({@link convertVerbatimItemStorageRow}), so every ItemStorage draft has the shape a save
|
|
3813
|
+
* gives it: the content in `<seedUid or seedLocalId><extension>`, the row holding
|
|
3814
|
+
* refResolvedValue / localStorageDir / refValueType 'file' and no property_value.
|
|
3815
|
+
*
|
|
3816
|
+
* Only local drafts (no uid, not derived from an attestation) of properties whose properties row
|
|
3817
|
+
* says `storage_type = 'ItemStorage'` are touched, and of those only the newest row of each
|
|
3818
|
+
* seed's property: that is the row reads show and saves write to, and older rows sharing the one
|
|
3819
|
+
* file name would overwrite it with older content. Published and synced rows are never changed.
|
|
3820
|
+
*
|
|
3821
|
+
* A row that fails is logged and left as it was (publish still converts it). The run is recorded
|
|
3822
|
+
* in appState under {@link LEGACY_ITEM_STORAGE_MIGRATION_KEY}; a run with failed rows is retried
|
|
3823
|
+
* on the next start, up to {@link LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS} runs. Safe to run
|
|
3824
|
+
* again regardless: a converted row no longer matches.
|
|
3825
|
+
*
|
|
3826
|
+
* @param options.force run even when the marker says it is done
|
|
3827
|
+
*/
|
|
3828
|
+
async function migrateLegacyItemStorageRows(options = {}) {
|
|
3829
|
+
const result = {
|
|
3830
|
+
alreadyDone: false,
|
|
3831
|
+
candidates: 0,
|
|
3832
|
+
converted: 0,
|
|
3833
|
+
failed: 0,
|
|
3834
|
+
skipped: 0,
|
|
3835
|
+
};
|
|
3836
|
+
const db = BaseDb.getAppDb();
|
|
3837
|
+
if (!db)
|
|
3838
|
+
return { ...result, alreadyDone: true };
|
|
3839
|
+
const marker = await readMarker();
|
|
3840
|
+
const previousAttempts = marker?.status === 'retry' ? marker.attempts : 0;
|
|
3841
|
+
if (!options.force && marker && marker.status === 'done') {
|
|
3842
|
+
return { ...result, alreadyDone: true };
|
|
3843
|
+
}
|
|
3844
|
+
const itemStorageNames = (await db
|
|
3845
|
+
.selectDistinct({ name: properties.name })
|
|
3846
|
+
.from(properties)
|
|
3847
|
+
.where(eq(properties.storageType, 'ItemStorage'))).map((r) => r.name);
|
|
3848
|
+
const candidates = itemStorageNames.length
|
|
3849
|
+
? await db
|
|
3850
|
+
.select()
|
|
3851
|
+
.from(metadata$1)
|
|
3852
|
+
.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, '')))
|
|
3853
|
+
: [];
|
|
3854
|
+
const resolveStorage = createStorageResolver();
|
|
3855
|
+
for (const row of candidates) {
|
|
3856
|
+
if (!row.localId || !isVerbatimItemStorageDraftRow(row))
|
|
3857
|
+
continue;
|
|
3858
|
+
try {
|
|
3859
|
+
const storage = await resolveStorage(row);
|
|
3860
|
+
if (storage?.storageType !== 'ItemStorage')
|
|
3861
|
+
continue;
|
|
3862
|
+
result.candidates++;
|
|
3863
|
+
if (!(await isNewestRowOfProperty(row))) {
|
|
3864
|
+
result.skipped++;
|
|
3865
|
+
continue;
|
|
3866
|
+
}
|
|
3867
|
+
const converted = await convertVerbatimItemStorageRow(row.localId, {
|
|
3868
|
+
localStorageDir: storage.localStorageDir,
|
|
3869
|
+
filenameSuffix: storage.filenameSuffix,
|
|
3870
|
+
});
|
|
3871
|
+
if (converted) {
|
|
3872
|
+
result.converted++;
|
|
3873
|
+
logger$1(`wrote ${row.propertyName} of ${row.seedLocalId} to ${converted.filePath}`);
|
|
3874
|
+
}
|
|
3875
|
+
else {
|
|
3876
|
+
result.skipped++;
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
catch (error) {
|
|
3880
|
+
result.failed++;
|
|
3881
|
+
logger$1(`converting ${row.propertyName} of ${row.seedLocalId} (${row.localId}) failed; left as is`, error);
|
|
3882
|
+
}
|
|
3883
|
+
}
|
|
3884
|
+
const attempts = previousAttempts + 1;
|
|
3885
|
+
await writeMarker({
|
|
3886
|
+
status: result.failed > 0 && attempts < LEGACY_ITEM_STORAGE_MIGRATION_MAX_ATTEMPTS ? 'retry' : 'done',
|
|
3887
|
+
attempts,
|
|
3888
|
+
converted: result.converted,
|
|
3889
|
+
failed: result.failed,
|
|
3890
|
+
at: Date.now(),
|
|
3891
|
+
});
|
|
3892
|
+
if (result.candidates > 0) {
|
|
3893
|
+
logger$1(`legacy ItemStorage rows: ${result.converted} converted, ${result.failed} failed, ` +
|
|
3894
|
+
`${result.skipped} skipped of ${result.candidates}`);
|
|
3895
|
+
}
|
|
3896
|
+
return result;
|
|
3897
|
+
}
|
|
3898
|
+
let running;
|
|
3899
|
+
let deferredUntilLeader = false;
|
|
3900
|
+
const runInBackground = () => {
|
|
3901
|
+
running ?? (running = withDbTabLock('item-storage-migration', () => migrateLegacyItemStorageRows())
|
|
3902
|
+
.then(() => undefined)
|
|
3903
|
+
.catch((error) => {
|
|
3904
|
+
// Never fails init: rows stay as they were and publish converts them lazily.
|
|
3905
|
+
logger$1('legacy ItemStorage migration failed', error);
|
|
3906
|
+
})
|
|
3907
|
+
.finally(() => {
|
|
3908
|
+
running = undefined;
|
|
3909
|
+
}));
|
|
3910
|
+
return running;
|
|
3911
|
+
};
|
|
3912
|
+
/**
|
|
3913
|
+
* Starts {@link migrateLegacyItemStorageRows} in the background once client init has finished
|
|
3914
|
+
* (the properties table then holds the current storage settings). It runs in the leader tab only
|
|
3915
|
+
* (docs/MULTI_TAB.md), under a `seed:item-storage-migration:<db>` lock in case several tabs lead
|
|
3916
|
+
* (`multiTab: 'off'`); a tab that isn't leader runs it if it takes over. Never throws.
|
|
3917
|
+
*/
|
|
3918
|
+
function startLegacyItemStorageMigration() {
|
|
3919
|
+
if (isLeaderTab()) {
|
|
3920
|
+
void runInBackground();
|
|
3921
|
+
return;
|
|
3922
|
+
}
|
|
3923
|
+
if (deferredUntilLeader)
|
|
3924
|
+
return;
|
|
3925
|
+
deferredUntilLeader = true;
|
|
3926
|
+
void whenLeaderTab().then(() => {
|
|
3927
|
+
deferredUntilLeader = false;
|
|
3928
|
+
void runInBackground();
|
|
3929
|
+
});
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3653
3932
|
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
3933
|
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
3934
|
const logSyncAfterAddressSave = debug("seedSdk:client:clientManagerMachine:syncAfterAddressSave");
|
|
@@ -3870,9 +4149,15 @@ const clientManagerMachine = setup({
|
|
|
3870
4149
|
},
|
|
3871
4150
|
},
|
|
3872
4151
|
[IDLE]: {
|
|
3873
|
-
entry:
|
|
3874
|
-
|
|
3875
|
-
|
|
4152
|
+
entry: [
|
|
4153
|
+
assign({
|
|
4154
|
+
isInitialized: true,
|
|
4155
|
+
}),
|
|
4156
|
+
// One-time data migration that writes files, so it can't be a SQL migration in prepareDb.
|
|
4157
|
+
// In the background after init: the app is usable at once, the properties table holds the
|
|
4158
|
+
// current storage settings by now, and a failure never fails init.
|
|
4159
|
+
() => startLegacyItemStorageMigration(),
|
|
4160
|
+
],
|
|
3876
4161
|
on: {
|
|
3877
4162
|
[SAVE_APP_STATE_SUCCESS]: {
|
|
3878
4163
|
actions: [
|
|
@@ -4764,5 +5049,5 @@ var ClientManager$1 = /*#__PURE__*/Object.freeze({
|
|
|
4764
5049
|
getClient: getClient
|
|
4765
5050
|
});
|
|
4766
5051
|
|
|
4767
|
-
export {
|
|
4768
|
-
//# sourceMappingURL=ClientManager-
|
|
5052
|
+
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, schema as I, ClientManager$1 as J, 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 };
|
|
5053
|
+
//# sourceMappingURL=ClientManager-C-QXqUK9.js.map
|