@seedprotocol/sdk 0.7.3-next.613.g79a8dfd → 0.7.3
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,21 @@
|
|
|
1
1
|
import { waitFor, fromCallback, setup, assign, stateIn, createActor, isMachineSnapshot } from 'xstate';
|
|
2
|
-
import {
|
|
2
|
+
import { n as normalizeDataType, E as BaseDb, C as versions, m as metadata, A as seeds, z as schemas, s as models, q as modelSchemas, aQ as getOwnedAddressesFromDb, a9 as ZERO_BYTES32, aB as normalizeAddressList, a0 as normalizeHexAddress, ay as getAddressesForItemsFilter, H as toSnakeCase$1, ad as INTERNAL_PROPERTY_NAMES, J as BaseFileManager, aS as getStorageTransactionIdForSeedUid, aT as convertTxIdToImage, i as isDataType, X as normalizePublisher, ax as ensureImageLocal, ap as ImageSize, aU as downloadTransactionIdWithDedupe, u as properties, M as ModelPropertyDataTypes, $ as generateId, ag as INTERNAL_DATA_TYPES, r as modelUids, L as resolveItemModelFileId, aV as getPropertyIdForSchemaFileId, K as getPropertyIdForModelAndName, aW as getDataTypeFromString, aX as getMimeType, am as INTERNAL_STORAGE_MODEL_FILE_IDS, V as getItemStorageSubdir, W as getItemStorageLocalFileName, g as normalizePropertyRecordSchema, aY as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, a5 as getCorrectId, G as eventEmitter, ae as isStorageSeedRef } from './BasePathResolver-Cm4apKRb.js';
|
|
3
3
|
import { or, isNull, eq, max, count, and, getTableColumns, sql, desc, inArray, isNotNull, gt } from 'drizzle-orm';
|
|
4
4
|
import pluralize from 'pluralize';
|
|
5
|
-
import { n as normalizeDataType, W as getOwnedAddressesFromDb, E as normalizeAddressList, u as normalizeHexAddress, z as getAddressesForItemsFilter, k as isDataType, s as normalizePublisher, M as ModelPropertyDataTypes, r as resolveItemModelFileId, X as getPropertyIdForSchemaFileId, o as getPropertyIdForModelAndName, l as normalizePropertyRecordSchema, m as eventEmitter } from './db-CQt-gcAl.js';
|
|
6
5
|
import debug from 'debug';
|
|
7
6
|
import { BehaviorSubject } from 'rxjs';
|
|
8
7
|
import { startCase, upperFirst, camelCase, orderBy } from 'lodash-es';
|
|
9
8
|
import { toSnakeCase } from 'drizzle-orm/casing';
|
|
10
9
|
import { isValidEasAttestationUid, isPlaceholderUid, BaseQueryClient, BaseEasClient, GET_SCHEMAS, getEasSchemaUidForSchemaDefinition, getSchemaUidForModelFromCache, cachedSchemaLookup, setSchemaUidForModel, getEasSchemaUidForExactDefinition } from '@seedprotocol/eas';
|
|
11
|
-
import { t as toSnakeCase$1, H as getStorageTransactionIdForSeedUid, I as convertTxIdToImage, h as ensureImageLocal, J as downloadTransactionIdWithDedupe, b as generateId, K as getDataTypeFromString, M as getMimeType, N as notifyFileSaved, g as getCorrectId, a as isStorageSeedRef } from './tabEvents-BZJMY5uK.js';
|
|
12
10
|
import { fetchArweaveRawTextAcrossGateways } from '@seedprotocol/arweave';
|
|
11
|
+
import { d as notifyFileSaved, f as withTabLock } from './tabEvents-9s2WCYw-.js';
|
|
13
12
|
import { modelPropertiesToObject } from './model-DGMe-TTm.js';
|
|
14
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Default readyTimeout for create/find/all with waitForReady. Loads that touch OPFS and the DB can take
|
|
16
|
+
* several seconds on slow devices and CI runners; a load that is really stuck still errors.
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_READY_TIMEOUT_MS = 15000;
|
|
15
19
|
/**
|
|
16
20
|
* Wait for an entity's state machine to reach 'idle' state
|
|
17
21
|
* @param entity - Entity instance with getService() method
|
|
@@ -19,7 +23,7 @@ import { modelPropertiesToObject } from './model-DGMe-TTm.js';
|
|
|
19
23
|
* @returns Promise that resolves when entity reaches idle, or rejects on error/timeout
|
|
20
24
|
*/
|
|
21
25
|
async function waitForEntityIdle(entity, options = {}) {
|
|
22
|
-
const { timeout =
|
|
26
|
+
const { timeout = DEFAULT_READY_TIMEOUT_MS, throwOnError = true } = options;
|
|
23
27
|
const service = entity.getService();
|
|
24
28
|
const currentSnapshot = service.getSnapshot();
|
|
25
29
|
const isSnapshotIdle = (snapshot) => {
|
|
@@ -93,10 +97,20 @@ async function getPublisherForNewSeedsWithTimeout() {
|
|
|
93
97
|
return undefined;
|
|
94
98
|
}
|
|
95
99
|
}
|
|
100
|
+
let publishExecutor = null;
|
|
101
|
+
function setPublishExecutor(executor) {
|
|
102
|
+
publishExecutor = executor;
|
|
103
|
+
}
|
|
104
|
+
function getPublishExecutor() {
|
|
105
|
+
return publishExecutor;
|
|
106
|
+
}
|
|
107
|
+
const PUBLISH_NOT_CONFIGURED_MESSAGE = 'Publishing is not configured. item.publish() needs @seedprotocol/publish: call initPublish() from it, or mount <PublishProvider config={...}>, before publishing.';
|
|
96
108
|
let uploadExecutor = null;
|
|
109
|
+
/** @deprecated See UploadExecutor. */
|
|
97
110
|
function setUploadExecutor(executor) {
|
|
98
111
|
uploadExecutor = executor;
|
|
99
112
|
}
|
|
113
|
+
/** @deprecated See UploadExecutor. */
|
|
100
114
|
function getUploadExecutor() {
|
|
101
115
|
return uploadExecutor;
|
|
102
116
|
}
|
|
@@ -117,13 +131,16 @@ function getGetAdditionalSyncAddresses() {
|
|
|
117
131
|
|
|
118
132
|
var publishConfig = /*#__PURE__*/Object.freeze({
|
|
119
133
|
__proto__: null,
|
|
134
|
+
PUBLISH_NOT_CONFIGURED_MESSAGE: PUBLISH_NOT_CONFIGURED_MESSAGE,
|
|
120
135
|
getGetAdditionalSyncAddresses: getGetAdditionalSyncAddresses,
|
|
121
136
|
getGetPublisherForNewSeeds: getGetPublisherForNewSeeds,
|
|
137
|
+
getPublishExecutor: getPublishExecutor,
|
|
122
138
|
getPublisherForNewSeedsWithTimeout: getPublisherForNewSeedsWithTimeout,
|
|
123
139
|
getRevokeExecutor: getRevokeExecutor,
|
|
124
140
|
getUploadExecutor: getUploadExecutor,
|
|
125
141
|
setAdditionalSyncAddresses: setAdditionalSyncAddresses,
|
|
126
142
|
setGetPublisherForNewSeeds: setGetPublisherForNewSeeds,
|
|
143
|
+
setPublishExecutor: setPublishExecutor,
|
|
127
144
|
setRevokeExecutor: setRevokeExecutor,
|
|
128
145
|
setUploadExecutor: setUploadExecutor
|
|
129
146
|
});
|
|
@@ -708,7 +725,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
708
725
|
const itemPropertyMod = await Promise.resolve().then(function () { return ItemProperty$1; });
|
|
709
726
|
const { ItemProperty } = itemPropertyMod;
|
|
710
727
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
711
|
-
const _mod_0 = await import('./index-
|
|
728
|
+
const _mod_0 = await import('./index-8O3Uow-Y.js');
|
|
712
729
|
const _ns_0 = _mod_0.f;
|
|
713
730
|
const { Model } = _ns_0;
|
|
714
731
|
// Resolve Model and build property schemas (use getByNameAsync for models not yet in cache)
|
|
@@ -726,7 +743,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
726
743
|
const schemaNameToTry = schemaName ?? model?.schemaName;
|
|
727
744
|
if (schemaNameToTry) {
|
|
728
745
|
try {
|
|
729
|
-
const _mod_1 = await import('./Schema-
|
|
746
|
+
const _mod_1 = await import('./Schema-CpMNEnUO.js');
|
|
730
747
|
const _ns_1 = _mod_1.b;
|
|
731
748
|
const { Schema } = _ns_1;
|
|
732
749
|
const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false });
|
|
@@ -742,8 +759,8 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
742
759
|
}
|
|
743
760
|
if (Object.keys(propertySchemas).length === 0) {
|
|
744
761
|
try {
|
|
745
|
-
const _mod_2 = await import('./ClientManager-
|
|
746
|
-
const _ns_2 = _mod_2.
|
|
762
|
+
const _mod_2 = await import('./ClientManager-i3nJASkg.js');
|
|
763
|
+
const _ns_2 = _mod_2.K;
|
|
747
764
|
const { loadAllSchemasFromDb } = _ns_2;
|
|
748
765
|
const allSchemas = await loadAllSchemasFromDb();
|
|
749
766
|
for (const { schema: schemaFile } of allSchemas) {
|
|
@@ -763,11 +780,11 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
763
780
|
}
|
|
764
781
|
if (Object.keys(propertySchemas).length === 0) {
|
|
765
782
|
try {
|
|
766
|
-
const _mod_3 = await import('./ClientManager-
|
|
767
|
-
const _ns_3 = _mod_3.
|
|
783
|
+
const _mod_3 = await import('./ClientManager-i3nJASkg.js');
|
|
784
|
+
const _ns_3 = _mod_3.K;
|
|
768
785
|
const { listCompleteSchemaFiles } = _ns_3;
|
|
769
|
-
const _mod_4 = await import('./BasePathResolver-
|
|
770
|
-
const _ns_4 = _mod_4.
|
|
786
|
+
const _mod_4 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
787
|
+
const _ns_4 = _mod_4.a_;
|
|
771
788
|
const { BaseFileManager } = _ns_4;
|
|
772
789
|
const schemaFiles = await listCompleteSchemaFiles();
|
|
773
790
|
for (const { filePath } of schemaFiles) {
|
|
@@ -787,7 +804,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
787
804
|
}
|
|
788
805
|
}
|
|
789
806
|
if (Object.keys(propertySchemas).length === 0) {
|
|
790
|
-
const schemaMod = await import('./index-
|
|
807
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
791
808
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
792
809
|
const KNOWN_MODEL_FALLBACKS = {
|
|
793
810
|
Post: {
|
|
@@ -804,7 +821,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
804
821
|
}
|
|
805
822
|
}
|
|
806
823
|
// Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
|
|
807
|
-
const { normalizePropertyRecordSchema } = await import('./property-
|
|
824
|
+
const { normalizePropertyRecordSchema } = await import('./property-DwPD283A.js');
|
|
808
825
|
propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
|
|
809
826
|
// Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
|
|
810
827
|
// ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
|
|
@@ -837,7 +854,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
837
854
|
// Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
|
|
838
855
|
let propSchema = propertySchemas[propertyName];
|
|
839
856
|
if (!propSchema && isRefTypeFromMeta) {
|
|
840
|
-
const schemaMod = await import('./index-
|
|
857
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
841
858
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
842
859
|
propSchema = {
|
|
843
860
|
dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
|
|
@@ -1089,48 +1106,36 @@ const loadOrCreateItem = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
1089
1106
|
});
|
|
1090
1107
|
|
|
1091
1108
|
const logger$7 = debug('seedSdk:Item:runPublish');
|
|
1092
|
-
|
|
1109
|
+
/**
|
|
1110
|
+
* Runs the publish for item.publish() by handing the item to the PublishExecutor that
|
|
1111
|
+
* @seedprotocol/publish registers, which uploads to Arweave and writes to EAS.
|
|
1112
|
+
*/
|
|
1113
|
+
const runPublish = fromCallback(({ sendBack, input: { context, item: itemFromEvent, options } }) => {
|
|
1093
1114
|
const { seedLocalId } = context;
|
|
1094
1115
|
const _runPublish = async () => {
|
|
1095
1116
|
if (!seedLocalId) {
|
|
1096
1117
|
sendBack({ type: 'publishError', error: new Error('Item has no seedLocalId') });
|
|
1097
1118
|
return;
|
|
1098
1119
|
}
|
|
1120
|
+
const executor = getPublishExecutor();
|
|
1121
|
+
if (!executor) {
|
|
1122
|
+
sendBack({ type: 'publishError', error: new Error(PUBLISH_NOT_CONFIGURED_MESSAGE) });
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1099
1125
|
try {
|
|
1100
|
-
|
|
1101
|
-
const
|
|
1102
|
-
|
|
1126
|
+
// item.publish() sends its own instance; look it up only if startPublish came without one.
|
|
1127
|
+
const item = itemFromEvent ??
|
|
1128
|
+
(await (await Promise.resolve().then(function () { return Item$1; })).Item.find({ seedLocalId }));
|
|
1103
1129
|
if (!item) {
|
|
1104
|
-
sendBack({ type: 'publishError', error: new Error(`Item not found
|
|
1130
|
+
sendBack({ type: 'publishError', error: new Error(`Item not found: ${seedLocalId}`) });
|
|
1105
1131
|
return;
|
|
1106
1132
|
}
|
|
1107
|
-
|
|
1108
|
-
const { getPublishUploads } = getPublishUploadsMod;
|
|
1109
|
-
const _mod_5 = await import('./getPublishPayload-Xl3sRkR-.js');
|
|
1110
|
-
const _ns_5 = _mod_5.g;
|
|
1111
|
-
const getPublishPayloadMod = _ns_5;
|
|
1112
|
-
const { getPublishPayload } = getPublishPayloadMod;
|
|
1113
|
-
const uploads = await getPublishUploads(item);
|
|
1114
|
-
let uploadedTransactions = [];
|
|
1115
|
-
const executor = getUploadExecutor();
|
|
1116
|
-
if (executor && uploads.length > 0) {
|
|
1117
|
-
for (const upload of uploads) {
|
|
1118
|
-
const { txId } = await executor(upload);
|
|
1119
|
-
uploadedTransactions.push({
|
|
1120
|
-
txId,
|
|
1121
|
-
seedLocalId: upload.seedLocalId,
|
|
1122
|
-
versionLocalId: upload.versionLocalId,
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
await getPublishPayload(item, uploadedTransactions);
|
|
1127
|
-
logger$7('runPublish: payload prepared (upload/EAS submit stubbed)');
|
|
1133
|
+
await executor(item, options);
|
|
1128
1134
|
sendBack({ type: 'publishSuccess' });
|
|
1129
1135
|
}
|
|
1130
|
-
catch (
|
|
1131
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
1136
|
+
catch (error) {
|
|
1132
1137
|
logger$7('runPublish error:', error);
|
|
1133
|
-
sendBack({ type: 'publishError', error });
|
|
1138
|
+
sendBack({ type: 'publishError', error: error instanceof Error ? error : new Error(String(error)) });
|
|
1134
1139
|
}
|
|
1135
1140
|
};
|
|
1136
1141
|
_runPublish();
|
|
@@ -1258,7 +1263,11 @@ const itemMachineSingle = setup({
|
|
|
1258
1263
|
},
|
|
1259
1264
|
invoke: {
|
|
1260
1265
|
src: 'runPublish',
|
|
1261
|
-
input: ({ context }) => ({
|
|
1266
|
+
input: ({ context, event }) => ({
|
|
1267
|
+
context,
|
|
1268
|
+
item: event.item,
|
|
1269
|
+
options: event.options,
|
|
1270
|
+
}),
|
|
1262
1271
|
},
|
|
1263
1272
|
},
|
|
1264
1273
|
waitingForDb: {
|
|
@@ -1656,6 +1665,17 @@ async function batchLatestPublishedVersionBySeedLocalIds(seedLocalIds) {
|
|
|
1656
1665
|
}
|
|
1657
1666
|
|
|
1658
1667
|
const READ_ONLY_ERROR = 'Item is read-only: you do not own this item';
|
|
1668
|
+
/**
|
|
1669
|
+
* Thrown by write operations (save, destroy, publish, unpublish) on an item none
|
|
1670
|
+
* of the client's addresses own. See isItemOwned for what counts as owned.
|
|
1671
|
+
*/
|
|
1672
|
+
class OwnershipError extends Error {
|
|
1673
|
+
constructor(message = READ_ONLY_ERROR) {
|
|
1674
|
+
super(message);
|
|
1675
|
+
this.name = 'OwnershipError';
|
|
1676
|
+
Object.setPrototypeOf(this, OwnershipError.prototype);
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1659
1679
|
async function getSeedRowForItem(item) {
|
|
1660
1680
|
const appDb = BaseDb.getAppDb();
|
|
1661
1681
|
if (!appDb)
|
|
@@ -1731,8 +1751,9 @@ function isSeedRowOwned(row, ownedAddresses) {
|
|
|
1731
1751
|
return publisherIsInOwnedSet(publisher, ownedAddresses);
|
|
1732
1752
|
}
|
|
1733
1753
|
/**
|
|
1734
|
-
* SQL for
|
|
1735
|
-
* Compares `lower(publisher)` so checksummed rows match persisted lowercase
|
|
1754
|
+
* SQL for an address list on `publisher`. Empty list → no rows (`1=0`).
|
|
1755
|
+
* Compares `lower(publisher)` so checksummed rows match persisted lowercase addresses.
|
|
1756
|
+
* Used for `addressFilter: 'watched'`; `'owned'` uses {@link ownedSeedsSql}.
|
|
1736
1757
|
*/
|
|
1737
1758
|
function publisherInAddressListSql(column, addresses) {
|
|
1738
1759
|
const normalized = normalizeAddressList(addresses);
|
|
@@ -1741,10 +1762,37 @@ function publisherInAddressListSql(column, addresses) {
|
|
|
1741
1762
|
}
|
|
1742
1763
|
return inArray(sql `lower(${column})`, normalized);
|
|
1743
1764
|
}
|
|
1744
|
-
/**
|
|
1765
|
+
/**
|
|
1766
|
+
* @deprecated Matches `seeds.publisher` only. Use {@link ownedSeedsSql}, which agrees
|
|
1767
|
+
* with {@link isSeedRowOwned} (empty owned → local unsealed drafts; attester fallback).
|
|
1768
|
+
*/
|
|
1745
1769
|
function ownedPublisherSql(ownedAddresses) {
|
|
1746
1770
|
return publisherInAddressListSql(seeds.publisher, ownedAddresses);
|
|
1747
1771
|
}
|
|
1772
|
+
/** SQL form of {@link isPlaceholderUid}: null, `''`, `'NULL'`, or zero bytes32 (trimmed, any case). */
|
|
1773
|
+
function placeholderUidSql(column) {
|
|
1774
|
+
return or(isNull(column), eq(column, 'NULL'), sql `trim(${column}) = ''`, sql `lower(trim(${column})) = ${ZERO_BYTES32.toLowerCase()}`);
|
|
1775
|
+
}
|
|
1776
|
+
const isBlankSql = (column) => or(isNull(column), eq(column, ''));
|
|
1777
|
+
/** SQL form of {@link isLocalUnsealedDraft} on `seeds`. */
|
|
1778
|
+
function localUnsealedDraftSql() {
|
|
1779
|
+
return and(isBlankSql(seeds.publisher), placeholderUidSql(seeds.uid), isBlankSql(seeds.attestationRaw));
|
|
1780
|
+
}
|
|
1781
|
+
/**
|
|
1782
|
+
* SQL for `addressFilter: 'owned'`: a row passes exactly when {@link isSeedRowOwned} is true.
|
|
1783
|
+
* - Empty owned → local unsealed drafts (pre-connect authoring), not every row.
|
|
1784
|
+
* - Owned set → `lower(trim(publisher))` in the set, or, when publisher is blank, the
|
|
1785
|
+
* `attestationRaw.attester` ({@link resolvePublisherFromSeedRow}). `json_valid` guards
|
|
1786
|
+
* `json_extract`, which throws on malformed JSON.
|
|
1787
|
+
*/
|
|
1788
|
+
function ownedSeedsSql(ownedAddresses) {
|
|
1789
|
+
const normalized = normalizeAddressList(ownedAddresses);
|
|
1790
|
+
if (normalized.length === 0) {
|
|
1791
|
+
return localUnsealedDraftSql();
|
|
1792
|
+
}
|
|
1793
|
+
const attester = sql `CASE WHEN json_valid(${seeds.attestationRaw}) THEN lower(trim(json_extract(${seeds.attestationRaw}, '$.attester'))) END`;
|
|
1794
|
+
return or(inArray(sql `lower(trim(${seeds.publisher}))`, normalized), and(isBlankSql(seeds.publisher), inArray(attester, normalized)));
|
|
1795
|
+
}
|
|
1748
1796
|
/**
|
|
1749
1797
|
* Checks if the current user owns the item (publisher is in persisted owned addresses).
|
|
1750
1798
|
*
|
|
@@ -1766,22 +1814,27 @@ async function isItemOwned(item) {
|
|
|
1766
1814
|
return isSeedRowOwned(row, ownedAddresses);
|
|
1767
1815
|
}
|
|
1768
1816
|
/**
|
|
1769
|
-
* Throws if the item is not owned. Use before write operations
|
|
1817
|
+
* Throws OwnershipError if the item is not owned. Use before write operations
|
|
1818
|
+
* (publish, save, destroy).
|
|
1770
1819
|
*/
|
|
1771
1820
|
async function assertItemOwned(item) {
|
|
1772
1821
|
const owned = await isItemOwned(item);
|
|
1773
1822
|
if (!owned) {
|
|
1774
|
-
throw new
|
|
1823
|
+
throw new OwnershipError();
|
|
1775
1824
|
}
|
|
1776
1825
|
}
|
|
1777
1826
|
|
|
1778
1827
|
var ownership = /*#__PURE__*/Object.freeze({
|
|
1779
1828
|
__proto__: null,
|
|
1829
|
+
OwnershipError: OwnershipError,
|
|
1780
1830
|
assertItemOwned: assertItemOwned,
|
|
1781
1831
|
isItemOwned: isItemOwned,
|
|
1782
1832
|
isLocalUnsealedDraft: isLocalUnsealedDraft,
|
|
1783
1833
|
isSeedRowOwned: isSeedRowOwned,
|
|
1834
|
+
localUnsealedDraftSql: localUnsealedDraftSql,
|
|
1784
1835
|
ownedPublisherSql: ownedPublisherSql,
|
|
1836
|
+
ownedSeedsSql: ownedSeedsSql,
|
|
1837
|
+
placeholderUidSql: placeholderUidSql,
|
|
1785
1838
|
publisherInAddressListSql: publisherInAddressListSql,
|
|
1786
1839
|
publisherIsInOwnedSet: publisherIsInOwnedSet,
|
|
1787
1840
|
resolvePublisherFromSeedRow: resolvePublisherFromSeedRow
|
|
@@ -1801,15 +1854,15 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
|
|
|
1801
1854
|
const appDb = BaseDb.getAppDb();
|
|
1802
1855
|
const conditions = [];
|
|
1803
1856
|
if (!includeEas) {
|
|
1804
|
-
conditions.push(
|
|
1857
|
+
conditions.push(placeholderUidSql(seeds.uid));
|
|
1805
1858
|
}
|
|
1806
1859
|
if (modelName) {
|
|
1807
1860
|
conditions.push(eq(seeds.type, toSnakeCase(modelName)));
|
|
1808
1861
|
}
|
|
1809
1862
|
if (!modelFileId && schemaName && modelName) {
|
|
1810
|
-
const
|
|
1811
|
-
const
|
|
1812
|
-
const { resolveModelRecord } =
|
|
1863
|
+
const _mod_5 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
1864
|
+
const _ns_5 = _mod_5.b1;
|
|
1865
|
+
const { resolveModelRecord } = _ns_5;
|
|
1813
1866
|
modelFileId = (await resolveModelRecord(modelName, { schemaName }))?.schemaFileId ?? undefined;
|
|
1814
1867
|
if (!modelFileId)
|
|
1815
1868
|
return []; // that schema has no such model
|
|
@@ -1819,7 +1872,7 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
|
|
|
1819
1872
|
}
|
|
1820
1873
|
if (addressFilter === 'owned') {
|
|
1821
1874
|
const ownedAddresses = await getAddressesForItemsFilter('owned');
|
|
1822
|
-
conditions.push(
|
|
1875
|
+
conditions.push(ownedSeedsSql(ownedAddresses));
|
|
1823
1876
|
}
|
|
1824
1877
|
else if (addressFilter === 'watched') {
|
|
1825
1878
|
const watchedAddresses = await getAddressesForItemsFilter('watched');
|
|
@@ -2090,7 +2143,7 @@ const resolveRelatedValue = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2090
2143
|
const { isRelation, propertyValue, propertyName, seedUid, propertyRecordSchema, populatedFromDb, schemaUid, } = context;
|
|
2091
2144
|
const _resolveRelatedValue = async () => {
|
|
2092
2145
|
// Use dynamic import to break circular dependency
|
|
2093
|
-
const schemaMod = await import('./index-
|
|
2146
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
2094
2147
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
2095
2148
|
if (!propertyValue || !isRelation || populatedFromDb) {
|
|
2096
2149
|
return;
|
|
@@ -2525,9 +2578,9 @@ async function readHtmlBodyFromChildStorageArweave(seedLocalId) {
|
|
|
2525
2578
|
/* offline / bad tx id */
|
|
2526
2579
|
}
|
|
2527
2580
|
try {
|
|
2528
|
-
const
|
|
2529
|
-
const
|
|
2530
|
-
const { downloadTransactionIdWithDedupe } =
|
|
2581
|
+
const _mod_6 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2582
|
+
const _ns_6 = _mod_6.b3;
|
|
2583
|
+
const { downloadTransactionIdWithDedupe } = _ns_6;
|
|
2531
2584
|
await downloadTransactionIdWithDedupe(txId);
|
|
2532
2585
|
const retryFp = BaseFileManager.getFilesPath('html', `${seedLocalId}.html`);
|
|
2533
2586
|
if (await BaseFileManager.pathExists(retryFp)) {
|
|
@@ -2586,7 +2639,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2586
2639
|
// to use dynamically imported ModelPropertyDataTypes
|
|
2587
2640
|
const _hydrateFromDb = async () => {
|
|
2588
2641
|
// Use dynamic import to break circular dependency
|
|
2589
|
-
const schemaMod = await import('./index-
|
|
2642
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
2590
2643
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
2591
2644
|
const appDb = BaseDb.getAppDb();
|
|
2592
2645
|
const whereClauses = [];
|
|
@@ -2865,13 +2918,13 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
2865
2918
|
const modelNameForNew = context.modelName;
|
|
2866
2919
|
if (modelNameForNew) {
|
|
2867
2920
|
try {
|
|
2868
|
-
const
|
|
2869
|
-
const
|
|
2870
|
-
const { Model } =
|
|
2921
|
+
const _mod_7 = await import('./index-8O3Uow-Y.js');
|
|
2922
|
+
const _ns_7 = _mod_7.f;
|
|
2923
|
+
const { Model } = _ns_7;
|
|
2871
2924
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
2872
|
-
const
|
|
2873
|
-
const
|
|
2874
|
-
const { resolveItemModelFileId } =
|
|
2925
|
+
const _mod_8 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2926
|
+
const _ns_8 = _mod_8.b1;
|
|
2927
|
+
const { resolveItemModelFileId } = _ns_8;
|
|
2875
2928
|
const normalizedModelName = upperFirst(camelCase(modelNameForNew));
|
|
2876
2929
|
const itemModelFileId = await resolveItemModelFileId({
|
|
2877
2930
|
modelFileId: context.modelFileId,
|
|
@@ -2923,9 +2976,9 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
2923
2976
|
// It ends up in the context below, and later lookups by name (Model.getByName) can't match it.
|
|
2924
2977
|
const modelName = context.modelName || (metadataRecord.modelType ? upperFirst(camelCase(metadataRecord.modelType)) : undefined);
|
|
2925
2978
|
// Model names are only unique per schema: pin lookups to the item's own model row.
|
|
2926
|
-
const
|
|
2927
|
-
const
|
|
2928
|
-
const { resolveItemModelFileId, resolveModelRecord } =
|
|
2979
|
+
const _mod_9 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
2980
|
+
const _ns_9 = _mod_9.b1;
|
|
2981
|
+
const { resolveItemModelFileId, resolveModelRecord } = _ns_9;
|
|
2929
2982
|
const modelFileId = await resolveItemModelFileId({
|
|
2930
2983
|
modelFileId: context.modelFileId,
|
|
2931
2984
|
seedLocalId: seedLocalId ?? metadataRecord.seedLocalId,
|
|
@@ -2969,18 +3022,18 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
2969
3022
|
};
|
|
2970
3023
|
// Merge with schema from file/DB to get validation rules (enum, pattern, etc.) - properties table doesn't store these
|
|
2971
3024
|
try {
|
|
2972
|
-
const { getPropertySchema } = await import('./property-
|
|
3025
|
+
const { getPropertySchema } = await import('./property-DwPD283A.js');
|
|
2973
3026
|
let schemaFromFile = await getPropertySchema(normalizedModelName, propertyName, {
|
|
2974
3027
|
modelFileId: modelRecord?.schemaFileId ?? modelFileId,
|
|
2975
3028
|
});
|
|
2976
3029
|
if (!schemaFromFile?.validation) {
|
|
2977
3030
|
// Fallback: get validation from schemaData in database (Schema context may not be loaded yet)
|
|
2978
|
-
const
|
|
2979
|
-
const
|
|
2980
|
-
const { schemas: schemasTable } =
|
|
2981
|
-
const
|
|
2982
|
-
const
|
|
2983
|
-
const { modelSchemas } =
|
|
3031
|
+
const _mod_10 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
3032
|
+
const _ns_10 = _mod_10.a$;
|
|
3033
|
+
const { schemas: schemasTable } = _ns_10;
|
|
3034
|
+
const _mod_11 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
3035
|
+
const _ns_11 = _mod_11.b0;
|
|
3036
|
+
const { modelSchemas } = _ns_11;
|
|
2984
3037
|
const modelSchemaRows = await db
|
|
2985
3038
|
.select({ schemaId: modelSchemas.schemaId })
|
|
2986
3039
|
.from(modelSchemas)
|
|
@@ -3019,9 +3072,9 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
|
|
|
3019
3072
|
}
|
|
3020
3073
|
if (!propertyRecordSchema && modelName) {
|
|
3021
3074
|
try {
|
|
3022
|
-
const
|
|
3023
|
-
const
|
|
3024
|
-
const { Model } =
|
|
3075
|
+
const _mod_12 = await import('./index-8O3Uow-Y.js');
|
|
3076
|
+
const _ns_12 = _mod_12.f;
|
|
3077
|
+
const { Model } = _ns_12;
|
|
3025
3078
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
3026
3079
|
const normalizedModelName = upperFirst(camelCase(modelName));
|
|
3027
3080
|
// Try PascalCase first ("post" -> "Post"); then findByModelType for names with spaces ("new_model" -> "New model")
|
|
@@ -3395,10 +3448,16 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3395
3448
|
throw new Error('Missing propertyRecordSchema');
|
|
3396
3449
|
}
|
|
3397
3450
|
const _analyzeInput = async () => {
|
|
3451
|
+
// Assignment writes straight to the DB, so check ownership here as save()/destroy()/publish() do.
|
|
3452
|
+
const { isItemOwned, OwnershipError } = await Promise.resolve().then(function () { return ownership; });
|
|
3453
|
+
if (!(await isItemOwned({ seedLocalId: seedLocalId ?? undefined, seedUid: context.seedUid ?? undefined }))) {
|
|
3454
|
+
sendBack({ type: 'saveFailed', error: new OwnershipError() });
|
|
3455
|
+
return false;
|
|
3456
|
+
}
|
|
3398
3457
|
// Use dynamic import to break circular dependency
|
|
3399
|
-
const schemaMod = await import('./index-
|
|
3458
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
3400
3459
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
3401
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
3460
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-DieV4KL-.js');
|
|
3402
3461
|
let propertyName = propertyNameRaw;
|
|
3403
3462
|
if (!propertyName) {
|
|
3404
3463
|
throw new Error('propertyName is required');
|
|
@@ -3552,6 +3611,8 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
3552
3611
|
if (isDone) {
|
|
3553
3612
|
sendBack({ type: 'saveValueToDbSuccess' });
|
|
3554
3613
|
}
|
|
3614
|
+
}, (error) => {
|
|
3615
|
+
sendBack({ type: 'saveFailed', error });
|
|
3555
3616
|
});
|
|
3556
3617
|
});
|
|
3557
3618
|
|
|
@@ -3688,7 +3749,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
3688
3749
|
propertyRecordSchema?.validation &&
|
|
3689
3750
|
metadataValues.propertyValue != null &&
|
|
3690
3751
|
metadataValues.propertyValue !== '') {
|
|
3691
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
3752
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-DieV4KL-.js');
|
|
3692
3753
|
const validationService = new SchemaValidationService();
|
|
3693
3754
|
const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
|
|
3694
3755
|
? normalizeDataType(String(propertyRecordSchema.refValueType))
|
|
@@ -4270,7 +4331,7 @@ const saveRelation = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
|
4270
4331
|
}
|
|
4271
4332
|
const _saveRelation = async () => {
|
|
4272
4333
|
// Use dynamic import to break circular dependency
|
|
4273
|
-
const schemaMod = await import('./index-
|
|
4334
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
4274
4335
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
4275
4336
|
if (!propertyNameRaw) {
|
|
4276
4337
|
throw new Error('propertyName is required');
|
|
@@ -4361,6 +4422,86 @@ const getItemPropertyData = async (props) => {
|
|
|
4361
4422
|
return queryRows[0];
|
|
4362
4423
|
};
|
|
4363
4424
|
|
|
4425
|
+
/** Absolute path of the file {@link writeItemStorageFile} writes for `target`. */
|
|
4426
|
+
const getItemStorageFilePath = (target) => BaseFileManager.getFilesPath(getItemStorageSubdir(target.localStorageDir), target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix));
|
|
4427
|
+
/**
|
|
4428
|
+
* Write an ItemStorage property's content to its local file, where saveItemStorage, reads, publish
|
|
4429
|
+
* (resolveItemStorageChildFile) and download all look for it. Returns what the metadata row records:
|
|
4430
|
+
* `refResolvedValue` (the file name) and `localStorageDir` (with a leading slash).
|
|
4431
|
+
*
|
|
4432
|
+
* Callers that also update the file's metadata row hold {@link withItemStorageFileLock} around
|
|
4433
|
+
* both, so another writer of the same file can't land in between.
|
|
4434
|
+
*/
|
|
4435
|
+
const writeItemStorageFile = async (target, content) => {
|
|
4436
|
+
const dir = getItemStorageSubdir(target.localStorageDir);
|
|
4437
|
+
const fileName = target.fileName || getItemStorageLocalFileName(target.seedId, target.filenameSuffix);
|
|
4438
|
+
await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
|
|
4439
|
+
const filePath = BaseFileManager.getFilesPath(dir, fileName);
|
|
4440
|
+
await BaseFileManager.saveFile(filePath, content);
|
|
4441
|
+
return { fileName, filePath, localStorageDir: target.localStorageDir || `/${dir}` };
|
|
4442
|
+
};
|
|
4443
|
+
/**
|
|
4444
|
+
* Lock name for one ItemStorage file: `seed:item-storage:<absolute file path>`. The path starts
|
|
4445
|
+
* with the files root, which also names the database (`<filesDir>/db/seed.db`), so the name is
|
|
4446
|
+
* per database as well as per file.
|
|
4447
|
+
*/
|
|
4448
|
+
const itemStorageFileLockName = (filePath) => `seed:item-storage:${filePath}`;
|
|
4449
|
+
/**
|
|
4450
|
+
* Runs `fn` holding the lock of one ItemStorage file, across tabs (Web Locks) and within this JS
|
|
4451
|
+
* realm (an in-process queue where Web Locks are missing, e.g. Node < 24.5; see `withTabLock`).
|
|
4452
|
+
*
|
|
4453
|
+
* Writers of a local draft's file (saveItemStorage, convertVerbatimItemStorageRow, createNewItem)
|
|
4454
|
+
* hold it across "read the row → write the file → update the row", so the file and the row end
|
|
4455
|
+
* with the same writer's content. See docs/MULTI_TAB.md.
|
|
4456
|
+
*
|
|
4457
|
+
* Lock ordering: this lock is always the innermost. It may be taken while holding a broader lock
|
|
4458
|
+
* (`seed:item-storage-migration:<db>`, `seed:publish:<seedLocalId>`), never the other way round,
|
|
4459
|
+
* and no other lock (nor a second file lock) is requested while it is held. Keep the section to
|
|
4460
|
+
* local DB and file I/O: no network. Not re-entrant.
|
|
4461
|
+
*/
|
|
4462
|
+
function withItemStorageFileLock(filePath, fn) {
|
|
4463
|
+
return withTabLock(itemStorageFileLockName(filePath), fn);
|
|
4464
|
+
}
|
|
4465
|
+
/** Lock attempts before giving up when the row's target file keeps changing under us. */
|
|
4466
|
+
const ROW_LOCK_ATTEMPTS = 3;
|
|
4467
|
+
const readRow = async (localId) => {
|
|
4468
|
+
const rows = await BaseDb.getAppDb()
|
|
4469
|
+
.select()
|
|
4470
|
+
.from(metadata)
|
|
4471
|
+
.where(eq(metadata.localId, localId))
|
|
4472
|
+
.limit(1);
|
|
4473
|
+
return rows[0];
|
|
4474
|
+
};
|
|
4475
|
+
/**
|
|
4476
|
+
* Runs `fn` with a fresh read of metadata row `localId`, holding the lock of the file that row's
|
|
4477
|
+
* content goes to. `fileOf` names that file (absolute path) for a row, or returns undefined when
|
|
4478
|
+
* there is nothing to write (then `fn` isn't called and the result is undefined).
|
|
4479
|
+
*
|
|
4480
|
+
* The file depends on the row, so the row is read once to pick the lock and again once it is held;
|
|
4481
|
+
* if the row now points at another file (another writer changed it meanwhile), the lock is
|
|
4482
|
+
* released and taken again for that file.
|
|
4483
|
+
*/
|
|
4484
|
+
async function withLockedItemStorageRow(localId, fileOf, fn) {
|
|
4485
|
+
for (let attempt = 0; attempt < ROW_LOCK_ATTEMPTS; attempt++) {
|
|
4486
|
+
const row = await readRow(localId);
|
|
4487
|
+
const filePath = row && fileOf(row);
|
|
4488
|
+
if (!filePath)
|
|
4489
|
+
return undefined;
|
|
4490
|
+
const outcome = await withItemStorageFileLock(filePath, async () => {
|
|
4491
|
+
const fresh = await readRow(localId);
|
|
4492
|
+
const freshPath = fresh && fileOf(fresh);
|
|
4493
|
+
if (!freshPath)
|
|
4494
|
+
return { done: true, value: undefined };
|
|
4495
|
+
if (freshPath !== filePath)
|
|
4496
|
+
return { done: false };
|
|
4497
|
+
return { done: true, value: await fn(fresh, filePath) };
|
|
4498
|
+
});
|
|
4499
|
+
if (outcome.done)
|
|
4500
|
+
return outcome.value;
|
|
4501
|
+
}
|
|
4502
|
+
throw new Error(`ItemStorage file of metadata row ${localId} kept changing; not written`);
|
|
4503
|
+
}
|
|
4504
|
+
|
|
4364
4505
|
/** A local edit: no attestation uid of its own and not derived from one. */
|
|
4365
4506
|
const isLocalDraft = (row) => !row.uid && row.derivedFromUid == null;
|
|
4366
4507
|
const saveItemStorage = fromCallback(({ sendBack, input: { context, event } }) => {
|
|
@@ -4414,22 +4555,25 @@ const saveItemStorage = fromCallback(({ sendBack, input: { context, event } }) =
|
|
|
4414
4555
|
const latest = [...queryRows].sort(compareMetadataRowsLatestFirst)[0];
|
|
4415
4556
|
propertyData = latest && isLocalDraft(latest) ? latest : undefined;
|
|
4416
4557
|
if (!propertyData && newValue) {
|
|
4417
|
-
const
|
|
4418
|
-
|
|
4419
|
-
await BaseFileManager.createDirIfNotExists(BaseFileManager.getFilesPath(dir));
|
|
4420
|
-
const writeToPath = BaseFileManager.getFilesPath(dir, filename);
|
|
4421
|
-
await BaseFileManager.saveFile(writeToPath, newValue);
|
|
4422
|
-
propertyData = await createMetadata({
|
|
4423
|
-
propertyName,
|
|
4424
|
-
propertyValue: filename,
|
|
4425
|
-
modelType: (modelName ?? knownRow?.modelType ?? '').toLowerCase() || undefined,
|
|
4426
|
-
seedLocalId: draftSeedLocalId,
|
|
4427
|
-
seedUid: draftSeedUid,
|
|
4428
|
-
versionLocalId,
|
|
4429
|
-
versionUid,
|
|
4558
|
+
const target = {
|
|
4559
|
+
seedId: draftSeedUid || draftSeedLocalId,
|
|
4430
4560
|
localStorageDir: propertyRecordSchema.localStorageDir,
|
|
4431
|
-
|
|
4432
|
-
}
|
|
4561
|
+
filenameSuffix: propertyRecordSchema.filenameSuffix,
|
|
4562
|
+
};
|
|
4563
|
+
propertyData = await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
|
|
4564
|
+
const { fileName: filename } = await writeItemStorageFile(target, newValue);
|
|
4565
|
+
return createMetadata({
|
|
4566
|
+
propertyName,
|
|
4567
|
+
propertyValue: filename,
|
|
4568
|
+
modelType: (modelName ?? knownRow?.modelType ?? '').toLowerCase() || undefined,
|
|
4569
|
+
seedLocalId: draftSeedLocalId,
|
|
4570
|
+
seedUid: draftSeedUid,
|
|
4571
|
+
versionLocalId,
|
|
4572
|
+
versionUid,
|
|
4573
|
+
localStorageDir: propertyRecordSchema.localStorageDir,
|
|
4574
|
+
refValueType: 'file',
|
|
4575
|
+
}, propertyRecordSchema);
|
|
4576
|
+
});
|
|
4433
4577
|
}
|
|
4434
4578
|
}
|
|
4435
4579
|
else if (propertyData && !isLocalDraft(propertyData)) {
|
|
@@ -4438,31 +4582,64 @@ const saveItemStorage = fromCallback(({ sendBack, input: { context, event } }) =
|
|
|
4438
4582
|
if (!propertyData) {
|
|
4439
4583
|
throw new Error(`No metadata row to save ${propertyName} to`);
|
|
4440
4584
|
}
|
|
4441
|
-
|
|
4442
|
-
const
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4585
|
+
// No storage.path: the `files` directory, as resolveItemStorageChildFile and download assume.
|
|
4586
|
+
const localStorageDirOf = (row) => propertyRecordSchema.localStorageDir || row.localStorageDir || '/files';
|
|
4587
|
+
const fileNameOf = (row) => {
|
|
4588
|
+
if (row.refResolvedValue)
|
|
4589
|
+
return row.refResolvedValue;
|
|
4590
|
+
const seedId = row.seedUid || row.seedLocalId;
|
|
4591
|
+
return seedId ? getItemStorageLocalFileName(seedId, propertyRecordSchema.filenameSuffix) : undefined;
|
|
4592
|
+
};
|
|
4593
|
+
if (!fileNameOf(propertyData)) {
|
|
4594
|
+
throw new Error(`Missing a seed id to name the ${propertyName} file after`);
|
|
4595
|
+
}
|
|
4596
|
+
// Read the row, write the file and update the row under the file's lock, so a conversion of a
|
|
4597
|
+
// legacy row (migration, publish) or another save of this file, in this tab or another, can't
|
|
4598
|
+
// land in between and leave the file with older content than the row says.
|
|
4599
|
+
const saved = await withLockedItemStorageRow(propertyData.localId, (row) => {
|
|
4600
|
+
const fileName = fileNameOf(row);
|
|
4601
|
+
return fileName && BaseFileManager.getFilesPath(getItemStorageSubdir(localStorageDirOf(row)), fileName);
|
|
4602
|
+
}, async (row, filePath) => {
|
|
4603
|
+
const localStorageDir = localStorageDirOf(row);
|
|
4604
|
+
const fileName = fileNameOf(row);
|
|
4605
|
+
try {
|
|
4606
|
+
await writeItemStorageFile({ seedId: row.seedUid || row.seedLocalId || '', localStorageDir, fileName }, newValue);
|
|
4607
|
+
}
|
|
4608
|
+
catch (error) {
|
|
4609
|
+
const fs = await BaseFileManager.getFs();
|
|
4610
|
+
fs.writeFileSync(filePath, newValue);
|
|
4611
|
+
}
|
|
4612
|
+
// A legacy row (made before Item.create saved ItemStorage values) holds the old content itself
|
|
4613
|
+
// in propertyValue. The file is the content now: drop it, or a fresh load shows the old text
|
|
4614
|
+
// until the file is read. A row whose propertyValue is the file name keeps it.
|
|
4615
|
+
const clearsVerbatimValue = !row.refResolvedValue &&
|
|
4616
|
+
row.propertyValue != null &&
|
|
4617
|
+
row.propertyValue !== '' &&
|
|
4618
|
+
row.propertyValue !== fileName;
|
|
4619
|
+
// The row says where the file is (read back by hydration, the browser's metadata live query
|
|
4620
|
+
// and publish); without localStorageDir the live query would clear it from the context.
|
|
4621
|
+
await appDb
|
|
4622
|
+
.update(metadata)
|
|
4623
|
+
.set({
|
|
4624
|
+
refResolvedValue: fileName,
|
|
4625
|
+
localStorageDir,
|
|
4626
|
+
// Same shape as a row the migration or publish converted (convertVerbatimItemStorageRow).
|
|
4627
|
+
...(clearsVerbatimValue && { propertyValue: null, refValueType: 'file' }),
|
|
4628
|
+
})
|
|
4629
|
+
.where(eq(metadata.localId, row.localId));
|
|
4630
|
+
return { fileName, localStorageDir };
|
|
4631
|
+
});
|
|
4632
|
+
// The row went away (or lost its seed ids) before the lock was granted.
|
|
4633
|
+
if (!saved)
|
|
4634
|
+
throw new Error(`No metadata row to save ${propertyName} to`);
|
|
4635
|
+
const { fileName, localStorageDir } = saved;
|
|
4463
4636
|
sendBack({
|
|
4464
4637
|
type: 'updateContext',
|
|
4465
4638
|
renderValue: newValue,
|
|
4639
|
+
// Where the file is, right away: localStoragePath (and so publish uploads) must not wait for
|
|
4640
|
+
// the browser's metadata live query, which Node does not have at all.
|
|
4641
|
+
refResolvedValue: fileName,
|
|
4642
|
+
localStorageDir,
|
|
4466
4643
|
// Point the property at the draft row when the edit moved off a published row.
|
|
4467
4644
|
...(propertyData.localId !== localId && { localId: propertyData.localId }),
|
|
4468
4645
|
});
|
|
@@ -4532,9 +4709,23 @@ const propertyMachine = setup({
|
|
|
4532
4709
|
isSaving: true,
|
|
4533
4710
|
_saveError: undefined,
|
|
4534
4711
|
_saveValidationErrors: undefined,
|
|
4712
|
+
_valueBeforeSave: ({ event }) => event.before,
|
|
4535
4713
|
}),
|
|
4536
4714
|
target: '.saving',
|
|
4537
4715
|
},
|
|
4716
|
+
/** analyzeInput refused (item not owned) or failed before writing: restore the shown value. */
|
|
4717
|
+
saveFailed: {
|
|
4718
|
+
target: '.idle',
|
|
4719
|
+
actions: assign(({ context, event }) => {
|
|
4720
|
+
const error = event.error;
|
|
4721
|
+
return {
|
|
4722
|
+
isSaving: false,
|
|
4723
|
+
_saveError: error instanceof Error ? { message: error.message, name: error.name } : { message: String(error) },
|
|
4724
|
+
...(context._valueBeforeSave ?? {}),
|
|
4725
|
+
_valueBeforeSave: undefined,
|
|
4726
|
+
};
|
|
4727
|
+
}),
|
|
4728
|
+
},
|
|
4538
4729
|
updateContext: {
|
|
4539
4730
|
actions: assign(({ context, event }) => {
|
|
4540
4731
|
const newContext = Object.assign({}, context);
|
|
@@ -4834,12 +5025,12 @@ const getPropertyData = async ({ propertyName, seedLocalId, seedUid, modelName,
|
|
|
4834
5025
|
let names = [...getMetadataPropertyNamesForQuery(propertyName)];
|
|
4835
5026
|
if (modelName) {
|
|
4836
5027
|
try {
|
|
4837
|
-
const
|
|
4838
|
-
const
|
|
4839
|
-
const { Model } =
|
|
4840
|
-
const
|
|
4841
|
-
const
|
|
4842
|
-
const { resolveItemModelFileId } =
|
|
5028
|
+
const _mod_13 = await import('./index-8O3Uow-Y.js');
|
|
5029
|
+
const _ns_13 = _mod_13.f;
|
|
5030
|
+
const { Model } = _ns_13;
|
|
5031
|
+
const _mod_14 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
5032
|
+
const _ns_14 = _mod_14.b1;
|
|
5033
|
+
const { resolveItemModelFileId } = _ns_14;
|
|
4843
5034
|
// Model names are only unique per schema: use the seed's own model when it is recorded.
|
|
4844
5035
|
const modelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
|
|
4845
5036
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
@@ -4999,6 +5190,8 @@ function forceRemoveFromCaches(instance, config) {
|
|
|
4999
5190
|
/**
|
|
5000
5191
|
* Run the service event sequence and stop the service:
|
|
5001
5192
|
* destroyStarted -> doDestroy -> (destroyError on failure) -> stop.
|
|
5193
|
+
* A doDestroy failure is recorded on the service (destroyError) and rethrown, so destroy()
|
|
5194
|
+
* rejects instead of resolving with the rows still in the DB.
|
|
5002
5195
|
* Event names must match what the entity machines expect.
|
|
5003
5196
|
*/
|
|
5004
5197
|
async function runDestroyLifecycle(instance, config) {
|
|
@@ -5009,6 +5202,7 @@ async function runDestroyLifecycle(instance, config) {
|
|
|
5009
5202
|
}
|
|
5010
5203
|
catch (error) {
|
|
5011
5204
|
service.send({ type: 'destroyError', error });
|
|
5205
|
+
throw error;
|
|
5012
5206
|
}
|
|
5013
5207
|
finally {
|
|
5014
5208
|
try {
|
|
@@ -5028,9 +5222,9 @@ const HTML_PROP_SEED_UID_RE = /^0x[a-fA-F0-9]{64}$/;
|
|
|
5028
5222
|
*/
|
|
5029
5223
|
const resolvePropertyRecordSchemaFromSchemaData = async (modelName, propertyName, modelType, schemaName) => {
|
|
5030
5224
|
try {
|
|
5031
|
-
const
|
|
5032
|
-
const
|
|
5033
|
-
const { loadAllSchemasFromDb } =
|
|
5225
|
+
const _mod_15 = await import('./ClientManager-i3nJASkg.js');
|
|
5226
|
+
const _ns_15 = _mod_15.K;
|
|
5227
|
+
const { loadAllSchemasFromDb } = _ns_15;
|
|
5034
5228
|
const allSchemas = await loadAllSchemasFromDb();
|
|
5035
5229
|
const modelNameAlt = modelType ? upperFirst(camelCase(modelType)) : '';
|
|
5036
5230
|
for (const { schema } of allSchemas) {
|
|
@@ -5082,13 +5276,13 @@ hints = {}) => {
|
|
|
5082
5276
|
return undefined;
|
|
5083
5277
|
}
|
|
5084
5278
|
try {
|
|
5085
|
-
const
|
|
5086
|
-
const
|
|
5087
|
-
const { Model } =
|
|
5279
|
+
const _mod_16 = await import('./index-8O3Uow-Y.js');
|
|
5280
|
+
const _ns_16 = _mod_16.f;
|
|
5281
|
+
const { Model } = _ns_16;
|
|
5088
5282
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
5089
|
-
const
|
|
5090
|
-
const
|
|
5091
|
-
const { resolveItemModelFileId } =
|
|
5283
|
+
const _mod_17 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
5284
|
+
const _ns_17 = _mod_17.b1;
|
|
5285
|
+
const { resolveItemModelFileId } = _ns_17;
|
|
5092
5286
|
const modelFileId = await resolveItemModelFileId(hints);
|
|
5093
5287
|
let model = modelFileId
|
|
5094
5288
|
? await Model.resolveAsync(modelName || modelTypeToModelName(modelType ?? ''), { modelFileId })
|
|
@@ -5246,7 +5440,7 @@ class ItemProperty {
|
|
|
5246
5440
|
return;
|
|
5247
5441
|
}
|
|
5248
5442
|
// Use dynamic import to break circular dependency
|
|
5249
|
-
const schemaMod = await import('./index-
|
|
5443
|
+
const schemaMod = await import('./index-Cvt5UBz4.js');
|
|
5250
5444
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
5251
5445
|
const { context } = snapshot;
|
|
5252
5446
|
const { propertyRecordSchema } = context;
|
|
@@ -5417,9 +5611,9 @@ class ItemProperty {
|
|
|
5417
5611
|
const normalizedRefValueType = normalizeDataType(propertyRecordSchema?.refValueType);
|
|
5418
5612
|
const propertyNames = getMetadataPropertyNamesForQuery(propertyName, normalizedDataType, normalizedRefValueType);
|
|
5419
5613
|
const propertyNameVariant = propertyNames.length > 1 ? propertyNames[1] : undefined;
|
|
5420
|
-
const
|
|
5421
|
-
const
|
|
5422
|
-
const seedSchemaMod =
|
|
5614
|
+
const _mod_18 = await import('./index-AVFTVp1m.js');
|
|
5615
|
+
const _ns_18 = _mod_18.s;
|
|
5616
|
+
const seedSchemaMod = _ns_18;
|
|
5423
5617
|
const { metadata } = seedSchemaMod;
|
|
5424
5618
|
const drizzleMod = await import('drizzle-orm');
|
|
5425
5619
|
const { eq, and, or } = drizzleMod;
|
|
@@ -5633,9 +5827,9 @@ class ItemProperty {
|
|
|
5633
5827
|
const ctx = this._service.getSnapshot().context;
|
|
5634
5828
|
let modelFileId;
|
|
5635
5829
|
try {
|
|
5636
|
-
const
|
|
5637
|
-
const
|
|
5638
|
-
const { resolveItemModelFileId } =
|
|
5830
|
+
const _mod_19 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
5831
|
+
const _ns_19 = _mod_19.b1;
|
|
5832
|
+
const { resolveItemModelFileId } = _ns_19;
|
|
5639
5833
|
modelFileId = await resolveItemModelFileId({
|
|
5640
5834
|
modelFileId: ctx.modelFileId,
|
|
5641
5835
|
seedLocalId: ctx.seedLocalId,
|
|
@@ -5748,7 +5942,7 @@ class ItemProperty {
|
|
|
5748
5942
|
}
|
|
5749
5943
|
static create(props, options) {
|
|
5750
5944
|
const waitForReady = options?.waitForReady !== false;
|
|
5751
|
-
const readyTimeout = options?.readyTimeout ??
|
|
5945
|
+
const readyTimeout = options?.readyTimeout ?? DEFAULT_READY_TIMEOUT_MS;
|
|
5752
5946
|
const { propertyName, seedLocalId, seedUid, versionLocalId, versionUid } = props;
|
|
5753
5947
|
if (!propertyName || (!seedLocalId && !seedUid)) {
|
|
5754
5948
|
if (!waitForReady)
|
|
@@ -5934,7 +6128,7 @@ class ItemProperty {
|
|
|
5934
6128
|
}
|
|
5935
6129
|
return undefined;
|
|
5936
6130
|
}
|
|
5937
|
-
static async find({ propertyName, seedLocalId, seedUid, modelName: modelNameOption, waitForReady = true, readyTimeout =
|
|
6131
|
+
static async find({ propertyName, seedLocalId, seedUid, modelName: modelNameOption, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, }) {
|
|
5938
6132
|
if ((!seedLocalId && !seedUid) || !propertyName) {
|
|
5939
6133
|
return undefined;
|
|
5940
6134
|
}
|
|
@@ -5988,7 +6182,7 @@ class ItemProperty {
|
|
|
5988
6182
|
* Loads property data via getItemProperties, creates instances via create, optionally waits for idle.
|
|
5989
6183
|
*/
|
|
5990
6184
|
static async all(params, options) {
|
|
5991
|
-
const { waitForReady = false, readyTimeout =
|
|
6185
|
+
const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS } = options ?? {};
|
|
5992
6186
|
const { seedLocalId, seedUid } = params;
|
|
5993
6187
|
if (!seedLocalId && !seedUid) {
|
|
5994
6188
|
return [];
|
|
@@ -5996,9 +6190,9 @@ class ItemProperty {
|
|
|
5996
6190
|
const propertiesData = await getItemProperties({ seedLocalId, seedUid });
|
|
5997
6191
|
const instances = [];
|
|
5998
6192
|
const seenNormalized = new Set();
|
|
5999
|
-
const
|
|
6000
|
-
const
|
|
6001
|
-
const { resolveItemModelFileId } =
|
|
6193
|
+
const _mod_20 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
6194
|
+
const _ns_20 = _mod_20.b1;
|
|
6195
|
+
const { resolveItemModelFileId } = _ns_20;
|
|
6002
6196
|
const itemModelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
|
|
6003
6197
|
for (const data of propertiesData) {
|
|
6004
6198
|
const d = data;
|
|
@@ -6014,9 +6208,9 @@ class ItemProperty {
|
|
|
6014
6208
|
}
|
|
6015
6209
|
else if (baseName) {
|
|
6016
6210
|
try {
|
|
6017
|
-
const
|
|
6018
|
-
const
|
|
6019
|
-
const { Model } =
|
|
6211
|
+
const _mod_21 = await import('./index-8O3Uow-Y.js');
|
|
6212
|
+
const _ns_21 = _mod_21.f;
|
|
6213
|
+
const { Model } = _ns_21;
|
|
6020
6214
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
6021
6215
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6022
6216
|
if (model?.properties) {
|
|
@@ -6031,9 +6225,9 @@ class ItemProperty {
|
|
|
6031
6225
|
}
|
|
6032
6226
|
if (modelName && propertyName) {
|
|
6033
6227
|
try {
|
|
6034
|
-
const
|
|
6035
|
-
const
|
|
6036
|
-
const { Model } =
|
|
6228
|
+
const _mod_22 = await import('./index-8O3Uow-Y.js');
|
|
6229
|
+
const _ns_22 = _mod_22.f;
|
|
6230
|
+
const { Model } = _ns_22;
|
|
6037
6231
|
const { modelPropertiesToObject } = await import('./model-DGMe-TTm.js');
|
|
6038
6232
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6039
6233
|
if (model?.properties?.length) {
|
|
@@ -6189,6 +6383,8 @@ class ItemProperty {
|
|
|
6189
6383
|
if (currentValue === value) {
|
|
6190
6384
|
return;
|
|
6191
6385
|
}
|
|
6386
|
+
// Restored if the save is refused (item not owned) or fails.
|
|
6387
|
+
const before = { propertyValue: context.propertyValue, renderValue: context.renderValue };
|
|
6192
6388
|
// Update context immediately so UI shows the value before save completes
|
|
6193
6389
|
this._service.send({
|
|
6194
6390
|
type: 'updateContext',
|
|
@@ -6207,7 +6403,7 @@ class ItemProperty {
|
|
|
6207
6403
|
if (!schema)
|
|
6208
6404
|
return false;
|
|
6209
6405
|
this._service.send({ type: 'updateContext', propertyRecordSchema: schema });
|
|
6210
|
-
this._service.send({ type: 'save', newValue: value });
|
|
6406
|
+
this._service.send({ type: 'save', newValue: value, before });
|
|
6211
6407
|
return true;
|
|
6212
6408
|
}, () => false);
|
|
6213
6409
|
this._pendingSchemaSave = pending;
|
|
@@ -6220,6 +6416,7 @@ class ItemProperty {
|
|
|
6220
6416
|
this._service.send({
|
|
6221
6417
|
type: 'save',
|
|
6222
6418
|
newValue: value,
|
|
6419
|
+
before,
|
|
6223
6420
|
});
|
|
6224
6421
|
}
|
|
6225
6422
|
}
|
|
@@ -6329,10 +6526,17 @@ class ItemProperty {
|
|
|
6329
6526
|
}
|
|
6330
6527
|
}
|
|
6331
6528
|
/**
|
|
6332
|
-
* Destroy the item property: remove from caches, delete metadata
|
|
6529
|
+
* Destroy the item property: remove from caches, delete its metadata rows (every version of
|
|
6530
|
+
* this item's value) from the DB, remove it from the parent Item, and stop the service.
|
|
6531
|
+
* Throws OwnershipError if none of the client's addresses own the item.
|
|
6333
6532
|
*/
|
|
6334
6533
|
async destroy() {
|
|
6335
6534
|
const context = this._getSnapshotContext();
|
|
6535
|
+
const { assertItemOwned } = await Promise.resolve().then(function () { return ownership; });
|
|
6536
|
+
await assertItemOwned({
|
|
6537
|
+
seedLocalId: context.seedLocalId ?? undefined,
|
|
6538
|
+
seedUid: context.seedUid ?? undefined,
|
|
6539
|
+
});
|
|
6336
6540
|
const cacheKey = ItemProperty.cacheKey(context.seedUid || context.seedLocalId || '', context.propertyName || '');
|
|
6337
6541
|
const cacheKeys = cacheKey && cacheKey !== 'Item__' ? [cacheKey] : [];
|
|
6338
6542
|
clearDestroySubscriptions(this, {
|
|
@@ -6353,17 +6557,16 @@ class ItemProperty {
|
|
|
6353
6557
|
if (!propertyName || (!seedLocalId && !seedUid))
|
|
6354
6558
|
return;
|
|
6355
6559
|
if (db) {
|
|
6356
|
-
const
|
|
6357
|
-
const
|
|
6358
|
-
const seedSchemaMod =
|
|
6560
|
+
const _mod_23 = await import('./index-AVFTVp1m.js');
|
|
6561
|
+
const _ns_23 = _mod_23.s;
|
|
6562
|
+
const seedSchemaMod = _ns_23;
|
|
6359
6563
|
const { metadata } = seedSchemaMod;
|
|
6360
6564
|
const drizzleMod = await import('drizzle-orm');
|
|
6361
|
-
const { and, eq
|
|
6565
|
+
const { and, eq } = drizzleMod;
|
|
6362
6566
|
const conditions = [eq(metadata.propertyName, propertyName)];
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
else if (seedLocalId) {
|
|
6567
|
+
// Match this item's local rows only. Matching seedUid too would also delete rows of
|
|
6568
|
+
// other local copies of the same seed (e.g. duplicate EAS syncs).
|
|
6569
|
+
if (seedLocalId) {
|
|
6367
6570
|
conditions.push(eq(metadata.seedLocalId, seedLocalId));
|
|
6368
6571
|
}
|
|
6369
6572
|
else if (seedUid) {
|
|
@@ -6399,9 +6602,9 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6399
6602
|
}
|
|
6400
6603
|
const seedType = toSnakeCase(modelName);
|
|
6401
6604
|
// Dynamic import to break circular dependency
|
|
6402
|
-
const
|
|
6403
|
-
const
|
|
6404
|
-
const modelMod =
|
|
6605
|
+
const _mod_24 = await import('./index-8O3Uow-Y.js');
|
|
6606
|
+
const _ns_24 = _mod_24.f;
|
|
6607
|
+
const modelMod = _ns_24;
|
|
6405
6608
|
const { Model } = modelMod;
|
|
6406
6609
|
const model = await Model.resolveAsync(modelName, { modelFileId });
|
|
6407
6610
|
const propertySchemas = model?.properties ? modelPropertiesToObject(model.properties) : undefined;
|
|
@@ -6420,13 +6623,38 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6420
6623
|
for (const propertyName of allPropertyNames) {
|
|
6421
6624
|
const propertyValue = propertyData[propertyName];
|
|
6422
6625
|
const propertyRecordSchema = propertySchemas?.[propertyName];
|
|
6423
|
-
|
|
6626
|
+
// ItemStorage content lives in the property's file (`<seedLocalId><extension>`), as a save puts
|
|
6627
|
+
// it; the row records where. Stored verbatim in the row, publish would never upload it.
|
|
6628
|
+
const isItemStorageValue = propertyRecordSchema?.storageType === 'ItemStorage' &&
|
|
6629
|
+
propertyValue != null &&
|
|
6630
|
+
propertyValue !== '';
|
|
6631
|
+
const insertRow = (storageFields) => createMetadata({
|
|
6424
6632
|
seedLocalId: newSeedId,
|
|
6425
6633
|
versionLocalId: newVersionId,
|
|
6426
6634
|
propertyName,
|
|
6427
|
-
propertyValue,
|
|
6635
|
+
propertyValue: storageFields ? undefined : propertyValue,
|
|
6636
|
+
...storageFields,
|
|
6428
6637
|
modelName,
|
|
6429
6638
|
}, propertyRecordSchema, { skipValidation: true, modelFileId });
|
|
6639
|
+
if (!isItemStorageValue) {
|
|
6640
|
+
await insertRow();
|
|
6641
|
+
continue;
|
|
6642
|
+
}
|
|
6643
|
+
// File and row under the file's lock, like every writer of a local draft's file (see
|
|
6644
|
+
// withItemStorageFileLock). The seed is new, so nothing else should be writing it yet.
|
|
6645
|
+
const target = {
|
|
6646
|
+
seedId: newSeedId,
|
|
6647
|
+
localStorageDir: propertyRecordSchema.localStorageDir,
|
|
6648
|
+
filenameSuffix: propertyRecordSchema.filenameSuffix,
|
|
6649
|
+
};
|
|
6650
|
+
await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
|
|
6651
|
+
const written = await writeItemStorageFile(target, propertyValue);
|
|
6652
|
+
await insertRow({
|
|
6653
|
+
refResolvedValue: written.fileName,
|
|
6654
|
+
localStorageDir: written.localStorageDir,
|
|
6655
|
+
refValueType: 'file',
|
|
6656
|
+
});
|
|
6657
|
+
});
|
|
6430
6658
|
}
|
|
6431
6659
|
return {
|
|
6432
6660
|
modelName,
|
|
@@ -6444,7 +6672,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6444
6672
|
* @returns Entity instance if found, undefined otherwise
|
|
6445
6673
|
*/
|
|
6446
6674
|
async function findEntity(config, params, options = {}) {
|
|
6447
|
-
const { waitForReady = true, readyTimeout =
|
|
6675
|
+
const { waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS } = options;
|
|
6448
6676
|
let instance;
|
|
6449
6677
|
// Try ID lookup first (most specific)
|
|
6450
6678
|
if (params.id) {
|
|
@@ -6557,9 +6785,9 @@ const getModel = () => {
|
|
|
6557
6785
|
// the fragile `import(...).then(n => n.X)` chunk-namespace pattern.
|
|
6558
6786
|
if (!modelImportPromise) {
|
|
6559
6787
|
modelImportPromise = (async () => {
|
|
6560
|
-
const
|
|
6561
|
-
const
|
|
6562
|
-
const mod =
|
|
6788
|
+
const _mod_25 = await import('./index-8O3Uow-Y.js');
|
|
6789
|
+
const _ns_25 = _mod_25.f;
|
|
6790
|
+
const mod = _ns_25;
|
|
6563
6791
|
ModelClass = mod.Model;
|
|
6564
6792
|
return mod;
|
|
6565
6793
|
})();
|
|
@@ -6590,10 +6818,16 @@ const getModel = () => {
|
|
|
6590
6818
|
};
|
|
6591
6819
|
// Define tracked properties for the Proxy
|
|
6592
6820
|
// These properties will be read from/written to the actor context
|
|
6593
|
-
/**
|
|
6594
|
-
|
|
6821
|
+
/**
|
|
6822
|
+
* Initial values that need ItemProperty.save() rather than a verbatim metadata row: raw File/Image/Html
|
|
6823
|
+
* content (not already a storage seed reference) becomes a storage seed, and an ItemStorage property's
|
|
6824
|
+
* content goes into its file (`<seedLocalId><extension>`), where publish and reads look for it.
|
|
6825
|
+
*/
|
|
6826
|
+
function needsStorageSavePipeline(dataType, value, storageType) {
|
|
6595
6827
|
if (value == null || value === '')
|
|
6596
6828
|
return false;
|
|
6829
|
+
if (storageType === 'ItemStorage')
|
|
6830
|
+
return true;
|
|
6597
6831
|
const isStorageType = isDataType(dataType, ModelPropertyDataTypes.File) ||
|
|
6598
6832
|
isDataType(dataType, ModelPropertyDataTypes.Image) ||
|
|
6599
6833
|
isDataType(dataType, ModelPropertyDataTypes.Html);
|
|
@@ -6669,29 +6903,41 @@ class Item {
|
|
|
6669
6903
|
latestVersionUid: head?.uid ?? undefined,
|
|
6670
6904
|
});
|
|
6671
6905
|
};
|
|
6672
|
-
|
|
6906
|
+
/**
|
|
6907
|
+
* Upload this item's files to Arweave and write its attestations to EAS.
|
|
6908
|
+
*
|
|
6909
|
+
* Requires @seedprotocol/publish. Its `initPublish()` (or `<PublishProvider config>`)
|
|
6910
|
+
* registers the PublishExecutor this delegates to; without it, publish() throws
|
|
6911
|
+
* PUBLISH_NOT_CONFIGURED_MESSAGE. `options` are passed to that package unchanged (its
|
|
6912
|
+
* CreatePublishOptions: signers, Arweave tags, `publishMode`, `onPublished`, ...).
|
|
6913
|
+
*
|
|
6914
|
+
* Resolves when the publish has finished, and rejects with the publish package's error
|
|
6915
|
+
* if it failed. Throws OwnershipError if none of the client's addresses own the item.
|
|
6916
|
+
*/
|
|
6917
|
+
this.publish = async (options) => {
|
|
6673
6918
|
const { assertItemOwned } = await Promise.resolve().then(function () { return ownership; });
|
|
6919
|
+
const { getPublishExecutor, PUBLISH_NOT_CONFIGURED_MESSAGE } = await Promise.resolve().then(function () { return publishConfig; });
|
|
6674
6920
|
await assertItemOwned(this);
|
|
6675
|
-
|
|
6921
|
+
if (!getPublishExecutor()) {
|
|
6922
|
+
throw new Error(PUBLISH_NOT_CONFIGURED_MESSAGE);
|
|
6923
|
+
}
|
|
6924
|
+
const current = this._service.getSnapshot().value;
|
|
6925
|
+
if (current !== 'idle') {
|
|
6926
|
+
throw new Error(current === 'publishing'
|
|
6927
|
+
? 'Item is already being published.'
|
|
6928
|
+
: `Item is not ready to publish (state: ${current}).`);
|
|
6929
|
+
}
|
|
6676
6930
|
return new Promise((resolve, reject) => {
|
|
6931
|
+
// Subscribe before sending: subscribe() does not replay the current snapshot,
|
|
6932
|
+
// so a subscription made after startPublish could miss the 'publishing' state.
|
|
6677
6933
|
let wasPublishing = false;
|
|
6678
|
-
const timeoutMs = 300000; // 5 minutes, match previous handler timeout
|
|
6679
|
-
const timeoutId = setTimeout(() => {
|
|
6680
|
-
unsub.unsubscribe();
|
|
6681
|
-
if (!wasPublishing) {
|
|
6682
|
-
reject(new Error('Publish did not start (timeout)'));
|
|
6683
|
-
}
|
|
6684
|
-
else {
|
|
6685
|
-
reject(new Error('Publish timed out'));
|
|
6686
|
-
}
|
|
6687
|
-
}, timeoutMs);
|
|
6688
6934
|
const unsub = this._service.subscribe((snapshot) => {
|
|
6689
6935
|
const value = snapshot.value;
|
|
6690
6936
|
if (value === 'publishing') {
|
|
6691
6937
|
wasPublishing = true;
|
|
6938
|
+
return;
|
|
6692
6939
|
}
|
|
6693
6940
|
if (value === 'idle' && wasPublishing) {
|
|
6694
|
-
clearTimeout(timeoutId);
|
|
6695
6941
|
unsub.unsubscribe();
|
|
6696
6942
|
const ctx = snapshot.context;
|
|
6697
6943
|
if (ctx._publishError) {
|
|
@@ -6702,18 +6948,19 @@ class Item {
|
|
|
6702
6948
|
}
|
|
6703
6949
|
}
|
|
6704
6950
|
});
|
|
6951
|
+
this._service.send({ type: 'startPublish', item: this, options });
|
|
6705
6952
|
});
|
|
6706
6953
|
};
|
|
6707
6954
|
this.getPublishUploads = async (options) => {
|
|
6708
6955
|
// Use dynamic import to break circular dependency
|
|
6709
|
-
const getPublishUploadsMod = await import('./getPublishUploads-
|
|
6956
|
+
const getPublishUploadsMod = await import('./getPublishUploads-SFHCbf_y.js');
|
|
6710
6957
|
const { getPublishUploads } = getPublishUploadsMod;
|
|
6711
6958
|
return await getPublishUploads(this, [], undefined, options);
|
|
6712
6959
|
};
|
|
6713
6960
|
this.getPublishPayload = async (uploadedTransactions, options) => {
|
|
6714
|
-
const
|
|
6715
|
-
const
|
|
6716
|
-
const getPublishPayloadMod =
|
|
6961
|
+
const _mod_26 = await import('./getPublishPayload-CTCvRUoU.js');
|
|
6962
|
+
const _ns_26 = _mod_26.g;
|
|
6963
|
+
const getPublishPayloadMod = _ns_26;
|
|
6717
6964
|
const { getPublishPayload } = getPublishPayloadMod;
|
|
6718
6965
|
return await getPublishPayload(this, uploadedTransactions, options);
|
|
6719
6966
|
};
|
|
@@ -7070,7 +7317,7 @@ class Item {
|
|
|
7070
7317
|
}
|
|
7071
7318
|
static async create(props, options) {
|
|
7072
7319
|
const waitForReady = options?.waitForReady !== false;
|
|
7073
|
-
const readyTimeout = options?.readyTimeout ??
|
|
7320
|
+
const readyTimeout = options?.readyTimeout ?? DEFAULT_READY_TIMEOUT_MS;
|
|
7074
7321
|
if (!props.modelName && props.type) {
|
|
7075
7322
|
props.modelName = startCase(props.type);
|
|
7076
7323
|
}
|
|
@@ -7243,12 +7490,13 @@ class Item {
|
|
|
7243
7490
|
// Get property names directly from database to make Item independent from Model
|
|
7244
7491
|
let propertyNames = [];
|
|
7245
7492
|
const dataTypeByPropertyName = new Map();
|
|
7493
|
+
const storageTypeByPropertyName = new Map();
|
|
7246
7494
|
const db = BaseDb.getAppDb();
|
|
7247
7495
|
if (db && props.modelName) {
|
|
7248
7496
|
// Model names are only unique per schema: resolve the exact models row from the most specific scope.
|
|
7249
|
-
const
|
|
7250
|
-
const
|
|
7251
|
-
const { resolveModelRecord } =
|
|
7497
|
+
const _mod_27 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
7498
|
+
const _ns_27 = _mod_27.b1;
|
|
7499
|
+
const { resolveModelRecord } = _ns_27;
|
|
7252
7500
|
const modelRecord = await resolveModelRecord(props.modelName, {
|
|
7253
7501
|
modelFileId: props.modelFileId ?? modelInstance?.id,
|
|
7254
7502
|
schemaName: schemaName ?? modelInstance?.schemaName,
|
|
@@ -7260,12 +7508,12 @@ class Item {
|
|
|
7260
7508
|
// Scope the constructor's Model lookup to this model's schema (as getItemData does on reload),
|
|
7261
7509
|
// so a same-named model cached from another schema can't supply the property set.
|
|
7262
7510
|
if (modelRecord && !props.schemaName) {
|
|
7263
|
-
const
|
|
7264
|
-
const
|
|
7265
|
-
const { modelSchemas } =
|
|
7266
|
-
const
|
|
7267
|
-
const
|
|
7268
|
-
const { schemas: schemasTable } =
|
|
7511
|
+
const _mod_28 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
7512
|
+
const _ns_28 = _mod_28.b0;
|
|
7513
|
+
const { modelSchemas } = _ns_28;
|
|
7514
|
+
const _mod_29 = await import('./BasePathResolver-Cm4apKRb.js');
|
|
7515
|
+
const _ns_29 = _mod_29.a$;
|
|
7516
|
+
const { schemas: schemasTable } = _ns_29;
|
|
7269
7517
|
const schemaRows = await db
|
|
7270
7518
|
.select({ schemaName: schemasTable.name })
|
|
7271
7519
|
.from(modelSchemas)
|
|
@@ -7278,13 +7526,19 @@ class Item {
|
|
|
7278
7526
|
}
|
|
7279
7527
|
if (modelRecords.length > 0 && modelRecords[0].id) {
|
|
7280
7528
|
const propertyRecords = await db
|
|
7281
|
-
.select({
|
|
7529
|
+
.select({
|
|
7530
|
+
name: properties.name,
|
|
7531
|
+
dataType: properties.dataType,
|
|
7532
|
+
storageType: properties.storageType,
|
|
7533
|
+
})
|
|
7282
7534
|
.from(properties)
|
|
7283
7535
|
.where(eq(properties.modelId, modelRecords[0].id));
|
|
7284
7536
|
propertyNames = propertyRecords.map((r) => r.name).filter((name) => Boolean(name));
|
|
7285
7537
|
for (const r of propertyRecords) {
|
|
7286
7538
|
if (r.name && r.dataType)
|
|
7287
7539
|
dataTypeByPropertyName.set(r.name, r.dataType);
|
|
7540
|
+
if (r.name && r.storageType)
|
|
7541
|
+
storageTypeByPropertyName.set(r.name, r.storageType);
|
|
7288
7542
|
}
|
|
7289
7543
|
}
|
|
7290
7544
|
}
|
|
@@ -7293,7 +7547,8 @@ class Item {
|
|
|
7293
7547
|
modelFileId: props.modelFileId,
|
|
7294
7548
|
};
|
|
7295
7549
|
// File/Image/Html values that are raw content (html string, data URI, URL, File) must go through
|
|
7296
|
-
// the property's save pipeline to become storage seeds
|
|
7550
|
+
// the property's save pipeline to become storage seeds, and ItemStorage values to be written to
|
|
7551
|
+
// their file with the property context pointing at it (as `prop.value = v; await prop.save()`).
|
|
7297
7552
|
const pipelineValues = [];
|
|
7298
7553
|
// Only include properties that are in the model schema
|
|
7299
7554
|
// Exclude modelInstance, modelName, and schemaName as they're metadata, not item properties
|
|
@@ -7303,7 +7558,7 @@ class Item {
|
|
|
7303
7558
|
continue;
|
|
7304
7559
|
}
|
|
7305
7560
|
if (propertyNames.length === 0 || propertyNames.includes(key)) {
|
|
7306
|
-
if (needsStorageSavePipeline(dataTypeByPropertyName.get(key), value)) {
|
|
7561
|
+
if (needsStorageSavePipeline(dataTypeByPropertyName.get(key), value, storageTypeByPropertyName.get(key))) {
|
|
7307
7562
|
pipelineValues.push([key, value]);
|
|
7308
7563
|
continue;
|
|
7309
7564
|
}
|
|
@@ -7435,7 +7690,7 @@ class Item {
|
|
|
7435
7690
|
return proxiedInstance;
|
|
7436
7691
|
}
|
|
7437
7692
|
/**
|
|
7438
|
-
* Run each File/Image/Html initial value through its ItemProperty save pipeline (sequentially, to
|
|
7693
|
+
* Run each File/Image/Html/ItemStorage initial value through its ItemProperty save pipeline (sequentially, to
|
|
7439
7694
|
* avoid SQLite write contention). Rejects on the first failure; the item itself has been created.
|
|
7440
7695
|
*/
|
|
7441
7696
|
static async savePipelineValues(item, pipelineValues, timeout) {
|
|
@@ -7559,7 +7814,7 @@ class Item {
|
|
|
7559
7814
|
modelName,
|
|
7560
7815
|
});
|
|
7561
7816
|
}
|
|
7562
|
-
static async find({ modelName, seedLocalId, seedUid, waitForReady = true, readyTimeout =
|
|
7817
|
+
static async find({ modelName, seedLocalId, seedUid, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, }) {
|
|
7563
7818
|
if (!seedLocalId && !seedUid) {
|
|
7564
7819
|
return undefined;
|
|
7565
7820
|
}
|
|
@@ -7585,7 +7840,7 @@ class Item {
|
|
|
7585
7840
|
}
|
|
7586
7841
|
}
|
|
7587
7842
|
static async all(modelName, deleted, options) {
|
|
7588
|
-
const { waitForReady = false, readyTimeout =
|
|
7843
|
+
const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, includeEas = false, addressFilter, modelFileId, schemaName, } = options ?? {};
|
|
7589
7844
|
const itemsData = await getItemsData({ modelName, modelFileId, schemaName, deleted, includeEas, addressFilter });
|
|
7590
7845
|
const itemInstances = [];
|
|
7591
7846
|
for (const itemData of itemsData) {
|
|
@@ -7609,9 +7864,9 @@ class Item {
|
|
|
7609
7864
|
if (!appDb || Item.instanceCache.size === 0) {
|
|
7610
7865
|
return;
|
|
7611
7866
|
}
|
|
7612
|
-
const
|
|
7613
|
-
const
|
|
7614
|
-
const { metadata } =
|
|
7867
|
+
const _mod_30 = await import('./index-AVFTVp1m.js');
|
|
7868
|
+
const _ns_30 = _mod_30.s;
|
|
7869
|
+
const { metadata } = _ns_30;
|
|
7615
7870
|
const { eq, and } = await import('drizzle-orm');
|
|
7616
7871
|
const dedupedInstances = new Map();
|
|
7617
7872
|
for (const entry of Item.instanceCache.values()) {
|
|
@@ -7770,8 +8025,27 @@ class Item {
|
|
|
7770
8025
|
});
|
|
7771
8026
|
state.definedPropertyNames.add(propertyName);
|
|
7772
8027
|
}
|
|
7773
|
-
|
|
7774
|
-
|
|
8028
|
+
/** Same as `item.publish(options)`; requires @seedprotocol/publish. */
|
|
8029
|
+
/**
|
|
8030
|
+
* Set `publisher` on loaded Items for these seeds (after claimUnpublishedDrafts stamped
|
|
8031
|
+
* their rows). Items that aren't loaded read it from the DB when they load.
|
|
8032
|
+
*/
|
|
8033
|
+
static setPublisherForCachedSeeds(seedLocalIds, publisher) {
|
|
8034
|
+
const normalized = normalizePublisher(publisher);
|
|
8035
|
+
if (!normalized)
|
|
8036
|
+
return;
|
|
8037
|
+
for (const seedLocalId of seedLocalIds) {
|
|
8038
|
+
const item = Item.getById(seedLocalId);
|
|
8039
|
+
if (!item)
|
|
8040
|
+
continue;
|
|
8041
|
+
const status = item.getService().getSnapshot().status;
|
|
8042
|
+
if (status === 'stopped' || status === 'done')
|
|
8043
|
+
continue;
|
|
8044
|
+
item.getService().send({ type: 'updateContext', publisher: normalized });
|
|
8045
|
+
}
|
|
8046
|
+
}
|
|
8047
|
+
static async publish(item, options) {
|
|
8048
|
+
await item.publish(options);
|
|
7775
8049
|
}
|
|
7776
8050
|
get serviceContext() {
|
|
7777
8051
|
const snapshot = this._service.getSnapshot();
|
|
@@ -8068,9 +8342,9 @@ class Item {
|
|
|
8068
8342
|
itemActor.send(event);
|
|
8069
8343
|
};
|
|
8070
8344
|
try {
|
|
8071
|
-
const
|
|
8072
|
-
const
|
|
8073
|
-
const seedSchemaMod =
|
|
8345
|
+
const _mod_31 = await import('./index-AVFTVp1m.js');
|
|
8346
|
+
const _ns_31 = _mod_31.s;
|
|
8347
|
+
const seedSchemaMod = _ns_31;
|
|
8074
8348
|
const { seeds, versions, metadata } = seedSchemaMod;
|
|
8075
8349
|
const drizzleMod = await import('drizzle-orm');
|
|
8076
8350
|
const { eq, and } = drizzleMod;
|
|
@@ -8161,7 +8435,7 @@ class Item {
|
|
|
8161
8435
|
// Watch the seed row by local id: its uid changes when an unpublished item is published
|
|
8162
8436
|
// again (a new seed attestation), and a watch on the uid would stop seeing the row.
|
|
8163
8437
|
const seeds$ = BaseDb.liveQuery((sql) => sql `
|
|
8164
|
-
SELECT local_id as localId, uid, schema_uid as schemaUid, revoked_at as revokedAt
|
|
8438
|
+
SELECT local_id as localId, uid, schema_uid as schemaUid, revoked_at as revokedAt, publisher
|
|
8165
8439
|
FROM seeds
|
|
8166
8440
|
WHERE local_id = ${watchedSeedLocalId}
|
|
8167
8441
|
`);
|
|
@@ -8211,6 +8485,8 @@ class Item {
|
|
|
8211
8485
|
seedLocalId: seedRow.localId,
|
|
8212
8486
|
schemaUid: seedRow.schemaUid || undefined,
|
|
8213
8487
|
revokedAt: seedRow.revokedAt ?? undefined,
|
|
8488
|
+
// claimUnpublishedDrafts (here or in another tab) stamps drafts' publisher.
|
|
8489
|
+
...(seedRow.publisher ? { publisher: seedRow.publisher } : {}),
|
|
8214
8490
|
});
|
|
8215
8491
|
},
|
|
8216
8492
|
error: (error) => {
|
|
@@ -8421,5 +8697,5 @@ var Item$1 = /*#__PURE__*/Object.freeze({
|
|
|
8421
8697
|
Item: Item
|
|
8422
8698
|
});
|
|
8423
8699
|
|
|
8424
|
-
export {
|
|
8425
|
-
//# sourceMappingURL=Item-
|
|
8700
|
+
export { getInvariantSafePropertyDescriptor as $, getGetPublisherForNewSeeds as A, getMetadataLatest as B, ClientManagerState as C, DEFAULT_READY_TIMEOUT_MS as D, getPublishExecutor as E, getRevokeExecutor as F, getUploadExecutor as G, getVersionData$1 as H, Item as I, isLocalUnsealedDraft as J, isSeedRowOwned as K, localUnsealedDraftSql as L, METADATA_LATEST_FIRST_ORDER_SQL as M, ownedPublisherSql as N, OwnershipError as O, PUBLISH_NOT_CONFIGURED_MESSAGE as P, ownedSeedsSql as Q, pickLatestMetadataRowPerProperty as R, placeholderUidSql as S, propertyMachine as T, publisherInAddressListSql as U, publisherIsInOwnedSet as V, setAdditionalSyncAddresses as W, setGetPublisherForNewSeeds as X, setPublishExecutor as Y, setRevokeExecutor as Z, setUploadExecutor as _, chunkValues as a, clearDestroySubscriptions as a0, unloadEntity as a1, ClientManagerEvents as a2, withLockedItemStorageRow as a3, getItemStorageFilePath as a4, writeItemStorageFile as a5, resolvePublisherFromSeedRow as a6, getPropertyData$1 as a7, Item$1 as a8, rowsPerInsert as b, compareMetadataRowsLatestFirst as c, getGetAdditionalSyncAddresses as d, ItemProperty as e, ItemPropertySaveValidationError as f, getItemData as g, assertItemOwned as h, isItemOwned as i, getEasSchemaUidForModel as j, getLatestPublishedVersionRow as k, listRelationEasPropertyName as l, isVersionRevoked as m, waitForEntityIdle as n, createReactiveProxy as o, parseListPropertyValueFromStorage as p, findEntity as q, resolveStorageNameToSchemaName as r, selectInBatches as s, forceRemoveFromCaches as t, runDestroyLifecycle as u, isPublishedMetadataRow as v, writeInBatches as w, MachineIds as x, createNewItem as y, getEasSchemaForItemProperty as z };
|
|
8701
|
+
//# sourceMappingURL=Item-DBFchXpC.js.map
|