@seedprotocol/sdk 0.6.10 → 0.7.1
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-B6CKqoKw.js → BasePathResolver-DRT09oVv.js} +36 -2
- package/dist/BasePathResolver-DRT09oVv.js.map +1 -0
- package/dist/ClientManager-DngaZdw6.js +4763 -0
- package/dist/ClientManager-DngaZdw6.js.map +1 -0
- package/dist/{ClientManager-ChcmUL47.js → Item-ZUAmf943.js} +1175 -5903
- package/dist/Item-ZUAmf943.js.map +1 -0
- package/dist/{ModelProperty-D79uV42p.js → ModelProperty-6llK4MTH.js} +326 -109
- package/dist/ModelProperty-6llK4MTH.js.map +1 -0
- package/dist/{Schema-a8uO-hIZ.js → Schema-D-Ud-XYw.js} +164 -885
- package/dist/Schema-D-Ud-XYw.js.map +1 -0
- package/dist/{SchemaValidationService-Y49vqast.js → SchemaValidationService-IoS7JquP.js} +26 -18
- package/dist/SchemaValidationService-IoS7JquP.js.map +1 -0
- package/dist/{backfillMetadataPropertyIds-CBsf7LnU.js → backfillMetadataPropertyIds-BlVeE7w7.js} +11 -6
- package/dist/backfillMetadataPropertyIds-BlVeE7w7.js.map +1 -0
- package/dist/cjs/{ModelProperty-D9FGaGuE.js → ModelProperty-Dv7AQfmQ.js} +297 -89
- package/dist/cjs/ModelProperty-Dv7AQfmQ.js.map +1 -0
- package/dist/cjs/{Schema-BiJIPLEL.js → Schema-BHVp1g-M.js} +136 -868
- package/dist/cjs/Schema-BHVp1g-M.js.map +1 -0
- package/dist/cjs/{SchemaValidationService-DtYs_CNY.js → SchemaValidationService-BSU9knjf.js} +18 -11
- package/dist/cjs/SchemaValidationService-BSU9knjf.js.map +1 -0
- package/dist/cjs/{backfillMetadataPropertyIds-2XaN3b9S.js → backfillMetadataPropertyIds-WIovQ_d8.js} +8 -3
- package/dist/cjs/backfillMetadataPropertyIds-WIovQ_d8.js.map +1 -0
- package/dist/cjs/{eas-CMNppmGE.js → eas-CUYXdr2t.js} +4 -4
- package/dist/cjs/{eas-CMNppmGE.js.map → eas-CUYXdr2t.js.map} +1 -1
- package/dist/cjs/{getItem-B6jEINjW.js → getItem-z1tHu0hu.js} +2 -2
- package/dist/cjs/{getItem-B6jEINjW.js.map → getItem-z1tHu0hu.js.map} +1 -1
- package/dist/cjs/getLatestVersionRow-CcaabxIW.js +59 -0
- package/dist/cjs/getLatestVersionRow-CcaabxIW.js.map +1 -0
- package/dist/cjs/{getPublishPayload-D5DhLGvN.js → getPublishPayload-CEP_e-Kv.js} +283 -138
- package/dist/cjs/getPublishPayload-CEP_e-Kv.js.map +1 -0
- package/dist/cjs/{getPublishUploads-DMhCCKYF.js → getPublishUploads-Ctn5k1k6.js} +65 -19
- package/dist/cjs/getPublishUploads-Ctn5k1k6.js.map +1 -0
- package/dist/cjs/{index-CSNtEnbF.js → index-Cvvt0-5B.js} +2698 -1725
- package/dist/cjs/index-Cvvt0-5B.js.map +1 -0
- package/dist/cjs/{index-DPp9rdRL.js → index-DfGhF1dc.js} +3 -3
- package/dist/cjs/index-DfGhF1dc.js.map +1 -0
- package/dist/cjs/{property-DlKiAWt4.js → property-DbEPQ1m9.js} +40 -35
- package/dist/cjs/property-DbEPQ1m9.js.map +1 -0
- package/dist/cjs/publishDraftGraph-C38gf302.js +403 -0
- package/dist/cjs/publishDraftGraph-C38gf302.js.map +1 -0
- package/dist/cjs/resetAmbiguousLegacyItemData-CfMhRHwK.js +116 -0
- package/dist/cjs/resetAmbiguousLegacyItemData-CfMhRHwK.js.map +1 -0
- package/dist/cjs/resolveModelForSyncedSeed-CNYaLOir.js +49 -0
- package/dist/cjs/resolveModelForSyncedSeed-CNYaLOir.js.map +1 -0
- package/dist/cjs/syncDbWithEas-d1iOdTTI.js +886 -0
- package/dist/cjs/syncDbWithEas-d1iOdTTI.js.map +1 -0
- package/dist/{configurePlatform-CE0Vew17.js → configurePlatform-CZpjyuCo.js} +4 -4
- package/dist/{configurePlatform-CE0Vew17.js.map → configurePlatform-CZpjyuCo.js.map} +1 -1
- package/dist/db/drizzle/0015_add_model_file_id_to_seeds.sql +11 -0
- package/dist/db/drizzle/0016_add_revoked_at_to_metadata.sql +1 -0
- package/dist/db/drizzle/0017_add_revoked_at_to_versions.sql +1 -0
- package/dist/db/drizzle/0018_add_storage_settings_to_properties.sql +53 -0
- package/dist/db/drizzle/0019_add_derived_from_uid_to_metadata.sql +35 -0
- package/dist/db/drizzle/meta/0011_snapshot.json +1182 -0
- package/dist/db/drizzle/meta/0012_snapshot.json +1244 -0
- package/dist/db/drizzle/meta/0013_snapshot.json +63 -1
- package/dist/db/drizzle/meta/0014_snapshot.json +62 -0
- package/dist/db/drizzle/meta/0015_snapshot.json +1338 -0
- package/dist/db/drizzle/meta/0016_snapshot.json +1345 -0
- package/dist/db/drizzle/meta/0017_snapshot.json +1352 -0
- package/dist/db/drizzle/meta/0018_snapshot.json +1373 -0
- package/dist/db/drizzle/meta/0019_snapshot.json +1380 -0
- package/dist/db/drizzle/meta/_journal.json +35 -0
- package/dist/{db-WbrzEf7c.js → db-Lw0KVZmc.js} +546 -106
- package/dist/db-Lw0KVZmc.js.map +1 -0
- package/dist/{eas-CfYCu4IX.js → eas-CQ-Smzk2.js} +7 -7
- package/dist/eas-CQ-Smzk2.js.map +1 -0
- package/dist/errors-CrBxGWah.js +17 -0
- package/dist/errors-CrBxGWah.js.map +1 -0
- package/dist/{getItem-Br-bGNFO.js → getItem-CSfSok9f.js} +8 -10
- package/dist/{getItem-Br-bGNFO.js.map → getItem-CSfSok9f.js.map} +1 -1
- package/dist/getLatestVersionRow-72Atl9vB.js +46 -0
- package/dist/getLatestVersionRow-72Atl9vB.js.map +1 -0
- package/dist/{getPublishPayload-BIrTVUxb.js → getPublishPayload-76_KfB5Y.js} +297 -154
- package/dist/getPublishPayload-76_KfB5Y.js.map +1 -0
- package/dist/{getPublishUploads-C6cDeZdz.js → getPublishUploads-CqgMBD8f.js} +68 -21
- package/dist/getPublishUploads-CqgMBD8f.js.map +1 -0
- package/dist/{index-Djd3667v.js → index-5b3JsS55.js} +2 -2
- package/dist/index-5b3JsS55.js.map +1 -0
- package/dist/{index-ClSv5pTA.js → index-BpgD305l.js} +12 -11
- package/dist/index-BpgD305l.js.map +1 -0
- package/dist/{index-HRHkbVQd.js → index-Y-yYyRBf.js} +530 -196
- package/dist/index-Y-yYyRBf.js.map +1 -0
- package/dist/index.browser-DaTzn79x.js +4139 -0
- package/dist/index.browser-DaTzn79x.js.map +1 -0
- package/dist/{index.node-DBtQkEfz.js → index.node-NYKqFOoe.js} +9 -4
- package/dist/index.node-NYKqFOoe.js.map +1 -0
- package/dist/main.cjs +1 -1
- package/dist/main.js +886 -560
- package/dist/main.js.map +1 -1
- package/dist/node.js +19 -15
- package/dist/node.js.map +1 -1
- package/dist/platform.browser.js +18 -3719
- package/dist/platform.browser.js.map +1 -1
- package/dist/platform.node.js +3 -3
- package/dist/{property-CQjuZ4JW.js → property-ByaiSyUK.js} +53 -48
- package/dist/property-ByaiSyUK.js.map +1 -0
- package/dist/publishDraftGraph-BRm6Pq3Q.js +405 -0
- package/dist/publishDraftGraph-BRm6Pq3Q.js.map +1 -0
- package/dist/resetAmbiguousLegacyItemData-B4dX6ZA1.js +88 -0
- package/dist/resetAmbiguousLegacyItemData-B4dX6ZA1.js.map +1 -0
- package/dist/resolveModelForSyncedSeed-B0tco3zG.js +46 -0
- package/dist/resolveModelForSyncedSeed-B0tco3zG.js.map +1 -0
- package/dist/seedSchema/MetadataSchema.ts +9 -0
- package/dist/seedSchema/ModelSchema.ts +5 -0
- package/dist/seedSchema/SeedSchema.ts +3 -0
- package/dist/seedSchema/VersionSchema.ts +5 -0
- package/dist/src/Item/Item.d.ts +21 -0
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/Item/service/actors/loadOrCreateItem.d.ts.map +1 -1
- package/dist/src/Item/service/actors/waitForDb.d.ts.map +1 -1
- package/dist/src/Item/service/itemMachineSingle.d.ts +3 -29
- package/dist/src/Item/service/itemMachineSingle.d.ts.map +1 -1
- package/dist/src/ItemProperty/ItemProperty.d.ts +13 -4
- package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/loadOrCreateProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveFile.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveHtml.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveImage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/propertyMachine.d.ts +4 -9
- package/dist/src/ItemProperty/service/propertyMachine.d.ts.map +1 -1
- package/dist/src/Model/Model.d.ts +52 -2
- package/dist/src/Model/Model.d.ts.map +1 -1
- package/dist/src/Model/errors.d.ts +10 -0
- package/dist/src/Model/errors.d.ts.map +1 -0
- package/dist/src/Model/service/actors/createModelProperties.d.ts.map +1 -1
- package/dist/src/Model/service/actors/loadOrCreateModel.d.ts.map +1 -1
- package/dist/src/Model/service/actors/validateModel.d.ts.map +1 -1
- package/dist/src/Model/service/modelMachine.d.ts +0 -8
- package/dist/src/Model/service/modelMachine.d.ts.map +1 -1
- package/dist/src/ModelProperty/ModelProperty.d.ts +42 -2
- package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
- package/dist/src/ModelProperty/service/actors/compareAndMarkDraft.d.ts.map +1 -1
- package/dist/src/ModelProperty/service/actors/saveToSchema.d.ts.map +1 -1
- package/dist/src/ModelProperty/service/actors/validateProperty.d.ts.map +1 -1
- package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts +2 -9
- package/dist/src/ModelProperty/service/modelPropertyMachine.d.ts.map +1 -1
- package/dist/src/Schema/Schema.d.ts +8 -2
- package/dist/src/Schema/Schema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/checkExistingSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/createModelInstances.d.ts.map +1 -1
- package/dist/src/Schema/service/actors/loadOrCreateSchema.d.ts.map +1 -1
- package/dist/src/Schema/service/schemaMachine.d.ts +1 -217
- package/dist/src/Schema/service/schemaMachine.d.ts.map +1 -1
- package/dist/src/Schema/service/validation/SchemaValidationService.d.ts.map +1 -1
- package/dist/src/browser/db/Db.d.ts +3 -0
- package/dist/src/browser/db/Db.d.ts.map +1 -1
- package/dist/src/browser/db/drizzleFiles.d.ts +7 -2
- package/dist/src/browser/db/drizzleFiles.d.ts.map +1 -1
- package/dist/src/browser/db/embeddedMigrations.d.ts +11 -2
- package/dist/src/browser/db/embeddedMigrations.d.ts.map +1 -1
- package/dist/src/browser/db/sqliteBusyRetry.d.ts +14 -0
- package/dist/src/browser/db/sqliteBusyRetry.d.ts.map +1 -0
- package/dist/src/browser/helpers/FileManager.d.ts +1 -0
- package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/browser/helpers/QueryClient.d.ts +1 -0
- package/dist/src/browser/helpers/QueryClient.d.ts.map +1 -1
- package/dist/src/browser/helpers/opfsErrors.d.ts +2 -0
- package/dist/src/browser/helpers/opfsErrors.d.ts.map +1 -0
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts +47 -0
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -0
- package/dist/src/browser/workers/FileDownloader.d.ts.map +1 -1
- package/dist/src/browser/workers/ImageResizer.d.ts.map +1 -1
- package/dist/src/browser/workers/filesDownload.d.ts.map +1 -1
- package/dist/src/browser/workers/imageResize.d.ts.map +1 -1
- package/dist/src/client/ClientManager.d.ts.map +1 -1
- package/dist/src/client/actors/addModelsToDb.d.ts +14 -0
- package/dist/src/client/actors/addModelsToDb.d.ts.map +1 -1
- 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 +11 -0
- package/dist/src/client/actors/saveConfig.d.ts.map +1 -1
- package/dist/src/client/constants.d.ts +0 -8
- package/dist/src/client/constants.d.ts.map +1 -1
- package/dist/src/db/backfillMetadataPropertyIds.d.ts.map +1 -1
- package/dist/src/db/configs/{dev.schema.config.d.ts → migrations.config.d.ts} +1 -1
- package/dist/src/db/configs/migrations.config.d.ts.map +1 -0
- package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts +1 -1
- package/dist/src/db/read/batchLatestPublishedVersionBySeedLocalIds.d.ts.map +1 -1
- package/dist/src/db/read/getItemData.d.ts.map +1 -1
- package/dist/src/db/read/getItemProperties.d.ts.map +1 -1
- package/dist/src/db/read/getItems.d.ts +7 -2
- package/dist/src/db/read/getItems.d.ts.map +1 -1
- package/dist/src/db/read/getLatestPublishedVersionRow.d.ts +2 -1
- package/dist/src/db/read/getLatestPublishedVersionRow.d.ts.map +1 -1
- package/dist/src/db/read/getLatestVersionRow.d.ts +13 -0
- package/dist/src/db/read/getLatestVersionRow.d.ts.map +1 -0
- package/dist/src/db/read/getModelSchemas.d.ts.map +1 -1
- package/dist/src/db/read/getPropertyData.d.ts.map +1 -1
- package/dist/src/db/read/getPublishPayload.d.ts +18 -11
- package/dist/src/db/read/getPublishPayload.d.ts.map +1 -1
- package/dist/src/db/read/getPublishPendingDiff.d.ts +2 -1
- package/dist/src/db/read/getPublishPendingDiff.d.ts.map +1 -1
- package/dist/src/db/read/getPublishUploads.d.ts +5 -0
- package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
- package/dist/src/db/read/getSchemaUidForModel.d.ts.map +1 -1
- package/dist/src/db/read/getSeedPublishState.d.ts +8 -2
- package/dist/src/db/read/getSeedPublishState.d.ts.map +1 -1
- package/dist/src/db/read/isSeedRevoked.d.ts +7 -0
- package/dist/src/db/read/isSeedRevoked.d.ts.map +1 -0
- package/dist/src/db/read/publishDraftGraph.d.ts +57 -0
- package/dist/src/db/read/publishDraftGraph.d.ts.map +1 -0
- package/dist/src/db/read/publishErrors.d.ts +37 -0
- package/dist/src/db/read/publishErrors.d.ts.map +1 -0
- package/dist/src/db/read/resolveModelForSyncedSeed.d.ts +39 -0
- package/dist/src/db/read/resolveModelForSyncedSeed.d.ts.map +1 -0
- package/dist/src/db/read/resolveModelRecord.d.ts +69 -0
- package/dist/src/db/read/resolveModelRecord.d.ts.map +1 -0
- package/dist/src/db/read/resolveRelatedSeedRef.d.ts +34 -0
- package/dist/src/db/read/resolveRelatedSeedRef.d.ts.map +1 -0
- package/dist/src/db/read/subqueries/liveVersion.d.ts +12 -0
- package/dist/src/db/read/subqueries/liveVersion.d.ts.map +1 -0
- package/dist/src/db/read/subqueries/metadataLatest.d.ts +4 -0
- package/dist/src/db/read/subqueries/metadataLatest.d.ts.map +1 -1
- package/dist/src/db/read/subqueries/versionData.d.ts +7 -2
- package/dist/src/db/read/subqueries/versionData.d.ts.map +1 -1
- package/dist/src/db/read/summarizePublishWork.d.ts +10 -2
- package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
- package/dist/src/db/resetAmbiguousLegacyItemData.d.ts +17 -0
- package/dist/src/db/resetAmbiguousLegacyItemData.d.ts.map +1 -0
- package/dist/src/db/sqlParamBatches.d.ts +27 -0
- package/dist/src/db/sqlParamBatches.d.ts.map +1 -0
- package/dist/src/db/write/addExcludedTransactions.d.ts +7 -0
- package/dist/src/db/write/addExcludedTransactions.d.ts.map +1 -0
- package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts +6 -0
- package/dist/src/db/write/applyPropertyAttestationUidsFromPublish.d.ts.map +1 -1
- package/dist/src/db/write/createMetadata.d.ts +2 -0
- package/dist/src/db/write/createMetadata.d.ts.map +1 -1
- package/dist/src/db/write/createNewItem.d.ts +3 -1
- package/dist/src/db/write/createNewItem.d.ts.map +1 -1
- package/dist/src/db/write/createSeed.d.ts +2 -1
- package/dist/src/db/write/createSeed.d.ts.map +1 -1
- package/dist/src/db/write/createSeeds.d.ts +1 -1
- package/dist/src/db/write/createSeeds.d.ts.map +1 -1
- package/dist/src/db/write/linkModelToSchema.d.ts +12 -0
- package/dist/src/db/write/linkModelToSchema.d.ts.map +1 -0
- package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
- package/dist/src/db/write/updateMetadata.d.ts.map +1 -1
- package/dist/src/db/write/updateSeedRevokedAt.d.ts +11 -1
- package/dist/src/db/write/updateSeedRevokedAt.d.ts.map +1 -1
- package/dist/src/db/write/updateSeedUid.d.ts.map +1 -1
- package/dist/src/db/write/updateVersionUid.d.ts +2 -1
- package/dist/src/db/write/updateVersionUid.d.ts.map +1 -1
- package/dist/src/events/files/download.d.ts.map +1 -1
- package/dist/src/events/item/easSyncManager.d.ts +2 -0
- package/dist/src/events/item/easSyncManager.d.ts.map +1 -1
- package/dist/src/events/item/index.d.ts.map +1 -1
- package/dist/src/events/item/syncDbWithEas.d.ts +16 -0
- package/dist/src/events/item/syncDbWithEas.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts +1 -0
- package/dist/src/helpers/FileManager/BaseFileManager.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/IFileManager.d.ts +5 -0
- package/dist/src/helpers/FileManager/IFileManager.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/errors.d.ts +10 -0
- package/dist/src/helpers/FileManager/errors.d.ts.map +1 -0
- package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts +21 -3
- package/dist/src/helpers/compareMetadataRowsLatestFirst.d.ts.map +1 -1
- package/dist/src/helpers/constants.d.ts +9 -0
- package/dist/src/helpers/constants.d.ts.map +1 -1
- package/dist/src/helpers/crypto.d.ts +5 -0
- package/dist/src/helpers/crypto.d.ts.map +1 -1
- package/dist/src/helpers/db.d.ts +25 -5
- package/dist/src/helpers/db.d.ts.map +1 -1
- package/dist/src/helpers/easPropertyCanonical.d.ts +1 -1
- package/dist/src/helpers/easPropertyCanonical.d.ts.map +1 -1
- package/dist/src/helpers/entity/entityCommon.d.ts +10 -0
- package/dist/src/helpers/entity/entityCommon.d.ts.map +1 -1
- package/dist/src/helpers/entity/entityDestroy.d.ts +1 -1
- package/dist/src/helpers/entity/entityDestroy.d.ts.map +1 -1
- package/dist/src/helpers/entity/entityLiveQuery.d.ts +5 -0
- package/dist/src/helpers/entity/entityLiveQuery.d.ts.map +1 -1
- package/dist/src/helpers/entity/evictionEpoch.d.ts +18 -0
- package/dist/src/helpers/entity/evictionEpoch.d.ts.map +1 -0
- package/dist/src/helpers/file/fetchAll/actors.d.ts.map +1 -1
- package/dist/src/helpers/getSegmentedItemProperties.d.ts.map +1 -1
- package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts +31 -3
- package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts.map +1 -1
- package/dist/src/helpers/isPublishedMetadataRow.d.ts +10 -0
- package/dist/src/helpers/isPublishedMetadataRow.d.ts.map +1 -0
- package/dist/src/helpers/ownership.d.ts.map +1 -1
- package/dist/src/helpers/property.d.ts +6 -1
- package/dist/src/helpers/property.d.ts.map +1 -1
- package/dist/src/helpers/schema.d.ts +14 -4
- package/dist/src/helpers/schema.d.ts.map +1 -1
- package/dist/src/helpers/tabCoordinator.d.ts +45 -0
- package/dist/src/helpers/tabCoordinator.d.ts.map +1 -0
- package/dist/src/helpers/tabEvents.d.ts +27 -0
- package/dist/src/helpers/tabEvents.d.ts.map +1 -0
- package/dist/src/helpers/tabLocks.d.ts +28 -0
- package/dist/src/helpers/tabLocks.d.ts.map +1 -0
- package/dist/src/helpers/updateSchema.d.ts.map +1 -1
- package/dist/src/imports/json.d.ts.map +1 -1
- package/dist/src/imports/markdown.d.ts.map +1 -1
- package/dist/src/index.d.ts +13 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/node/db/Db.d.ts.map +1 -1
- package/dist/src/node/helpers/FileManager.d.ts +2 -0
- package/dist/src/node/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/query/createLocalQueryDataSource.d.ts +4 -0
- package/dist/src/query/createLocalQueryDataSource.d.ts.map +1 -1
- package/dist/src/seedSchema/MetadataSchema.d.ts +36 -0
- package/dist/src/seedSchema/MetadataSchema.d.ts.map +1 -1
- package/dist/src/seedSchema/ModelSchema.d.ts +57 -0
- package/dist/src/seedSchema/ModelSchema.d.ts.map +1 -1
- package/dist/src/seedSchema/SeedSchema.d.ts +19 -0
- package/dist/src/seedSchema/SeedSchema.d.ts.map +1 -1
- package/dist/src/seedSchema/VersionSchema.d.ts +17 -0
- package/dist/src/seedSchema/VersionSchema.d.ts.map +1 -1
- package/dist/src/services/write/actors/validateEntity.d.ts.map +1 -1
- package/dist/src/services/write/actors/writeToDatabase.d.ts +5 -0
- package/dist/src/services/write/actors/writeToDatabase.d.ts.map +1 -1
- package/dist/src/services/write/writeProcessMachine.d.ts.map +1 -1
- package/dist/src/stores/eas.d.ts +1 -1
- package/dist/src/stores/eas.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/item.d.ts +19 -11
- package/dist/src/types/item.d.ts.map +1 -1
- package/dist/src/types/property.d.ts +3 -2
- package/dist/src/types/property.d.ts.map +1 -1
- package/dist/syncDbWithEas-BPap9Sru.js +855 -0
- package/dist/syncDbWithEas-BPap9Sru.js.map +1 -0
- package/dist/{index-280bL-n4.js → tabEvents-C6NXS6Jl.js} +231 -68
- package/dist/tabEvents-C6NXS6Jl.js.map +1 -0
- package/dist/tolerantWebAccess-NBQ1NB4i.js +160 -0
- package/dist/tolerantWebAccess-NBQ1NB4i.js.map +1 -0
- package/dist/updateSeedRevokedAt-CYwgVNlM.js +32 -0
- package/dist/updateSeedRevokedAt-CYwgVNlM.js.map +1 -0
- package/package.json +8 -10
- package/dist/BasePathResolver-B6CKqoKw.js.map +0 -1
- package/dist/ClientManager-ChcmUL47.js.map +0 -1
- package/dist/ModelProperty-D79uV42p.js.map +0 -1
- package/dist/Schema-a8uO-hIZ.js.map +0 -1
- package/dist/SchemaValidationService-Y49vqast.js.map +0 -1
- package/dist/backfillMetadataPropertyIds-CBsf7LnU.js.map +0 -1
- package/dist/cjs/ModelProperty-D9FGaGuE.js.map +0 -1
- package/dist/cjs/Schema-BiJIPLEL.js.map +0 -1
- package/dist/cjs/SchemaValidationService-DtYs_CNY.js.map +0 -1
- package/dist/cjs/backfillMetadataPropertyIds-2XaN3b9S.js.map +0 -1
- package/dist/cjs/getPublishPayload-D5DhLGvN.js.map +0 -1
- package/dist/cjs/getPublishUploads-DMhCCKYF.js.map +0 -1
- package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js +0 -148
- package/dist/cjs/getSegmentedItemProperties-CU8rtBAo.js.map +0 -1
- package/dist/cjs/index-CSNtEnbF.js.map +0 -1
- package/dist/cjs/index-DPp9rdRL.js.map +0 -1
- package/dist/cjs/property-DlKiAWt4.js.map +0 -1
- package/dist/cjs/syncDbWithEas-C6n34o_Q.js +0 -606
- package/dist/cjs/syncDbWithEas-C6n34o_Q.js.map +0 -1
- package/dist/db-WbrzEf7c.js.map +0 -1
- package/dist/eas-CfYCu4IX.js.map +0 -1
- package/dist/getPublishPayload-BIrTVUxb.js.map +0 -1
- package/dist/getPublishUploads-C6cDeZdz.js.map +0 -1
- package/dist/getSegmentedItemProperties-BmKE71vU.js +0 -148
- package/dist/getSegmentedItemProperties-BmKE71vU.js.map +0 -1
- package/dist/index-280bL-n4.js.map +0 -1
- package/dist/index-ClSv5pTA.js.map +0 -1
- package/dist/index-Djd3667v.js.map +0 -1
- package/dist/index-HRHkbVQd.js.map +0 -1
- package/dist/index.node-DBtQkEfz.js.map +0 -1
- package/dist/property-CQjuZ4JW.js.map +0 -1
- package/dist/src/Item/service/actors/fetchDataFromEas.d.ts +0 -4
- package/dist/src/Item/service/actors/fetchDataFromEas.d.ts.map +0 -1
- package/dist/src/Item/service/actors/hydrateExistingItem.d.ts +0 -4
- package/dist/src/Item/service/actors/hydrateExistingItem.d.ts.map +0 -1
- package/dist/src/Item/service/actors/hydrateNewItem.d.ts +0 -4
- package/dist/src/Item/service/actors/hydrateNewItem.d.ts.map +0 -1
- package/dist/src/Item/service/actors/initialize.d.ts +0 -4
- package/dist/src/Item/service/actors/initialize.d.ts.map +0 -1
- package/dist/src/Item/service/actors/reload.d.ts +0 -5
- package/dist/src/Item/service/actors/reload.d.ts.map +0 -1
- package/dist/src/Item/service/actors/saveDataToDb.d.ts +0 -4
- package/dist/src/Item/service/actors/saveDataToDb.d.ts.map +0 -1
- package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts +0 -5
- package/dist/src/ItemProperty/service/actors/resolveRemoteStorage.d.ts.map +0 -1
- package/dist/src/Schema/service/addModelsMachine.d.ts +0 -123
- package/dist/src/Schema/service/addModelsMachine.d.ts.map +0 -1
- package/dist/src/browser/helpers/index.d.ts +0 -4
- package/dist/src/browser/helpers/index.d.ts.map +0 -1
- package/dist/src/db/configs/dev.schema.config.d.ts.map +0 -1
- package/dist/src/helpers/file/download/actors.d.ts +0 -17
- package/dist/src/helpers/file/download/actors.d.ts.map +0 -1
- package/dist/src/helpers/file/download/index.d.ts +0 -70
- package/dist/src/helpers/file/download/index.d.ts.map +0 -1
- package/dist/src/services/publish/actors/createPublishAttempt.d.ts +0 -4
- package/dist/src/services/publish/actors/createPublishAttempt.d.ts.map +0 -1
- package/dist/src/services/publish/actors/preparePublishRequestData.d.ts +0 -4
- package/dist/src/services/publish/actors/preparePublishRequestData.d.ts.map +0 -1
- package/dist/src/services/publish/actors/upload.d.ts +0 -4
- package/dist/src/services/publish/actors/upload.d.ts.map +0 -1
- package/dist/src/services/publish/actors/validateItemData.d.ts +0 -4
- package/dist/src/services/publish/actors/validateItemData.d.ts.map +0 -1
- package/dist/src/services/publish/publishMachine.d.ts +0 -32
- package/dist/src/services/publish/publishMachine.d.ts.map +0 -1
- package/dist/syncDbWithEas-CuARXfyN.js +0 -598
- package/dist/syncDbWithEas-CuARXfyN.js.map +0 -1
- package/dist/updateSeedRevokedAt-CBcLfHWs.js +0 -22
- package/dist/updateSeedRevokedAt-CBcLfHWs.js.map +0 -1
package/dist/main.js
CHANGED
|
@@ -1,50 +1,55 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
|
-
export { M as Model } from './index-
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
5
|
-
export { getPropertySchema } from './property-
|
|
6
|
-
import { n as normalizeRelationPropertyValue, r as resolveSeedIdsFromRefString, b as getArweaveUrlForTransaction } from './
|
|
7
|
-
export { c as classifyMediaRef, d as closestImageSize, f as ensureImageLocal,
|
|
8
|
-
import {
|
|
9
|
-
export {
|
|
10
|
-
import {
|
|
11
|
-
export {
|
|
12
|
-
import {
|
|
2
|
+
export { M as Model } from './index-Y-yYyRBf.js';
|
|
3
|
+
import { s as normalizePublisher, k as isDataType, M as ModelPropertyDataTypes, n as normalizeDataType } from './db-Lw0KVZmc.js';
|
|
4
|
+
export { A as AmbiguousModelError, m as eventEmitter, z as getAddressesForItemsFilter, C as normalizeAddressConfig, E as normalizeAddressList, u as normalizeHexAddress } from './db-Lw0KVZmc.js';
|
|
5
|
+
export { getPropertySchema } from './property-ByaiSyUK.js';
|
|
6
|
+
import { n as normalizeRelationPropertyValue, r as resolveSeedIdsFromRefString, b as getArweaveUrlForTransaction } from './tabEvents-C6NXS6Jl.js';
|
|
7
|
+
export { A as ADDRESSES_PERSISTED_EVENT, F as FILES_CHANGED_EVENT, L as LOCAL_COPIES_REMOVED_EVENT, T as TabLockTimeoutError, c as classifyMediaRef, d as closestImageSize, f as ensureImageLocal, g as getCorrectId, h as getFeedItemStringField, j as isLeaderTab, i as isPublishedSeedRef, k as normalizeArweaveTxIdForEnsure, l as normalizeFeedItemFields, p as parseAddressesPersistedPayload, m as resolveMediaRef, w as whenLeaderTab } from './tabEvents-C6NXS6Jl.js';
|
|
8
|
+
import { g as getContentHash } from './ClientManager-DngaZdw6.js';
|
|
9
|
+
export { E as EAS_CHAIN_ID_APP_STATE_KEY, a as assertLocalDbChain, c as claimUnpublishedDrafts, C as client, d as createLocalQueryDataSource, e as createSchema, f as easSyncActor, h as getClient, j as getPublishedSeedRecord, k as getSchemaNameFromId, i as importJsonSchema, m as isSeedQueryLocalSourceRegistered, n as listSchemas, o as loadAllSchemasFromDb, p as mergeEasSyncRequestIntents, r as readJsonImportFile, q as readSchema, u as registerSeedQueryLocalSource, v as requestEasSyncFromAddressChange, x as requestEasSyncFromEventBus, y as requestEasSyncFromModelsInit, z as sendEasSyncClientRequest, A as startEasSyncActor, s as syncSchemaFromSource, t as transformImportToSchemaFile, B as unregisterSeedQueryLocalSource } from './ClientManager-DngaZdw6.js';
|
|
10
|
+
import { i as isVersionRevoked, q as compareMetadataRowsLatestFirst, t as isPublishedMetadataRow, b as getLatestPublishedVersionRow, p as parseListPropertyValueFromStorage, I as Item, j as waitForEntityIdle } from './Item-ZUAmf943.js';
|
|
11
|
+
export { C as ClientManagerState, f as ItemProperty, h as ItemPropertySaveValidationError, M as METADATA_LATEST_FIRST_ORDER_SQL, u as MachineIds, x as createNewItem, y as getEasSchemaForItemProperty, e as getGetAdditionalSyncAddresses, z as getGetPublisherForNewSeeds, A as getMetadataLatest, B as getRevokeExecutor, D as getUploadExecutor, E as getVersionData, F as isItemOwned, G as isLocalUnsealedDraft, H as isSeedRowOwned, l as listRelationEasPropertyName, J as ownedPublisherSql, K as pickLatestMetadataRowPerProperty, L as propertyMachine, N as publisherInAddressListSql, O as publisherIsInOwnedSet, P as setAdditionalSyncAddresses, Q as setGetPublisherForNewSeeds, R as setRevokeExecutor, S as setUploadExecutor } from './Item-ZUAmf943.js';
|
|
12
|
+
import { B as BaseDb, v as versions, r as seeds, m as metadata, h as htmlEmbeddedImageCoPublish, a as BaseFileManager, C as INTERNAL_STORAGE_MODEL_FILE_IDS, I as INTERNAL_PROPERTY_NAMES, Z as ZERO_BYTES32 } from './BasePathResolver-DRT09oVv.js';
|
|
13
|
+
export { E as EAS_SEED_DATA_SYNCED_TO_DB_EVENT, x as INTERNAL_DATA_TYPES, D as ImageSize, F as SEED_PROTOCOL_SCHEMA_NAME, G as SeedModels, H as VERSION_SCHEMA_DEF, V as VERSION_SCHEMA_UID, J as VERSION_SCHEMA_UID_OPTIMISM_SEPOLIA, b as appState, c as arweaveL1FinalizeJobs, e as easSyncProcesses, g as modelSchemas, i as modelUids, j as models, p as properties, o as propertyUids, q as publishProcesses, s as schemas, u as uploadProcesses } from './BasePathResolver-DRT09oVv.js';
|
|
14
|
+
import { eq, desc, and, or, isNotNull, ne } from 'drizzle-orm';
|
|
13
15
|
import { isPlaceholderUid, isValidEasAttestationUid, normalizeBytes32Hex } from '@seedprotocol/eas';
|
|
14
16
|
export { EAS_CHAIN_DEPLOYMENTS, BaseEasClient as EasClient, getCanonicalItemPropertiesFromEas, getEasChainDeployment, getEasEndpoint, getEasReadChainId, getEasSchemaUidBySchemaName, getItemPropertiesFromEas, getItemVersionsFromEas, getSeedsBySchemaName, getSeedsFromSchemaUids, isPlaceholderUid, isValidEasAttestationUid, normalizeBytes32Hex, pickLatestPropertyAttestationsByRefAndSchema, setSchemaUidForModel, setSchemaUidForSchemaDefinition, withExcludeRevokedFilter } from '@seedprotocol/eas';
|
|
15
|
-
|
|
16
|
-
export {
|
|
17
|
-
export {
|
|
17
|
+
import { generateId } from './generateId-BopUwD8F.js';
|
|
18
|
+
export { S as Schema, d as deleteModelFromSchema, a as deletePropertyFromModel, r as renameModelProperty, s as schemaMachine, u as updateModelProperties } from './Schema-D-Ud-XYw.js';
|
|
19
|
+
export { F as FileSystemLockedError } from './errors-CrBxGWah.js';
|
|
20
|
+
export { M as MODEL_AMBIGUOUS_EVENT } from './resolveModelForSyncedSeed-B0tco3zG.js';
|
|
21
|
+
export { ModelProperty } from './ModelProperty-6llK4MTH.js';
|
|
22
|
+
export { getModelSchemasFromEas } from './eas-CQ-Smzk2.js';
|
|
18
23
|
export { BaseArweaveClient, DEFAULT_ARWEAVE_GATEWAYS, DEFAULT_ARWEAVE_GRAPHQL_URL, DEFAULT_ARWEAVE_HOST, DEFAULT_GATEWAY_SIDECAR_HOST, DEFAULT_GATEWAY_SIDECAR_PORT, DEFAULT_SEED_FEED_HYPER_KEY, DEFAULT_SEED_GATEWAY_HYPER_KEY, SEED_RSS_IMAGE_RELATION_FIELD_KEYS, ensureReadGatewaySelected, fetchArweaveRawFromBaseUrl, fetchArweaveRawTextAcrossGateways, getArweaveReadBaseUrls, getArweaveUploadStatus, getDefaultArweaveReadGatewayHostsOrdered, getLastHealthyReadGatewayHost, getPreferredArweaveReadBaseUrls, getReadGatewayHostsForConfig, getResolvedArweaveReadBaseUrls, getResolvedSeedGatewayEndpoints, getUploadApiArweaveDataUrl, getUploadApiArweaveStatusUrl, getUploadPipelineTransactionStatus, invalidateReadGatewayCache, invalidateSidecarProbeCache, isArweaveL1AnchoringComplete, isEasAttestationExplorerUrl, isGatewayHostCircuitOpen, isKnownArweaveGatewayHostname, isReadGatewayKnownHealthy, mergePrimaryHostWithDefaults, normalizeGatewayHostKey, normalizeUploadApiBaseUrl, queryArweaveGatewayTransaction, queryArweaveGatewayTransactionWithFallback, recordGatewayHostFailure, recordGatewayHostSuccess, resetArweaveReadGatewayForTests, resolveSeedGatewayEndpoints, resolveSeedRssImageRelationFromItem, resolveSeedRssImageRelationRef, seedGatewayConfigFromClientContext, seedGatewayConfigFromSeedConfig, setPreferredArweaveReadBaseUrls, setResolvedSeedGatewayEndpoints } from '@seedprotocol/arweave';
|
|
19
|
-
export { u as updateSeedRevokedAt } from './updateSeedRevokedAt-
|
|
20
|
-
import {
|
|
21
|
-
export { PublishValidationFailedError, resolvePublishPayloadValues, validateItemForPublish } from './getPublishPayload-
|
|
24
|
+
export { u as updateSeedRevokedAt } from './updateSeedRevokedAt-CYwgVNlM.js';
|
|
25
|
+
import { a as getSegmentedItemProperties, g as getPublishDraftGraph, i as isSeedRevoked, f as findRelatedSeedRow, b as isUnpublishedSeed, h as htmlPropertyNameForHtmlSeed, r as relatedModelNameFromDef } from './publishDraftGraph-BRm6Pq3Q.js';
|
|
26
|
+
export { P as PublishValidationFailedError, R as RELATED_ITEM_UNPUBLISHED_CODE, a as RelatedItemUnpublishedError, r as resolvePublishPayloadValues, v as validateItemForPublish } from './getPublishPayload-76_KfB5Y.js';
|
|
22
27
|
import 'pluralize';
|
|
23
|
-
export { itemHasPublishUploadCandidates } from './getPublishUploads-
|
|
24
|
-
import { parseFragment
|
|
28
|
+
export { itemHasPublishUploadCandidates } from './getPublishUploads-CqgMBD8f.js';
|
|
29
|
+
import { parseFragment } from 'parse5';
|
|
25
30
|
import 'js-yaml';
|
|
26
31
|
import 'fs';
|
|
27
|
-
export { generateId } from './generateId-BopUwD8F.js';
|
|
28
32
|
import 'xstate';
|
|
29
33
|
import 'debug';
|
|
30
34
|
import './model-DGMe-TTm.js';
|
|
31
35
|
import 'drizzle-orm/casing';
|
|
32
36
|
import '@sinclair/typebox';
|
|
33
37
|
import 'lodash-es';
|
|
38
|
+
import 'rxjs';
|
|
34
39
|
import 'nanoid';
|
|
35
40
|
import 'nanoid-dictionary';
|
|
36
41
|
import '@seedprotocol/query';
|
|
42
|
+
import 'drizzle-orm/sqlite-core';
|
|
37
43
|
import '@noble/hashes/sha3';
|
|
38
44
|
import '@noble/hashes/utils';
|
|
39
|
-
import '
|
|
40
|
-
import 'drizzle-orm/sqlite-core';
|
|
41
|
-
import './SchemaValidationService-Y49vqast.js';
|
|
45
|
+
import './SchemaValidationService-IoS7JquP.js';
|
|
42
46
|
import '@sinclair/typebox/value';
|
|
43
47
|
import '@ethereum-attestation-service/eas-sdk';
|
|
44
48
|
|
|
45
49
|
/**
|
|
46
50
|
* Updates the version record with the attestation UID after a Version attestation is created.
|
|
47
|
-
* Targets the version without a uid yet (the one being published).
|
|
51
|
+
* Targets the version without a uid yet (the one being published). A uid one of the seed's
|
|
52
|
+
* version rows already has is ignored.
|
|
48
53
|
* Publisher is immutable once set: we never overwrite an existing publisher.
|
|
49
54
|
*/
|
|
50
55
|
const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestationCreatedAt, }) => {
|
|
@@ -59,10 +64,37 @@ const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestatio
|
|
|
59
64
|
.from(versions)
|
|
60
65
|
.where(eq(versions.seedLocalId, seedLocalId))
|
|
61
66
|
.orderBy(desc(versions.createdAt));
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
// Already recorded: nothing to stamp. A patch publish attaches to an existing version, and the
|
|
68
|
+
// modular executor's SeedPublished event still reports that version's uid; stamping it onto a
|
|
69
|
+
// local draft version would give two rows the same version uid.
|
|
70
|
+
const wanted = versionUid.toLowerCase();
|
|
71
|
+
if (rows.some((r) => r.uid?.toLowerCase() === wanted))
|
|
64
72
|
return;
|
|
73
|
+
const toUpdate = rows.find((r) => r.localId && isPlaceholderUid(r.uid));
|
|
65
74
|
const normalizedPublisher = normalizePublisher(publisher);
|
|
75
|
+
if (!toUpdate?.localId) {
|
|
76
|
+
// No local draft version took this attestation (e.g. a republish after unpublish, where every
|
|
77
|
+
// version row is a revoked attestation): record the new version so it is the latest one.
|
|
78
|
+
const [seed] = await appDb
|
|
79
|
+
.select({ type: seeds.type })
|
|
80
|
+
.from(seeds)
|
|
81
|
+
.where(eq(seeds.localId, seedLocalId))
|
|
82
|
+
.limit(1);
|
|
83
|
+
if (!seed)
|
|
84
|
+
return;
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
await appDb.insert(versions).values({
|
|
87
|
+
localId: generateId(),
|
|
88
|
+
seedLocalId,
|
|
89
|
+
seedType: seed.type,
|
|
90
|
+
uid: versionUid,
|
|
91
|
+
createdAt: now,
|
|
92
|
+
updatedAt: now,
|
|
93
|
+
...(normalizedPublisher && { publisher: normalizedPublisher }),
|
|
94
|
+
...(attestationCreatedAt != null && { attestationCreatedAt }),
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
66
98
|
let shouldSetPublisher = normalizedPublisher != null;
|
|
67
99
|
if (shouldSetPublisher && toUpdate.publisher != null && toUpdate.publisher !== '') {
|
|
68
100
|
shouldSetPublisher = false;
|
|
@@ -83,6 +115,12 @@ const updateVersionUid = async ({ seedLocalId, versionUid, publisher, attestatio
|
|
|
83
115
|
* so getPublishPendingDiff stays aligned with on-chain state.
|
|
84
116
|
* When pair.propertyName is set, match that property even if the row has no schemaUid;
|
|
85
117
|
* if the row has a schemaUid it must still match. Pair-only schema match remains for unnamed pairs.
|
|
118
|
+
*
|
|
119
|
+
* A full-snapshot publish (`new_version`, or a republish after unpublish) also attests properties
|
|
120
|
+
* whose rows are already attested (on an older version, or the revoked seed's). With no placeholder
|
|
121
|
+
* to take the uid, the attestation is recorded as a new row for the published version: a copy of
|
|
122
|
+
* the property's latest row with the new uid, so readers show the published version without a
|
|
123
|
+
* sync. Rows keep or get the published version's local id when `versionUid` has a version row.
|
|
86
124
|
*/
|
|
87
125
|
async function applyPropertyAttestationUidsFromPublish(params) {
|
|
88
126
|
const { seedLocalId, attestationCreatedAtMs, pairs, versionUid } = params;
|
|
@@ -96,6 +134,27 @@ async function applyPropertyAttestationUidsFromPublish(params) {
|
|
|
96
134
|
const validVersion = versionUid != null && versionUid !== '' && isValidEasAttestationUid(versionUid)
|
|
97
135
|
? versionUid
|
|
98
136
|
: undefined;
|
|
137
|
+
let versionLocalId;
|
|
138
|
+
let liveSeedUid = null;
|
|
139
|
+
if (validVersion) {
|
|
140
|
+
const [versionRow] = await appDb
|
|
141
|
+
.select({ localId: versions.localId, seedUid: versions.seedUid })
|
|
142
|
+
.from(versions)
|
|
143
|
+
.where(and(eq(versions.seedLocalId, seedLocalId), eq(versions.uid, validVersion)))
|
|
144
|
+
.limit(1);
|
|
145
|
+
versionLocalId = versionRow?.localId ?? undefined;
|
|
146
|
+
const [seedRow] = await appDb
|
|
147
|
+
.select({ uid: seeds.uid, revokedAt: seeds.revokedAt })
|
|
148
|
+
.from(seeds)
|
|
149
|
+
.where(eq(seeds.localId, seedLocalId))
|
|
150
|
+
.limit(1);
|
|
151
|
+
// A republish records its new seed uid after this; updateSeedUid fills it in then.
|
|
152
|
+
liveSeedUid =
|
|
153
|
+
versionRow?.seedUid ??
|
|
154
|
+
(isValidEasAttestationUid(seedRow?.uid) && !isVersionRevoked(seedRow?.revokedAt)
|
|
155
|
+
? seedRow.uid
|
|
156
|
+
: null);
|
|
157
|
+
}
|
|
99
158
|
for (const pair of pairs) {
|
|
100
159
|
const att = pair.attestationUid?.trim();
|
|
101
160
|
if (!isValidEasAttestationUid(att))
|
|
@@ -106,6 +165,9 @@ async function applyPropertyAttestationUidsFromPublish(params) {
|
|
|
106
165
|
const pairName = pair.propertyName != null && pair.propertyName !== '' ? pair.propertyName : undefined;
|
|
107
166
|
const candidates = working
|
|
108
167
|
.filter((r) => {
|
|
168
|
+
// Rows sync derived for ItemStorage properties aren't placeholders for an attestation.
|
|
169
|
+
if (r.derivedFromUid != null)
|
|
170
|
+
return false;
|
|
109
171
|
if (pairName) {
|
|
110
172
|
if (r.propertyName !== pairName)
|
|
111
173
|
return false;
|
|
@@ -120,8 +182,34 @@ async function applyPropertyAttestationUidsFromPublish(params) {
|
|
|
120
182
|
})
|
|
121
183
|
.sort(compareMetadataRowsLatestFirst);
|
|
122
184
|
const target = candidates.find((r) => isPlaceholderUid(r.uid));
|
|
123
|
-
if (!target?.localId)
|
|
185
|
+
if (!target?.localId) {
|
|
186
|
+
// Full snapshot: the property's rows are all attested. Record this attestation as a new row
|
|
187
|
+
// for the published version (unless it is already recorded, e.g. a replayed receipt).
|
|
188
|
+
const source = candidates[0];
|
|
189
|
+
if (!source || !validVersion)
|
|
190
|
+
continue;
|
|
191
|
+
if (working.some((r) => r.uid?.toLowerCase() === att.toLowerCase()))
|
|
192
|
+
continue;
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
const row = {
|
|
195
|
+
...source,
|
|
196
|
+
localId: generateId(),
|
|
197
|
+
uid: att,
|
|
198
|
+
schemaUid: normalizeBytes32Hex(source.schemaUid) ? source.schemaUid : wantSchema,
|
|
199
|
+
seedUid: liveSeedUid,
|
|
200
|
+
versionUid: validVersion,
|
|
201
|
+
versionLocalId: versionLocalId ?? source.versionLocalId,
|
|
202
|
+
attestationCreatedAt: attestationCreatedAtMs ?? now,
|
|
203
|
+
attestationRaw: null,
|
|
204
|
+
revokedAt: null,
|
|
205
|
+
derivedFromUid: null,
|
|
206
|
+
createdAt: now,
|
|
207
|
+
updatedAt: now,
|
|
208
|
+
};
|
|
209
|
+
await appDb.insert(metadata).values(row);
|
|
210
|
+
working.push(row);
|
|
124
211
|
continue;
|
|
212
|
+
}
|
|
125
213
|
const writeSchemaUid = !normalizeBytes32Hex(target.schemaUid);
|
|
126
214
|
await appDb
|
|
127
215
|
.update(metadata)
|
|
@@ -130,6 +218,7 @@ async function applyPropertyAttestationUidsFromPublish(params) {
|
|
|
130
218
|
...(writeSchemaUid && { schemaUid: wantSchema }),
|
|
131
219
|
...(attestationCreatedAtMs != null && { attestationCreatedAt: attestationCreatedAtMs }),
|
|
132
220
|
...(validVersion && { versionUid: validVersion }),
|
|
221
|
+
...(versionLocalId && { versionLocalId }),
|
|
133
222
|
updatedAt: Date.now(),
|
|
134
223
|
})
|
|
135
224
|
.where(eq(metadata.localId, target.localId));
|
|
@@ -141,6 +230,7 @@ async function applyPropertyAttestationUidsFromPublish(params) {
|
|
|
141
230
|
...(writeSchemaUid && { schemaUid: wantSchema }),
|
|
142
231
|
attestationCreatedAt: attestationCreatedAtMs ?? working[i].attestationCreatedAt,
|
|
143
232
|
...(validVersion && { versionUid: validVersion }),
|
|
233
|
+
...(versionLocalId && { versionLocalId }),
|
|
144
234
|
};
|
|
145
235
|
}
|
|
146
236
|
}
|
|
@@ -171,7 +261,8 @@ function resolveSeedIds$1(arg) {
|
|
|
171
261
|
}
|
|
172
262
|
/**
|
|
173
263
|
* Per property: the **latest** metadata row (by `attestationCreatedAt` / `createdAt`) lacks a valid
|
|
174
|
-
* EAS attestation `uid` — local edit or missing post-publish UID backfill.
|
|
264
|
+
* EAS attestation `uid` — local edit or missing post-publish UID backfill. Rows sync derived for
|
|
265
|
+
* ItemStorage properties (`derivedFromUid` set) count as published. **Not** equivalent to
|
|
175
266
|
* draft vs onchain for the whole seed; use `getSeedPublishState` for that.
|
|
176
267
|
*/
|
|
177
268
|
async function getPublishPendingDiff(arg) {
|
|
@@ -208,9 +299,8 @@ async function getPublishPendingDiff(arg) {
|
|
|
208
299
|
const latest = list[0];
|
|
209
300
|
if (!latest)
|
|
210
301
|
continue;
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const prevWithUid = list.find((r) => isValidEasAttestationUid(r.uid));
|
|
302
|
+
if (!isPublishedMetadataRow(latest)) {
|
|
303
|
+
const prevWithUid = list.find(isPublishedMetadataRow);
|
|
214
304
|
pendingProperties.push({
|
|
215
305
|
propertyName,
|
|
216
306
|
currentValue: latest.propertyValue ?? null,
|
|
@@ -259,7 +349,8 @@ function maxMs(a, b) {
|
|
|
259
349
|
}
|
|
260
350
|
/**
|
|
261
351
|
* Whether the seed has **any** on-chain anchor in local SQLite: valid EAS UID on the seed row,
|
|
262
|
-
* on the newest **published** version row (`getLatestPublishedVersionRow
|
|
352
|
+
* on the newest **published** version row (`getLatestPublishedVersionRow`, which skips revoked
|
|
353
|
+
* versions), or on **any** metadata row.
|
|
263
354
|
* Not the same as “no unpublished edits”; see `getPublishPendingDiff` for per-property head rows.
|
|
264
355
|
*/
|
|
265
356
|
async function getSeedPublishState(arg) {
|
|
@@ -271,6 +362,7 @@ async function getSeedPublishState(arg) {
|
|
|
271
362
|
versionAttestationUid: null,
|
|
272
363
|
explorerUid: null,
|
|
273
364
|
lastAttestedAtMs: null,
|
|
365
|
+
revokedAt: null,
|
|
274
366
|
};
|
|
275
367
|
if (!appDb || (!seedLocalId && !seedUid)) {
|
|
276
368
|
return empty;
|
|
@@ -316,6 +408,7 @@ async function getSeedPublishState(arg) {
|
|
|
316
408
|
versionAttestationUid,
|
|
317
409
|
explorerUid,
|
|
318
410
|
lastAttestedAtMs,
|
|
411
|
+
revokedAt: seedRow?.revokedAt ? seedRow.revokedAt : null,
|
|
319
412
|
};
|
|
320
413
|
}
|
|
321
414
|
|
|
@@ -437,7 +530,7 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
|
|
|
437
530
|
visited.add(seedLocalId);
|
|
438
531
|
const result = [];
|
|
439
532
|
const { itemRelationProperties, itemImageProperties, itemListProperties } = await getSegmentedItemProperties(item);
|
|
440
|
-
const getItemMod = await import('./getItem-
|
|
533
|
+
const getItemMod = await import('./getItem-CSfSok9f.js');
|
|
441
534
|
const { getItem } = getItemMod;
|
|
442
535
|
const processRelationOrImage = async (prop) => {
|
|
443
536
|
const snapshot = prop.getService().getSnapshot();
|
|
@@ -456,8 +549,8 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
|
|
|
456
549
|
if (!value && prop.propertyName && isStorageSeed) {
|
|
457
550
|
const ctx = context;
|
|
458
551
|
if (ctx.seedLocalId || ctx.seedUid) {
|
|
459
|
-
const _mod_0 = await import('./
|
|
460
|
-
const _ns_0 = _mod_0.
|
|
552
|
+
const _mod_0 = await import('./Item-ZUAmf943.js');
|
|
553
|
+
const _ns_0 = _mod_0.Y;
|
|
461
554
|
const { getPropertyData } = _ns_0;
|
|
462
555
|
const meta = await getPropertyData({
|
|
463
556
|
propertyName: prop.propertyName,
|
|
@@ -515,606 +608,839 @@ async function getRelatedItemsForPublish(item, visited = new Set()) {
|
|
|
515
608
|
return result;
|
|
516
609
|
}
|
|
517
610
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
611
|
+
const HTML_EMBEDDED_MAX_IMAGES_PER_DOC = 50;
|
|
612
|
+
const HTML_EMBEDDED_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
613
|
+
const HTML_EMBEDDED_MAX_TOTAL_BYTES = 25 * 1024 * 1024;
|
|
614
|
+
const DATA_URI_IMAGE = /^data:(image\/[a-zA-Z0-9.+-]+);base64,([\s\S]*)$/i;
|
|
615
|
+
const MIME_NORMALIZE = {
|
|
616
|
+
'image/jpg': 'image/jpeg',
|
|
617
|
+
};
|
|
618
|
+
function normalizeMime(m) {
|
|
619
|
+
const lower = m.toLowerCase().trim();
|
|
620
|
+
return MIME_NORMALIZE[lower] ?? lower;
|
|
526
621
|
}
|
|
527
|
-
|
|
528
|
-
|
|
622
|
+
const ALLOWED_MIMES = new Set([
|
|
623
|
+
'image/png',
|
|
624
|
+
'image/jpeg',
|
|
625
|
+
'image/webp',
|
|
626
|
+
'image/gif',
|
|
627
|
+
'image/svg+xml',
|
|
628
|
+
]);
|
|
629
|
+
class HtmlEmbeddedDataUriLimitError extends Error {
|
|
630
|
+
constructor(message) {
|
|
631
|
+
super(message);
|
|
632
|
+
this.name = 'HtmlEmbeddedDataUriLimitError';
|
|
633
|
+
}
|
|
529
634
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
return 0;
|
|
538
|
-
const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
|
|
539
|
-
return Math.max(0, Math.floor((b64.length * 3) / 4) - padding);
|
|
635
|
+
function resolveEffectiveHtmlEmbeddedDataUriPolicy(propertyDef, publishLevel) {
|
|
636
|
+
const fromProp = propertyDef?.htmlEmbeddedDataUriPolicy;
|
|
637
|
+
if (fromProp === 'materialize' || fromProp === 'preserve')
|
|
638
|
+
return fromProp;
|
|
639
|
+
if (publishLevel === 'materialize' || publishLevel === 'preserve')
|
|
640
|
+
return publishLevel;
|
|
641
|
+
return 'materialize';
|
|
540
642
|
}
|
|
541
|
-
function
|
|
542
|
-
const
|
|
543
|
-
return
|
|
544
|
-
? (snapshot.context ?? null)
|
|
545
|
-
: null;
|
|
643
|
+
function getAttr(node, name) {
|
|
644
|
+
const a = node.attrs?.find((x) => x.name === name);
|
|
645
|
+
return a?.value;
|
|
546
646
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
647
|
+
/**
|
|
648
|
+
* Walk fragment tree; collect unique data:image base64 URIs with limits.
|
|
649
|
+
*/
|
|
650
|
+
async function extractDataUriImagesFromHtml(html) {
|
|
651
|
+
const fragment = parseFragment(html);
|
|
652
|
+
const found = [];
|
|
653
|
+
const seenUris = new Set();
|
|
654
|
+
let totalBytes = 0;
|
|
655
|
+
const walk = async (node) => {
|
|
656
|
+
if (node.nodeName === '#text' || node.nodeName === '#comment')
|
|
657
|
+
return;
|
|
658
|
+
const el = node;
|
|
659
|
+
if (el.tagName === 'img') {
|
|
660
|
+
const src = getAttr(el, 'src')?.trim();
|
|
661
|
+
if (src && src.startsWith('data:image/')) {
|
|
662
|
+
const m = DATA_URI_IMAGE.exec(src);
|
|
663
|
+
if (m) {
|
|
664
|
+
const mimeRaw = normalizeMime(m[1]);
|
|
665
|
+
if (!ALLOWED_MIMES.has(mimeRaw)) {
|
|
666
|
+
throw new HtmlEmbeddedDataUriLimitError(`Unsupported embedded image type: ${mimeRaw}. Allowed: ${[...ALLOWED_MIMES].join(', ')}`);
|
|
667
|
+
}
|
|
668
|
+
let binary;
|
|
669
|
+
try {
|
|
670
|
+
const b64 = m[2].replace(/\s/g, '');
|
|
671
|
+
binary = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
672
|
+
}
|
|
673
|
+
catch {
|
|
674
|
+
throw new HtmlEmbeddedDataUriLimitError('Invalid base64 in embedded image data URI');
|
|
675
|
+
}
|
|
676
|
+
const byteLength = binary.byteLength;
|
|
677
|
+
if (byteLength > HTML_EMBEDDED_MAX_IMAGE_BYTES) {
|
|
678
|
+
throw new HtmlEmbeddedDataUriLimitError(`Embedded image exceeds max size (${HTML_EMBEDDED_MAX_IMAGE_BYTES} bytes)`);
|
|
679
|
+
}
|
|
680
|
+
totalBytes += byteLength;
|
|
681
|
+
if (totalBytes > HTML_EMBEDDED_MAX_TOTAL_BYTES) {
|
|
682
|
+
throw new HtmlEmbeddedDataUriLimitError(`Total embedded image size exceeds max (${HTML_EMBEDDED_MAX_TOTAL_BYTES} bytes)`);
|
|
683
|
+
}
|
|
684
|
+
if (!seenUris.has(src)) {
|
|
685
|
+
if (seenUris.size >= HTML_EMBEDDED_MAX_IMAGES_PER_DOC) {
|
|
686
|
+
throw new HtmlEmbeddedDataUriLimitError(`Too many distinct embedded images (max ${HTML_EMBEDDED_MAX_IMAGES_PER_DOC})`);
|
|
687
|
+
}
|
|
688
|
+
seenUris.add(src);
|
|
689
|
+
const stableKey = await getContentHash(binary);
|
|
690
|
+
found.push({ dataUri: src, stableKey, byteLength, mimeType: mimeRaw });
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
const parent = el;
|
|
696
|
+
if (parent.childNodes) {
|
|
697
|
+
for (const c of parent.childNodes)
|
|
698
|
+
await walk(c);
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
for (const c of fragment.childNodes)
|
|
702
|
+
await walk(c);
|
|
703
|
+
return found;
|
|
704
|
+
}
|
|
705
|
+
function escapeAttributeValue(value) {
|
|
706
|
+
return value.replace(/&/g, '&').replace(/"/g, '"');
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Rewrite attribute values of `html` by splicing each new value into the original string: every
|
|
710
|
+
* byte other than the rewritten attributes stays as written. Re-serializing the parsed tree would
|
|
711
|
+
* not round-trip (parse5 drops the newline the parser eats after `<pre>`/`<textarea>`/`<listing>`,
|
|
712
|
+
* a fragment parse drops doctype/html/head/body, and quoting, case and line endings are normalized),
|
|
713
|
+
* and sealed Html must not change with the serializer.
|
|
714
|
+
*
|
|
715
|
+
* `rewrite` gets each attribute's (entity-decoded) value and returns its new value, or undefined to
|
|
716
|
+
* leave it. A rewritten attribute is written as `name="value"`.
|
|
717
|
+
*/
|
|
718
|
+
function rewriteHtmlAttributes(html, rewrite) {
|
|
719
|
+
const fragment = parseFragment(html, { sourceCodeLocationInfo: true });
|
|
720
|
+
const edits = [];
|
|
721
|
+
const walk = (node) => {
|
|
722
|
+
if (node.nodeName === '#text' || node.nodeName === '#comment')
|
|
723
|
+
return;
|
|
724
|
+
const el = node;
|
|
725
|
+
if (el.attrs?.length) {
|
|
726
|
+
for (const attr of el.attrs) {
|
|
727
|
+
if (attr.prefix)
|
|
728
|
+
continue;
|
|
729
|
+
const next = rewrite(el, attr.name, attr.value);
|
|
730
|
+
const location = el.sourceCodeLocation?.attrs?.[attr.name];
|
|
731
|
+
if (next === undefined || !location)
|
|
732
|
+
continue;
|
|
733
|
+
edits.push({
|
|
734
|
+
start: location.startOffset,
|
|
735
|
+
end: location.endOffset,
|
|
736
|
+
text: `${attr.name}="${escapeAttributeValue(next)}"`,
|
|
737
|
+
});
|
|
567
738
|
}
|
|
568
739
|
}
|
|
740
|
+
const parent = el;
|
|
741
|
+
if (parent.childNodes) {
|
|
742
|
+
for (const c of parent.childNodes)
|
|
743
|
+
walk(c);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
for (const c of fragment.childNodes)
|
|
747
|
+
walk(c);
|
|
748
|
+
let out = html;
|
|
749
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
750
|
+
out = out.slice(0, edit.start) + edit.text + out.slice(edit.end);
|
|
569
751
|
}
|
|
570
|
-
return
|
|
752
|
+
return out;
|
|
571
753
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
754
|
+
/**
|
|
755
|
+
* Replace `data:image/...` `<img src>` values with Arweave URLs (keyed by data URI). Only those
|
|
756
|
+
* `src` attributes change; the rest of the Html is kept byte for byte.
|
|
757
|
+
*/
|
|
758
|
+
function replaceDataUrisInParsedHtml(html, replacements) {
|
|
759
|
+
if (replacements.size === 0)
|
|
760
|
+
return html;
|
|
761
|
+
return rewriteHtmlAttributes(html, (el, attrName, value) => {
|
|
762
|
+
if (el.tagName !== 'img' || attrName !== 'src')
|
|
763
|
+
return undefined;
|
|
764
|
+
return replacements.get(value.trim());
|
|
765
|
+
});
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* `seed:property/<propertyName>` in Html stands for the Arweave URL of the same item's
|
|
769
|
+
* `<propertyName>` storage property (Image, File or Json). Publish uploads that property first,
|
|
770
|
+
* then rewrites the placeholder to its gateway URL before the Html is uploaded, so Html can show a
|
|
771
|
+
* file published alongside it without embedding it (e.g. `<img class="u-featured"
|
|
772
|
+
* src="seed:property/featureImage">`).
|
|
773
|
+
*/
|
|
774
|
+
const SEED_PROPERTY_REF_PREFIX = 'seed:property/';
|
|
775
|
+
const SEED_PROPERTY_REF = /^seed:property\/([A-Za-z_$][A-Za-z0-9_$]*)$/;
|
|
776
|
+
/** Attributes whose whole (trimmed) value may be a `seed:property/` placeholder. */
|
|
777
|
+
const SEED_PROPERTY_REF_ATTRIBUTES = new Set(['src', 'href', 'poster']);
|
|
778
|
+
const seedPropertyRefName = (attrName, value) => SEED_PROPERTY_REF_ATTRIBUTES.has(attrName) ? SEED_PROPERTY_REF.exec(value.trim())?.[1] : undefined;
|
|
779
|
+
/** A `seed:property/` placeholder that names no usable property, or whose upload is unknown. */
|
|
780
|
+
class HtmlSeedPropertyRefError extends Error {
|
|
781
|
+
constructor(message) {
|
|
782
|
+
super(message);
|
|
783
|
+
this.name = 'HtmlSeedPropertyRefError';
|
|
587
784
|
}
|
|
588
|
-
return true;
|
|
589
785
|
}
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
786
|
+
/** Property names referenced by `seed:property/<name>` placeholders in `html`, each once. */
|
|
787
|
+
function findSeedPropertyRefsInHtml(html) {
|
|
788
|
+
if (!html.includes(SEED_PROPERTY_REF_PREFIX))
|
|
789
|
+
return [];
|
|
790
|
+
const names = new Set();
|
|
791
|
+
rewriteHtmlAttributes(html, (_el, attrName, value) => {
|
|
792
|
+
const name = seedPropertyRefName(attrName, value);
|
|
793
|
+
if (name)
|
|
794
|
+
names.add(name);
|
|
795
|
+
return undefined;
|
|
796
|
+
});
|
|
797
|
+
return [...names];
|
|
798
|
+
}
|
|
799
|
+
/** Replace `seed:property/<name>` placeholders with `urlByPropertyName.get(name)`; other bytes are kept. */
|
|
800
|
+
function replaceSeedPropertyRefsInHtml(html, urlByPropertyName) {
|
|
801
|
+
if (urlByPropertyName.size === 0)
|
|
802
|
+
return html;
|
|
803
|
+
return rewriteHtmlAttributes(html, (_el, attrName, value) => {
|
|
804
|
+
const name = seedPropertyRefName(attrName, value);
|
|
805
|
+
return name ? urlByPropertyName.get(name) : undefined;
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
const SEED_PROPERTY_REF_DATA_TYPES = [
|
|
809
|
+
ModelPropertyDataTypes.Image,
|
|
810
|
+
ModelPropertyDataTypes.File,
|
|
811
|
+
ModelPropertyDataTypes.Json,
|
|
812
|
+
];
|
|
813
|
+
/**
|
|
814
|
+
* The storage property of `item` a `seed:property/<name>` placeholder names, and the seed it holds.
|
|
815
|
+
* Html properties are refused: an Html seed may itself be deferred to after the rewrite.
|
|
816
|
+
*/
|
|
817
|
+
function resolveSeedPropertyRefTarget(item, propertyName) {
|
|
818
|
+
const property = item.properties.find((p) => p.propertyName === propertyName || p.propertyName === `${propertyName}Id`);
|
|
819
|
+
const def = property?.propertyDef;
|
|
820
|
+
if (!property || !def) {
|
|
821
|
+
throw new HtmlSeedPropertyRefError(`Html references ${SEED_PROPERTY_REF_PREFIX}${propertyName}, but ${item.modelName} has no property ${propertyName}`);
|
|
822
|
+
}
|
|
823
|
+
const dataType = normalizeDataTypeLocal(def.dataType);
|
|
824
|
+
const storageType = dataType === ModelPropertyDataTypes.Relation ? normalizeDataTypeLocal(def.refValueType) : dataType;
|
|
825
|
+
if (!SEED_PROPERTY_REF_DATA_TYPES.includes(storageType)) {
|
|
826
|
+
throw new HtmlSeedPropertyRefError(`Html references ${SEED_PROPERTY_REF_PREFIX}${propertyName}, but ${propertyName} is ${def.dataType}; ` +
|
|
827
|
+
`only Image, File and Json properties can be referenced`);
|
|
602
828
|
}
|
|
829
|
+
const snap = property.getService().getSnapshot();
|
|
830
|
+
const ctx = 'context' in snap ? snap.context : null;
|
|
831
|
+
const ids = resolveSeedIdsFromRefString(normalizeRelationPropertyValue(ctx?.propertyValue) ?? '');
|
|
832
|
+
if (!ids.seedLocalId && !ids.seedUid) {
|
|
833
|
+
throw new HtmlSeedPropertyRefError(`Html references ${SEED_PROPERTY_REF_PREFIX}${propertyName}, but ${propertyName} has no value`);
|
|
834
|
+
}
|
|
835
|
+
return ids;
|
|
603
836
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
837
|
+
const ARWEAVE_TX_ID = /^[a-z0-9_-]{43}$/i;
|
|
838
|
+
/**
|
|
839
|
+
* The Arweave tx of the storage seed a placeholder names: uploaded in this publish's phase 1, or,
|
|
840
|
+
* when not uploaded now, the transaction it was published with (its storageTransactionId).
|
|
841
|
+
*/
|
|
842
|
+
async function resolveSeedPropertyRefTxId(item, propertyName, txBySeedLocalId) {
|
|
843
|
+
const { seedLocalId, seedUid } = resolveSeedPropertyRefTarget(item, propertyName);
|
|
844
|
+
const uploaded = seedLocalId ? txBySeedLocalId.get(seedLocalId) : undefined;
|
|
845
|
+
if (uploaded)
|
|
846
|
+
return uploaded;
|
|
847
|
+
const storageItem = await Item.find({ seedLocalId, seedUid });
|
|
848
|
+
const st = storageItem?.internalProperties['storageTransactionId'] ??
|
|
849
|
+
storageItem?.allProperties['storageTransactionId'];
|
|
850
|
+
const stSnap = st?.getService().getSnapshot();
|
|
851
|
+
const stValue = stSnap && 'context' in stSnap ? stSnap.context.propertyValue : undefined;
|
|
852
|
+
if (typeof stValue === 'string' && ARWEAVE_TX_ID.test(stValue.trim()))
|
|
853
|
+
return stValue.trim();
|
|
854
|
+
throw new HtmlSeedPropertyRefError(`Html references ${SEED_PROPERTY_REF_PREFIX}${propertyName}, but ${propertyName} was not uploaded ` +
|
|
855
|
+
`in this publish and has no published transaction`);
|
|
610
856
|
}
|
|
611
|
-
async function
|
|
612
|
-
if (!
|
|
613
|
-
return;
|
|
614
|
-
const size = await BaseFileManager.getFileSize(filePath);
|
|
615
|
-
if (size == null || size <= 0)
|
|
857
|
+
async function deleteCoPublishRowsForParent(appDb, parentSeedLocalId) {
|
|
858
|
+
if (!appDb)
|
|
616
859
|
return;
|
|
617
|
-
await
|
|
860
|
+
await appDb.delete(htmlEmbeddedImageCoPublish).where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId));
|
|
618
861
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
if (childCount > 0) {
|
|
634
|
-
await addUpload(acc, seen, `upload:${item.seedLocalId}:${uploadProperty.itemProperty.localId}`, childBytes);
|
|
635
|
-
continue;
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
for (const itemProperty of itemImageProperties) {
|
|
639
|
-
const context = propertyContext(itemProperty);
|
|
640
|
-
if (!context)
|
|
641
|
-
continue;
|
|
642
|
-
const refResolvedValue = (typeof context.refResolvedValue === 'string' && context.refResolvedValue) ||
|
|
643
|
-
itemProperty.refResolvedValue;
|
|
644
|
-
if (typeof refResolvedValue !== 'string' || !refResolvedValue)
|
|
645
|
-
continue;
|
|
646
|
-
const propertyValue = context.propertyValue;
|
|
647
|
-
const { seedLocalId } = resolveSeedIdsFromRefString(normalizeRelationPropertyValue(propertyValue) ?? '');
|
|
648
|
-
const dataType = itemProperty.propertyDef?.refValueType ??
|
|
649
|
-
itemProperty.propertyDef?.dataType ??
|
|
650
|
-
'Image';
|
|
651
|
-
const fromGetter = itemProperty.localStoragePath;
|
|
652
|
-
const filePath = typeof fromGetter === 'string' && fromGetter
|
|
653
|
-
? fromGetter
|
|
654
|
-
: `${getStorageDirForDataType(String(dataType))}/${refResolvedValue}`;
|
|
655
|
-
await addUploadFromPath(acc, seen, filePath, seedLocalId ? `seed:${seedLocalId}` : `path:${filePath}`);
|
|
862
|
+
/**
|
|
863
|
+
* Create an Image item and persist a data URI into its storageTransactionId (same path as user paste).
|
|
864
|
+
*/
|
|
865
|
+
async function createImageItemFromDataUri(dataUri) {
|
|
866
|
+
const imageItem = await Item.create({
|
|
867
|
+
modelName: 'Image',
|
|
868
|
+
modelFileId: INTERNAL_STORAGE_MODEL_FILE_IDS.image,
|
|
869
|
+
});
|
|
870
|
+
await waitForEntityIdle(imageItem, { timeout: 60000 });
|
|
871
|
+
const st = imageItem.internalProperties['storageTransactionId'] ??
|
|
872
|
+
imageItem.allProperties['storageTransactionId'];
|
|
873
|
+
if (!st) {
|
|
874
|
+
throw new Error('Image item missing storageTransactionId property');
|
|
656
875
|
}
|
|
876
|
+
st.value = dataUri;
|
|
877
|
+
await st.save();
|
|
878
|
+
await waitForEntityIdle(imageItem, { timeout: 60000 });
|
|
879
|
+
return { seedLocalId: imageItem.seedLocalId };
|
|
657
880
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
try {
|
|
667
|
-
return await getItem({ seedLocalId, seedUid });
|
|
881
|
+
/**
|
|
882
|
+
* Scan Html storage properties, materialize embedded images as Image items, insert co-publish rows.
|
|
883
|
+
* Call before phase-1 Arweave tx build. Does not rewrite Html files yet.
|
|
884
|
+
*/
|
|
885
|
+
async function prepareHtmlEmbeddedImagesForPublish(item, publishPolicy) {
|
|
886
|
+
const appDb = BaseDb.getAppDb();
|
|
887
|
+
if (!appDb) {
|
|
888
|
+
return { deferredHtmlSeedLocalIds: [] };
|
|
668
889
|
}
|
|
669
|
-
|
|
670
|
-
|
|
890
|
+
const deferred = new Set();
|
|
891
|
+
// The item's own Html, and the Html of the draft items published with it: each gets its embedded
|
|
892
|
+
// images materialized and co-published (rows keyed by the item owning the Html property).
|
|
893
|
+
for (const parent of [item, ...(await getRelatedDraftsCoPublishedWith(item))]) {
|
|
894
|
+
await prepareHtmlEmbeddedImagesOfItem(appDb, parent, publishPolicy, deferred);
|
|
671
895
|
}
|
|
896
|
+
return { deferredHtmlSeedLocalIds: [...deferred] };
|
|
672
897
|
}
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
898
|
+
/**
|
|
899
|
+
* Draft items (no seed uid yet) that a publish of `item` publishes with it: every draft reachable
|
|
900
|
+
* through relation and list properties, as getPublishPayload and getPublishUploads walk them
|
|
901
|
+
* (publishDraftGraph.ts). Html-embedded images of these items are co-published with `item` like its own.
|
|
902
|
+
*/
|
|
903
|
+
async function getRelatedDraftsCoPublishedWith(item) {
|
|
904
|
+
const _mod_1 = await import('./publishDraftGraph-BRm6Pq3Q.js');
|
|
905
|
+
const _ns_1 = _mod_1.p;
|
|
906
|
+
const { getPublishDraftGraph } = _ns_1;
|
|
907
|
+
const { drafts } = await getPublishDraftGraph(item);
|
|
908
|
+
return drafts.map((d) => d.item);
|
|
681
909
|
}
|
|
682
|
-
async function
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
const
|
|
696
|
-
if (
|
|
697
|
-
|
|
910
|
+
async function prepareHtmlEmbeddedImagesOfItem(appDb, item, publishPolicy, deferred) {
|
|
911
|
+
await deleteCoPublishRowsForParent(appDb, item.seedLocalId);
|
|
912
|
+
for (const p of item.properties) {
|
|
913
|
+
const def = p.propertyDef;
|
|
914
|
+
if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
|
|
915
|
+
continue;
|
|
916
|
+
const snap = p.getService().getSnapshot();
|
|
917
|
+
const ctx = 'context' in snap ? snap.context : null;
|
|
918
|
+
const htmlSeedLocalId = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue : '';
|
|
919
|
+
const refResolved = ctx?.refResolvedValue;
|
|
920
|
+
if (!htmlSeedLocalId?.trim() || !refResolved)
|
|
921
|
+
continue;
|
|
922
|
+
const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
|
|
923
|
+
const exists = await BaseFileManager.pathExists(filePath);
|
|
924
|
+
if (!exists)
|
|
925
|
+
continue;
|
|
926
|
+
let html;
|
|
927
|
+
try {
|
|
928
|
+
html = await BaseFileManager.readFileAsString(filePath);
|
|
929
|
+
}
|
|
930
|
+
catch {
|
|
931
|
+
const buf = await BaseFileManager.readFileAsBuffer(filePath);
|
|
932
|
+
if (typeof Buffer !== 'undefined' && Buffer.isBuffer(buf)) {
|
|
933
|
+
html = buf.toString('utf-8');
|
|
934
|
+
}
|
|
935
|
+
else if (typeof Blob !== 'undefined' && buf instanceof Blob) {
|
|
936
|
+
html = await buf.text();
|
|
937
|
+
}
|
|
938
|
+
else if (buf instanceof ArrayBuffer) {
|
|
939
|
+
html = new TextDecoder('utf-8', { fatal: false }).decode(buf);
|
|
940
|
+
}
|
|
941
|
+
else {
|
|
942
|
+
const v = buf;
|
|
943
|
+
html = new TextDecoder('utf-8', { fatal: false }).decode(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
// seed:property/ placeholders are filled in after phase 1 whatever the data URI policy. A
|
|
947
|
+
// placeholder naming no usable property fails here, before anything is uploaded.
|
|
948
|
+
const refs = findSeedPropertyRefsInHtml(html);
|
|
949
|
+
for (const name of refs)
|
|
950
|
+
resolveSeedPropertyRefTarget(item, name);
|
|
951
|
+
if (refs.length > 0)
|
|
952
|
+
deferred.add(htmlSeedLocalId.trim());
|
|
953
|
+
const policy = resolveEffectiveHtmlEmbeddedDataUriPolicy(def, publishPolicy);
|
|
954
|
+
if (policy !== 'materialize')
|
|
955
|
+
continue;
|
|
956
|
+
const extracted = await extractDataUriImagesFromHtml(html);
|
|
957
|
+
if (extracted.length === 0)
|
|
958
|
+
continue;
|
|
959
|
+
deferred.add(htmlSeedLocalId.trim());
|
|
960
|
+
for (const ent of extracted) {
|
|
961
|
+
const { seedLocalId: imageSeedLocalId } = await createImageItemFromDataUri(ent.dataUri);
|
|
962
|
+
const now = Date.now();
|
|
963
|
+
await appDb.insert(htmlEmbeddedImageCoPublish).values({
|
|
964
|
+
parentSeedLocalId: item.seedLocalId,
|
|
965
|
+
htmlSeedLocalId: htmlSeedLocalId.trim(),
|
|
966
|
+
imageSeedLocalId,
|
|
967
|
+
stableKey: ent.stableKey,
|
|
968
|
+
createdAt: now,
|
|
969
|
+
}).onConflictDoNothing();
|
|
970
|
+
}
|
|
698
971
|
}
|
|
699
|
-
return out;
|
|
700
972
|
}
|
|
701
|
-
|
|
973
|
+
function normalizeDataTypeLocal(dt) {
|
|
974
|
+
if (!dt)
|
|
975
|
+
return '';
|
|
976
|
+
return dt.charAt(0).toUpperCase() + dt.slice(1).toLowerCase();
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* After phase-1 uploads, rewrite Html files on disk: data URI → Arweave gateway URL, and
|
|
980
|
+
* `seed:property/<name>` → the gateway URL of that property's upload.
|
|
981
|
+
*
|
|
982
|
+
* `deferredHtmlSeedLocalIds` (from {@link prepareHtmlEmbeddedImagesForPublish}) limits the rewrite to
|
|
983
|
+
* the Html held back from phase 1; without it, every Html of the item and its co-published drafts is
|
|
984
|
+
* considered.
|
|
985
|
+
*/
|
|
986
|
+
async function rewriteHtmlEmbeddedImagesOnDisk(parentSeedLocalId, uploadedTransactions, deferredHtmlSeedLocalIds) {
|
|
702
987
|
const appDb = BaseDb.getAppDb();
|
|
703
988
|
if (!appDb)
|
|
704
989
|
return;
|
|
990
|
+
const parentItem = await Item.find({ seedLocalId: parentSeedLocalId });
|
|
991
|
+
if (!parentItem)
|
|
992
|
+
return;
|
|
993
|
+
const txBySeedLocalId = new Map();
|
|
994
|
+
for (const u of uploadedTransactions) {
|
|
995
|
+
if (u.seedLocalId && u.txId) {
|
|
996
|
+
txBySeedLocalId.set(u.seedLocalId.trim(), u.txId.trim());
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
const deferred = deferredHtmlSeedLocalIds
|
|
1000
|
+
? new Set(deferredHtmlSeedLocalIds.map((id) => id.trim()))
|
|
1001
|
+
: undefined;
|
|
1002
|
+
// The parent's Html and that of the draft items published with it (see prepareHtmlEmbeddedImagesForPublish).
|
|
1003
|
+
for (const item of [parentItem, ...(await getRelatedDraftsCoPublishedWith(parentItem))]) {
|
|
1004
|
+
await rewriteHtmlEmbeddedImagesOfItem(appDb, item, txBySeedLocalId, deferred);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
async function rewriteHtmlEmbeddedImagesOfItem(appDb, parentItem, txBySeedLocalId, deferred) {
|
|
705
1008
|
const rows = await appDb
|
|
706
1009
|
.select()
|
|
707
1010
|
.from(htmlEmbeddedImageCoPublish)
|
|
708
|
-
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId,
|
|
709
|
-
for (const
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
const { Item } = _ns_1;
|
|
713
|
-
const imageItem = await Item.find({
|
|
714
|
-
seedLocalId: row.imageSeedLocalId,
|
|
715
|
-
modelName: 'Image',
|
|
716
|
-
});
|
|
717
|
-
if (!imageItem)
|
|
1011
|
+
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentItem.seedLocalId));
|
|
1012
|
+
for (const p of parentItem.properties) {
|
|
1013
|
+
const def = p.propertyDef;
|
|
1014
|
+
if (!def || normalizeDataTypeLocal(def.dataType) !== ModelPropertyDataTypes.Html)
|
|
718
1015
|
continue;
|
|
719
|
-
const
|
|
720
|
-
|
|
721
|
-
const
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
const { itemBasicProperties, itemRelationProperties, itemListProperties, itemUploadProperties, itemImageProperties, } = await getSegmentedItemProperties(item);
|
|
741
|
-
await collectUploadBytes(item, itemUploadProperties, itemImageProperties, undefined, acc, seenUploads);
|
|
742
|
-
for (const rel of itemRelationProperties) {
|
|
743
|
-
const related = await relatedIfUnpublished(rel);
|
|
744
|
-
if (related) {
|
|
745
|
-
await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited);
|
|
1016
|
+
const snap = p.getService().getSnapshot();
|
|
1017
|
+
const ctx = 'context' in snap ? snap.context : null;
|
|
1018
|
+
const htmlSeedLocalId = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
|
|
1019
|
+
const refResolved = ctx?.refResolvedValue;
|
|
1020
|
+
if (!htmlSeedLocalId || !refResolved)
|
|
1021
|
+
continue;
|
|
1022
|
+
if (deferred && !deferred.has(htmlSeedLocalId))
|
|
1023
|
+
continue;
|
|
1024
|
+
const htmlRows = rows.filter((r) => String(r.htmlSeedLocalId).trim() === htmlSeedLocalId);
|
|
1025
|
+
const filePath = `${BaseFileManager.getFilesPath('html')}/${refResolved}`;
|
|
1026
|
+
if (!(await BaseFileManager.pathExists(filePath)))
|
|
1027
|
+
continue;
|
|
1028
|
+
const html = await BaseFileManager.readFileAsString(filePath);
|
|
1029
|
+
const replacements = new Map();
|
|
1030
|
+
for (const r of htmlRows) {
|
|
1031
|
+
const txId = txBySeedLocalId.get(r.imageSeedLocalId.trim());
|
|
1032
|
+
if (!txId)
|
|
1033
|
+
continue;
|
|
1034
|
+
const dataUri = await findDataUriForStableKey(html, r.stableKey);
|
|
1035
|
+
if (dataUri)
|
|
1036
|
+
replacements.set(dataUri, getArweaveUrlForTransaction(txId));
|
|
746
1037
|
}
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
1038
|
+
const urlByPropertyName = new Map();
|
|
1039
|
+
for (const name of findSeedPropertyRefsInHtml(html)) {
|
|
1040
|
+
const txId = await resolveSeedPropertyRefTxId(parentItem, name, txBySeedLocalId);
|
|
1041
|
+
urlByPropertyName.set(name, getArweaveUrlForTransaction(txId));
|
|
751
1042
|
}
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
const attestable = [
|
|
755
|
-
...itemBasicProperties,
|
|
756
|
-
...itemRelationProperties,
|
|
757
|
-
...itemListProperties,
|
|
758
|
-
...itemImageProperties,
|
|
759
|
-
...itemUploadProperties.map((u) => u.itemProperty),
|
|
760
|
-
];
|
|
761
|
-
const seenProps = new Set();
|
|
762
|
-
for (const prop of attestable) {
|
|
763
|
-
const key = prop.localId || `${prop.propertyName}:${prop.seedLocalId}`;
|
|
764
|
-
if (seenProps.has(key))
|
|
1043
|
+
const newHtml = replaceSeedPropertyRefsInHtml(replaceDataUrisInParsedHtml(html, replacements), urlByPropertyName);
|
|
1044
|
+
if (newHtml === html)
|
|
765
1045
|
continue;
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
1046
|
+
try {
|
|
1047
|
+
await BaseFileManager.saveFile(filePath, newHtml);
|
|
1048
|
+
}
|
|
1049
|
+
catch {
|
|
1050
|
+
const fs = await BaseFileManager.getFs();
|
|
1051
|
+
fs.writeFileSync(filePath, newHtml);
|
|
1052
|
+
}
|
|
1053
|
+
p.getService().send({
|
|
1054
|
+
type: 'updateContext',
|
|
1055
|
+
renderValue: newHtml,
|
|
1056
|
+
});
|
|
769
1057
|
}
|
|
770
1058
|
}
|
|
1059
|
+
async function findDataUriForStableKey(html, stableKey) {
|
|
1060
|
+
const entries = await extractDataUriImagesFromHtml(html);
|
|
1061
|
+
const hit = entries.find((e) => e.stableKey === stableKey);
|
|
1062
|
+
return hit?.dataUri;
|
|
1063
|
+
}
|
|
771
1064
|
/**
|
|
772
|
-
*
|
|
773
|
-
* and Arweave upload byte totals. Does not hit the network or create transactions.
|
|
1065
|
+
* Remove co-publish rows after a successful publish for this parent seed.
|
|
774
1066
|
*/
|
|
775
|
-
|
|
776
|
-
const
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
newVersionCount: 0,
|
|
783
|
-
attestationCount: 0,
|
|
784
|
-
uploadCount: 0,
|
|
785
|
-
uploadBytes: 0,
|
|
786
|
-
};
|
|
787
|
-
await summarizeItem(item, publishMode, forceFullSnapshot, acc, new Set(), new Set());
|
|
788
|
-
return acc;
|
|
789
|
-
};
|
|
790
|
-
|
|
791
|
-
const HTML_EMBEDDED_MAX_IMAGES_PER_DOC = 50;
|
|
792
|
-
const HTML_EMBEDDED_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
793
|
-
const HTML_EMBEDDED_MAX_TOTAL_BYTES = 25 * 1024 * 1024;
|
|
794
|
-
const DATA_URI_IMAGE = /^data:(image\/[a-zA-Z0-9.+-]+);base64,([\s\S]*)$/i;
|
|
795
|
-
const MIME_NORMALIZE = {
|
|
796
|
-
'image/jpg': 'image/jpeg',
|
|
797
|
-
};
|
|
798
|
-
function normalizeMime(m) {
|
|
799
|
-
const lower = m.toLowerCase().trim();
|
|
800
|
-
return MIME_NORMALIZE[lower] ?? lower;
|
|
1067
|
+
async function clearHtmlEmbeddedImageCoPublishRows(parentSeedLocalId) {
|
|
1068
|
+
const appDb = BaseDb.getAppDb();
|
|
1069
|
+
if (!appDb || !parentSeedLocalId)
|
|
1070
|
+
return;
|
|
1071
|
+
await appDb
|
|
1072
|
+
.delete(htmlEmbeddedImageCoPublish)
|
|
1073
|
+
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, parentSeedLocalId.trim()));
|
|
801
1074
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
super(message);
|
|
812
|
-
this.name = 'HtmlEmbeddedDataUriLimitError';
|
|
813
|
-
}
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Counts seeds, property attestations, and Arweave upload bytes for a publish
|
|
1078
|
+
* without building transactions or requiring a valid payload.
|
|
1079
|
+
*/
|
|
1080
|
+
const DATA_URI = /^data:[^;]+;base64,([\s\S]*)$/i;
|
|
1081
|
+
const matchesDataType = (actual, expected) => normalizeDataType(actual) === expected;
|
|
1082
|
+
function isZeroUid(uid) {
|
|
1083
|
+
return !uid || uid === ZERO_BYTES32;
|
|
814
1084
|
}
|
|
815
|
-
function
|
|
816
|
-
|
|
817
|
-
if (fromProp === 'materialize' || fromProp === 'preserve')
|
|
818
|
-
return fromProp;
|
|
819
|
-
if (publishLevel === 'materialize' || publishLevel === 'preserve')
|
|
820
|
-
return publishLevel;
|
|
821
|
-
return 'materialize';
|
|
1085
|
+
function isStorageTransactionPropertyName(name) {
|
|
1086
|
+
return name === 'storageTransactionId' || name === 'storage_transaction_id';
|
|
822
1087
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
1088
|
+
/** Decoded byte length of a data-URI, or null if the string is not a base64 data URI. */
|
|
1089
|
+
function estimateDataUriByteLength(dataUri) {
|
|
1090
|
+
const m = DATA_URI.exec((dataUri ?? '').trim());
|
|
1091
|
+
if (!m)
|
|
1092
|
+
return null;
|
|
1093
|
+
const b64 = m[1].replace(/\s/g, '');
|
|
1094
|
+
if (!b64)
|
|
1095
|
+
return 0;
|
|
1096
|
+
const padding = b64.endsWith('==') ? 2 : b64.endsWith('=') ? 1 : 0;
|
|
1097
|
+
return Math.max(0, Math.floor((b64.length * 3) / 4) - padding);
|
|
826
1098
|
}
|
|
827
|
-
function
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
node.attrs[i].value = value;
|
|
833
|
-
else
|
|
834
|
-
node.attrs.push({ name, value });
|
|
1099
|
+
function propertyContext(prop) {
|
|
1100
|
+
const snapshot = prop.getService().getSnapshot();
|
|
1101
|
+
return snapshot && 'context' in snapshot
|
|
1102
|
+
? (snapshot.context ?? null)
|
|
1103
|
+
: null;
|
|
835
1104
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
857
|
-
let binary;
|
|
858
|
-
try {
|
|
859
|
-
const b64 = m[2].replace(/\s/g, '');
|
|
860
|
-
binary = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
861
|
-
}
|
|
862
|
-
catch {
|
|
863
|
-
throw new HtmlEmbeddedDataUriLimitError('Invalid base64 in embedded image data URI');
|
|
864
|
-
}
|
|
865
|
-
const byteLength = binary.byteLength;
|
|
866
|
-
if (byteLength > HTML_EMBEDDED_MAX_IMAGE_BYTES) {
|
|
867
|
-
throw new HtmlEmbeddedDataUriLimitError(`Embedded image exceeds max size (${HTML_EMBEDDED_MAX_IMAGE_BYTES} bytes)`);
|
|
868
|
-
}
|
|
869
|
-
totalBytes += byteLength;
|
|
870
|
-
if (totalBytes > HTML_EMBEDDED_MAX_TOTAL_BYTES) {
|
|
871
|
-
throw new HtmlEmbeddedDataUriLimitError(`Total embedded image size exceeds max (${HTML_EMBEDDED_MAX_TOTAL_BYTES} bytes)`);
|
|
872
|
-
}
|
|
873
|
-
if (!seenUris.has(src)) {
|
|
874
|
-
if (seenUris.size >= HTML_EMBEDDED_MAX_IMAGES_PER_DOC) {
|
|
875
|
-
throw new HtmlEmbeddedDataUriLimitError(`Too many distinct embedded images (max ${HTML_EMBEDDED_MAX_IMAGES_PER_DOC})`);
|
|
876
|
-
}
|
|
877
|
-
seenUris.add(src);
|
|
878
|
-
const stableKey = await getContentHash(binary);
|
|
879
|
-
found.push({ dataUri: src, stableKey, byteLength, mimeType: mimeRaw });
|
|
880
|
-
}
|
|
881
|
-
}
|
|
1105
|
+
function getPublishValue(prop, context) {
|
|
1106
|
+
const propertyDef = prop.propertyDef ?? context.propertyRecordSchema;
|
|
1107
|
+
const isFileImageHtml = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.File) ||
|
|
1108
|
+
matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Image) ||
|
|
1109
|
+
matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Html);
|
|
1110
|
+
const isJsonStorage = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Json) ||
|
|
1111
|
+
matchesDataType(propertyDef?.refValueType, ModelPropertyDataTypes.Json);
|
|
1112
|
+
const isRelation = matchesDataType(propertyDef?.dataType, ModelPropertyDataTypes.Relation);
|
|
1113
|
+
const isStorageTransactionIdProp = isStorageTransactionPropertyName(prop.propertyName);
|
|
1114
|
+
const preferPropertyValue = isFileImageHtml || isRelation || isJsonStorage || isStorageTransactionIdProp;
|
|
1115
|
+
let value = preferPropertyValue
|
|
1116
|
+
? context.propertyValue
|
|
1117
|
+
: (prop.value ?? context.propertyValue);
|
|
1118
|
+
if (isRelation || isFileImageHtml || isJsonStorage) {
|
|
1119
|
+
const pv = context.propertyValue;
|
|
1120
|
+
if (typeof value === 'object' || value == null) {
|
|
1121
|
+
if (typeof pv === 'string' && pv.trim())
|
|
1122
|
+
value = pv.trim();
|
|
1123
|
+
else if (pv && typeof pv === 'object' && typeof pv.seedLocalId === 'string') {
|
|
1124
|
+
value = pv.seedLocalId;
|
|
882
1125
|
}
|
|
883
1126
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
for (const c of parent.childNodes)
|
|
887
|
-
await walk(c);
|
|
888
|
-
}
|
|
889
|
-
};
|
|
890
|
-
for (const c of fragment.childNodes)
|
|
891
|
-
await walk(c);
|
|
892
|
-
return found;
|
|
1127
|
+
}
|
|
1128
|
+
return value;
|
|
893
1129
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
if (
|
|
899
|
-
return
|
|
900
|
-
const
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
const
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
const parent = el;
|
|
912
|
-
if (parent.childNodes) {
|
|
913
|
-
for (const c of parent.childNodes)
|
|
914
|
-
walk(c);
|
|
915
|
-
}
|
|
916
|
-
};
|
|
917
|
-
for (const c of fragment.childNodes)
|
|
918
|
-
walk(c);
|
|
919
|
-
return serialize(fragment);
|
|
1130
|
+
function shouldAttestProperty(prop, forceFullSnapshot) {
|
|
1131
|
+
if (INTERNAL_PROPERTY_NAMES.includes(prop.propertyName))
|
|
1132
|
+
return false;
|
|
1133
|
+
const context = propertyContext(prop);
|
|
1134
|
+
if (!context)
|
|
1135
|
+
return false;
|
|
1136
|
+
const value = getPublishValue(prop, context);
|
|
1137
|
+
if (value == null || value === '')
|
|
1138
|
+
return false;
|
|
1139
|
+
if (prop.uid && !forceFullSnapshot) {
|
|
1140
|
+
const allowStorageTx = isStorageTransactionPropertyName(prop.propertyName) &&
|
|
1141
|
+
typeof value === 'string' &&
|
|
1142
|
+
value.trim() !== '';
|
|
1143
|
+
if (!allowStorageTx)
|
|
1144
|
+
return false;
|
|
1145
|
+
}
|
|
1146
|
+
return true;
|
|
920
1147
|
}
|
|
921
|
-
|
|
922
|
-
|
|
1148
|
+
function getStorageDirForDataType(dataType) {
|
|
1149
|
+
switch (normalizeDataType(dataType)) {
|
|
1150
|
+
case 'Image':
|
|
1151
|
+
return BaseFileManager.getFilesPath('images');
|
|
1152
|
+
case 'File':
|
|
1153
|
+
return BaseFileManager.getFilesPath('files');
|
|
1154
|
+
case 'Html':
|
|
1155
|
+
return BaseFileManager.getFilesPath('html');
|
|
1156
|
+
case 'Json':
|
|
1157
|
+
return BaseFileManager.getFilesPath('json');
|
|
1158
|
+
default:
|
|
1159
|
+
return BaseFileManager.getFilesPath('images');
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
async function addUpload(acc, seen, key, bytes) {
|
|
1163
|
+
if (bytes <= 0 || seen.has(key))
|
|
923
1164
|
return;
|
|
924
|
-
|
|
1165
|
+
seen.add(key);
|
|
1166
|
+
acc.uploadCount += 1;
|
|
1167
|
+
acc.uploadBytes += bytes;
|
|
925
1168
|
}
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
await waitForEntityIdle(imageItem, { timeout: 60000 });
|
|
934
|
-
const st = imageItem.internalProperties['storageTransactionId'] ??
|
|
935
|
-
imageItem.allProperties['storageTransactionId'];
|
|
936
|
-
if (!st) {
|
|
937
|
-
throw new Error('Image item missing storageTransactionId property');
|
|
938
|
-
}
|
|
939
|
-
st.value = dataUri;
|
|
940
|
-
await st.save();
|
|
941
|
-
await waitForEntityIdle(imageItem, { timeout: 60000 });
|
|
942
|
-
return { seedLocalId: imageItem.seedLocalId };
|
|
1169
|
+
async function addUploadFromPath(acc, seen, filePath, key) {
|
|
1170
|
+
if (!filePath || filePath.endsWith('undefined'))
|
|
1171
|
+
return;
|
|
1172
|
+
const size = await BaseFileManager.getFileSize(filePath);
|
|
1173
|
+
if (size == null || size <= 0)
|
|
1174
|
+
return;
|
|
1175
|
+
await addUpload(acc, seen, key, size);
|
|
943
1176
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1177
|
+
async function collectUploadBytes(item, itemUploadProperties, itemImageProperties, relatedItemProperty, acc, seen) {
|
|
1178
|
+
for (const uploadProperty of itemUploadProperties) {
|
|
1179
|
+
let childBytes = 0;
|
|
1180
|
+
let childCount = 0;
|
|
1181
|
+
for (const childProperty of uploadProperty.childProperties) {
|
|
1182
|
+
const filePath = childProperty.localStoragePath;
|
|
1183
|
+
if (!filePath || filePath.endsWith('undefined'))
|
|
1184
|
+
continue;
|
|
1185
|
+
const size = await BaseFileManager.getFileSize(filePath);
|
|
1186
|
+
if (size == null || size <= 0)
|
|
1187
|
+
continue;
|
|
1188
|
+
childBytes += size;
|
|
1189
|
+
childCount += 1;
|
|
1190
|
+
}
|
|
1191
|
+
if (childCount > 0) {
|
|
1192
|
+
await addUpload(acc, seen, `upload:${item.seedLocalId}:${uploadProperty.itemProperty.localId}`, childBytes);
|
|
958
1193
|
continue;
|
|
959
|
-
|
|
960
|
-
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
for (const itemProperty of itemImageProperties) {
|
|
1197
|
+
const context = propertyContext(itemProperty);
|
|
1198
|
+
if (!context)
|
|
961
1199
|
continue;
|
|
962
|
-
const
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
const refResolved = ctx?.refResolvedValue;
|
|
966
|
-
if (!htmlSeedLocalId?.trim() || !refResolved)
|
|
1200
|
+
const refResolvedValue = (typeof context.refResolvedValue === 'string' && context.refResolvedValue) ||
|
|
1201
|
+
itemProperty.refResolvedValue;
|
|
1202
|
+
if (typeof refResolvedValue !== 'string' || !refResolvedValue)
|
|
967
1203
|
continue;
|
|
968
|
-
const
|
|
969
|
-
const
|
|
970
|
-
|
|
1204
|
+
const propertyValue = context.propertyValue;
|
|
1205
|
+
const { seedLocalId } = resolveSeedIdsFromRefString(normalizeRelationPropertyValue(propertyValue) ?? '');
|
|
1206
|
+
const dataType = itemProperty.propertyDef?.refValueType ??
|
|
1207
|
+
itemProperty.propertyDef?.dataType ??
|
|
1208
|
+
'Image';
|
|
1209
|
+
const fromGetter = itemProperty.localStoragePath;
|
|
1210
|
+
const filePath = typeof fromGetter === 'string' && fromGetter
|
|
1211
|
+
? fromGetter
|
|
1212
|
+
: `${getStorageDirForDataType(String(dataType))}/${refResolvedValue}`;
|
|
1213
|
+
await addUploadFromPath(acc, seen, filePath, seedLocalId ? `seed:${seedLocalId}` : `path:${filePath}`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
async function loadRelatedItem(value) {
|
|
1217
|
+
const normalized = normalizeRelationPropertyValue(value);
|
|
1218
|
+
if (!normalized)
|
|
1219
|
+
return undefined;
|
|
1220
|
+
const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(normalized);
|
|
1221
|
+
if (!seedLocalId && !seedUid)
|
|
1222
|
+
return undefined;
|
|
1223
|
+
const { getItem } = await import('./getItem-CSfSok9f.js');
|
|
1224
|
+
try {
|
|
1225
|
+
return await getItem({ seedLocalId, seedUid });
|
|
1226
|
+
}
|
|
1227
|
+
catch {
|
|
1228
|
+
return undefined;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
async function relatedIfUnpublished(prop) {
|
|
1232
|
+
const context = propertyContext(prop);
|
|
1233
|
+
if (!context)
|
|
1234
|
+
return undefined;
|
|
1235
|
+
const related = await loadRelatedItem(context.propertyValue);
|
|
1236
|
+
if (!related || !isZeroUid(related.seedUid))
|
|
1237
|
+
return undefined;
|
|
1238
|
+
return related;
|
|
1239
|
+
}
|
|
1240
|
+
/** Seed refs held by a relation/image property (one) or a list property (each member). */
|
|
1241
|
+
function seedRefsOf(prop, isList) {
|
|
1242
|
+
const context = propertyContext(prop);
|
|
1243
|
+
if (!context)
|
|
1244
|
+
return [];
|
|
1245
|
+
let value = context.propertyValue;
|
|
1246
|
+
if (isList) {
|
|
1247
|
+
if (typeof value === 'string')
|
|
1248
|
+
value = parseListPropertyValueFromStorage(value);
|
|
1249
|
+
return (Array.isArray(value) ? value : [])
|
|
1250
|
+
.map((v) => normalizeRelationPropertyValue(v))
|
|
1251
|
+
.filter((v) => !!v);
|
|
1252
|
+
}
|
|
1253
|
+
const ref = normalizeRelationPropertyValue(value);
|
|
1254
|
+
return ref ? [ref] : [];
|
|
1255
|
+
}
|
|
1256
|
+
/** Like getPublishPayload: attested refs to revoked seeds block the publish. */
|
|
1257
|
+
async function collectUnpublishedRelatedItems(props, isList, forceFullSnapshot, out, backReferences) {
|
|
1258
|
+
for (const prop of props) {
|
|
1259
|
+
if (!shouldAttestProperty(prop, forceFullSnapshot))
|
|
971
1260
|
continue;
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
html = new TextDecoder('utf-8', { fatal: false }).decode(buf);
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
const v = buf;
|
|
989
|
-
html = new TextDecoder('utf-8', { fatal: false }).decode(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));
|
|
1261
|
+
for (const ref of seedRefsOf(prop, isList)) {
|
|
1262
|
+
const { seedLocalId, seedUid } = resolveSeedIdsFromRefString(ref);
|
|
1263
|
+
if (!seedLocalId && !seedUid)
|
|
1264
|
+
continue;
|
|
1265
|
+
const row = await findRelatedSeedRow({ seedLocalId, seedUid });
|
|
1266
|
+
// A back reference to a seed this publish creates (e.g. a revoked root published again) is
|
|
1267
|
+
// left for a later publish, not attested (publishDraftGraph.ts)
|
|
1268
|
+
if (row && backReferences?.get(prop)?.has(row.seedLocalId))
|
|
1269
|
+
continue;
|
|
1270
|
+
if (!isUnpublishedSeed(row))
|
|
1271
|
+
continue;
|
|
1272
|
+
if (out.some((r) => r.propertyName === prop.propertyName && r.seedLocalId === row.seedLocalId)) {
|
|
1273
|
+
continue;
|
|
990
1274
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
throw e;
|
|
999
|
-
throw e;
|
|
1000
|
-
}
|
|
1001
|
-
if (extracted.length === 0)
|
|
1002
|
-
continue;
|
|
1003
|
-
deferred.add(htmlSeedLocalId.trim());
|
|
1004
|
-
for (const ent of extracted) {
|
|
1005
|
-
const { seedLocalId: imageSeedLocalId } = await createImageItemFromDataUri(ent.dataUri);
|
|
1006
|
-
const now = Date.now();
|
|
1007
|
-
await appDb.insert(htmlEmbeddedImageCoPublish).values({
|
|
1008
|
-
parentSeedLocalId: item.seedLocalId,
|
|
1009
|
-
htmlSeedLocalId: htmlSeedLocalId.trim(),
|
|
1010
|
-
imageSeedLocalId,
|
|
1011
|
-
stableKey: ent.stableKey,
|
|
1012
|
-
createdAt: now,
|
|
1013
|
-
}).onConflictDoNothing();
|
|
1275
|
+
const related = await loadRelatedItem(row.seedLocalId);
|
|
1276
|
+
out.push({
|
|
1277
|
+
propertyName: prop.propertyName,
|
|
1278
|
+
modelName: related?.modelName ?? relatedModelNameFromDef(prop.propertyDef) ?? row.type ?? 'unknown',
|
|
1279
|
+
seedLocalId: row.seedLocalId,
|
|
1280
|
+
seedUid: row.seedUid,
|
|
1281
|
+
});
|
|
1014
1282
|
}
|
|
1015
1283
|
}
|
|
1016
|
-
return { deferredHtmlSeedLocalIds: [...deferred] };
|
|
1017
|
-
}
|
|
1018
|
-
function normalizeDataTypeLocal(dt) {
|
|
1019
|
-
if (!dt)
|
|
1020
|
-
return '';
|
|
1021
|
-
return dt.charAt(0).toUpperCase() + dt.slice(1).toLowerCase();
|
|
1022
1284
|
}
|
|
1023
1285
|
/**
|
|
1024
|
-
*
|
|
1286
|
+
* Images embedded in Html properties (co-published) whose seed was revoked: getPublishPayload rejects
|
|
1287
|
+
* them like image properties pointing at revoked seeds. Like getPublishPayload, checks the published
|
|
1288
|
+
* item's co-publish rows and those of the draft items published with it.
|
|
1025
1289
|
*/
|
|
1026
|
-
async function
|
|
1290
|
+
async function collectUnpublishedEmbeddedImages(item, out) {
|
|
1291
|
+
const appDb = BaseDb.getAppDb();
|
|
1292
|
+
if (!appDb || !item.seedLocalId)
|
|
1293
|
+
return;
|
|
1294
|
+
for (const owner of [item, ...(await getRelatedDraftsCoPublishedWith(item))]) {
|
|
1295
|
+
const rows = await appDb
|
|
1296
|
+
.select()
|
|
1297
|
+
.from(htmlEmbeddedImageCoPublish)
|
|
1298
|
+
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, owner.seedLocalId));
|
|
1299
|
+
for (const row of rows) {
|
|
1300
|
+
const seed = await findRelatedSeedRow({ seedLocalId: row.imageSeedLocalId });
|
|
1301
|
+
if (!isUnpublishedSeed(seed))
|
|
1302
|
+
continue;
|
|
1303
|
+
const propertyName = htmlPropertyNameForHtmlSeed(owner, row.htmlSeedLocalId);
|
|
1304
|
+
if (out.some((r) => r.propertyName === propertyName && r.seedLocalId === seed.seedLocalId))
|
|
1305
|
+
continue;
|
|
1306
|
+
out.push({ propertyName, modelName: 'Image', seedLocalId: seed.seedLocalId, seedUid: seed.seedUid });
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
async function appendCoPublishImages(item, acc, seen, visited, forceFullSnapshot, publishMode, graph) {
|
|
1027
1311
|
const appDb = BaseDb.getAppDb();
|
|
1028
1312
|
if (!appDb)
|
|
1029
1313
|
return;
|
|
1030
1314
|
const rows = await appDb
|
|
1031
1315
|
.select()
|
|
1032
1316
|
.from(htmlEmbeddedImageCoPublish)
|
|
1033
|
-
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId,
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1317
|
+
.where(eq(htmlEmbeddedImageCoPublish.parentSeedLocalId, item.seedLocalId));
|
|
1318
|
+
for (const row of rows) {
|
|
1319
|
+
const _mod_2 = await import('./Item-ZUAmf943.js');
|
|
1320
|
+
const _ns_2 = _mod_2.Z;
|
|
1321
|
+
const { Item } = _ns_2;
|
|
1322
|
+
const imageItem = await Item.find({
|
|
1323
|
+
seedLocalId: row.imageSeedLocalId,
|
|
1324
|
+
modelName: 'Image',
|
|
1325
|
+
});
|
|
1326
|
+
// Like getPublishPayload: an embedded image that already has a seed (published, or unpublished
|
|
1327
|
+
// and reported by collectUnpublishedEmbeddedImages) is not co-published.
|
|
1328
|
+
if (!imageItem || !isZeroUid(imageItem.seedUid))
|
|
1329
|
+
continue;
|
|
1330
|
+
const st = imageItem.internalProperties['storageTransactionId'] ??
|
|
1331
|
+
imageItem.allProperties['storageTransactionId'];
|
|
1332
|
+
const stCtx = st ? propertyContext(st) : null;
|
|
1333
|
+
const stValue = typeof stCtx?.propertyValue === 'string' ? stCtx.propertyValue : '';
|
|
1334
|
+
const dataUriBytes = estimateDataUriByteLength(stValue);
|
|
1335
|
+
if (dataUriBytes != null && dataUriBytes > 0) {
|
|
1336
|
+
await addUpload(acc, seen, `seed:${imageItem.seedLocalId}`, dataUriBytes);
|
|
1040
1337
|
}
|
|
1338
|
+
await summarizeItem(imageItem, publishMode, forceFullSnapshot, acc, seen, visited, graph);
|
|
1041
1339
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
const
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1340
|
+
}
|
|
1341
|
+
async function summarizeItem(item, publishMode, forceFullSnapshot, acc, seenUploads, visited, graph) {
|
|
1342
|
+
const seedLocalId = item.seedLocalId;
|
|
1343
|
+
if (!seedLocalId || visited.has(seedLocalId))
|
|
1344
|
+
return;
|
|
1345
|
+
visited.add(seedLocalId);
|
|
1346
|
+
acc.seedCount += 1;
|
|
1347
|
+
if (isZeroUid(item.seedUid))
|
|
1348
|
+
acc.newSeedCount += 1;
|
|
1349
|
+
if (isZeroUid(item.seedUid) || forceFullSnapshot)
|
|
1350
|
+
acc.newVersionCount += 1;
|
|
1351
|
+
const { itemBasicProperties, itemRelationProperties, itemListProperties, itemUploadProperties, itemImageProperties, } = await getSegmentedItemProperties(item);
|
|
1352
|
+
await collectUploadBytes(item, itemUploadProperties, itemImageProperties, undefined, acc, seenUploads);
|
|
1353
|
+
await collectUnpublishedRelatedItems([...itemRelationProperties, ...itemImageProperties], false, forceFullSnapshot, acc.unpublishedRelatedItems, graph.backReferences);
|
|
1354
|
+
await collectUnpublishedRelatedItems(itemListProperties, true, forceFullSnapshot, acc.unpublishedRelatedItems, graph.backReferences);
|
|
1355
|
+
// Draft Image/File/Html/Json items its storage relations point at. Draft model items its relations
|
|
1356
|
+
// and lists reach are summarized by summarizePublishWork from the publish's draft graph.
|
|
1357
|
+
const storageProperties = new Set(itemImageProperties);
|
|
1358
|
+
for (const rel of itemRelationProperties) {
|
|
1359
|
+
if (!storageProperties.has(rel))
|
|
1360
|
+
continue;
|
|
1361
|
+
const related = await relatedIfUnpublished(rel);
|
|
1362
|
+
if (related) {
|
|
1363
|
+
await summarizeItem(related, publishMode, forceFullSnapshot, acc, seenUploads, visited, graph);
|
|
1056
1364
|
}
|
|
1057
1365
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1366
|
+
await appendCoPublishImages(item, acc, seenUploads, visited, forceFullSnapshot, publishMode, graph);
|
|
1367
|
+
const attestable = [
|
|
1368
|
+
...itemBasicProperties,
|
|
1369
|
+
...itemRelationProperties,
|
|
1370
|
+
...itemListProperties,
|
|
1371
|
+
...itemImageProperties,
|
|
1372
|
+
...itemUploadProperties.map((u) => u.itemProperty),
|
|
1373
|
+
];
|
|
1374
|
+
const seenProps = new Set();
|
|
1375
|
+
for (const prop of attestable) {
|
|
1376
|
+
const key = prop.localId || `${prop.propertyName}:${prop.seedLocalId}`;
|
|
1377
|
+
if (seenProps.has(key))
|
|
1064
1378
|
continue;
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
if (String(r.htmlSeedLocalId).trim() !== htmlSeedLocalId)
|
|
1069
|
-
continue;
|
|
1070
|
-
const txId = txByImageSeed.get(r.imageSeedLocalId.trim());
|
|
1071
|
-
if (!txId)
|
|
1072
|
-
continue;
|
|
1073
|
-
const dataUri = await findDataUriForStableKey(html, r.stableKey);
|
|
1074
|
-
if (dataUri)
|
|
1075
|
-
replacements.set(dataUri, getArweaveUrlForTransaction(txId));
|
|
1076
|
-
}
|
|
1077
|
-
if (replacements.size === 0)
|
|
1379
|
+
seenProps.add(key);
|
|
1380
|
+
// A ref back to an item this publish creates is left for a later publish (publishDraftGraph.ts).
|
|
1381
|
+
if (graph.deferredProperties.has(prop))
|
|
1078
1382
|
continue;
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
await BaseFileManager.saveFile(filePath, newHtml);
|
|
1082
|
-
}
|
|
1083
|
-
catch {
|
|
1084
|
-
const fs = await BaseFileManager.getFs();
|
|
1085
|
-
fs.writeFileSync(filePath, newHtml);
|
|
1086
|
-
}
|
|
1087
|
-
if (parentItem) {
|
|
1088
|
-
for (const p of parentItem.properties) {
|
|
1089
|
-
const snap = p.getService().getSnapshot();
|
|
1090
|
-
const ctx = 'context' in snap ? snap.context : null;
|
|
1091
|
-
const pv = typeof ctx?.propertyValue === 'string' ? ctx.propertyValue.trim() : '';
|
|
1092
|
-
if (pv === htmlSeedLocalId) {
|
|
1093
|
-
p.getService().send({
|
|
1094
|
-
type: 'updateContext',
|
|
1095
|
-
renderValue: newHtml,
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1383
|
+
if (shouldAttestProperty(prop, forceFullSnapshot))
|
|
1384
|
+
acc.attestationCount += 1;
|
|
1100
1385
|
}
|
|
1101
1386
|
}
|
|
1102
|
-
async function findDataUriForStableKey(html, stableKey) {
|
|
1103
|
-
const entries = await extractDataUriImagesFromHtml(html);
|
|
1104
|
-
const hit = entries.find((e) => e.stableKey === stableKey);
|
|
1105
|
-
return hit?.dataUri;
|
|
1106
|
-
}
|
|
1107
1387
|
/**
|
|
1108
|
-
*
|
|
1388
|
+
* Local measurement of what a publish would do: seed/version/attestation counts
|
|
1389
|
+
* and Arweave upload byte totals. Does not hit the network or create transactions.
|
|
1109
1390
|
*/
|
|
1110
|
-
async
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1391
|
+
const publishForcesFullSnapshot = async (item, publishMode) => {
|
|
1392
|
+
// Like getPublishPayload: an item whose seed was revoked republishes as a new seed with a full
|
|
1393
|
+
// snapshot.
|
|
1394
|
+
const republishRevokedSeed = !isZeroUid(item.seedUid) && (await isSeedRevoked(item.seedLocalId));
|
|
1395
|
+
return { republishRevokedSeed, forceFullSnapshot: publishMode === 'new_version' || republishRevokedSeed };
|
|
1396
|
+
};
|
|
1397
|
+
async function collectUnpublishedRelatedItemsOf(item, forceFullSnapshot, out, backReferences) {
|
|
1398
|
+
const { itemRelationProperties, itemListProperties, itemImageProperties } = await getSegmentedItemProperties(item);
|
|
1399
|
+
await collectUnpublishedRelatedItems([...itemRelationProperties, ...itemImageProperties], false, forceFullSnapshot, out, backReferences);
|
|
1400
|
+
await collectUnpublishedRelatedItems(itemListProperties, true, forceFullSnapshot, out, backReferences);
|
|
1117
1401
|
}
|
|
1402
|
+
/**
|
|
1403
|
+
* References a publish of `item` would attest to items whose seed was unpublished (revoked), the
|
|
1404
|
+
* same ones getPublishPayload rejects with RelatedItemUnpublishedError. Local reads only: the
|
|
1405
|
+
* publish package checks this before registering schemas or uploading anything.
|
|
1406
|
+
*/
|
|
1407
|
+
const getUnpublishedRelatedItems = async (item, options) => {
|
|
1408
|
+
const { forceFullSnapshot } = await publishForcesFullSnapshot(item, options?.publishMode ?? 'patch');
|
|
1409
|
+
const out = [];
|
|
1410
|
+
// The item and every draft its publish carries along (publishDraftGraph.ts).
|
|
1411
|
+
const { drafts, backReferences } = await getPublishDraftGraph(item, { forceFullSnapshot });
|
|
1412
|
+
for (const owner of [item, ...drafts.map((d) => d.item)]) {
|
|
1413
|
+
await collectUnpublishedRelatedItemsOf(owner, forceFullSnapshot, out, backReferences);
|
|
1414
|
+
}
|
|
1415
|
+
await collectUnpublishedEmbeddedImages(item, out);
|
|
1416
|
+
return out;
|
|
1417
|
+
};
|
|
1418
|
+
const summarizePublishWork = async (item, options) => {
|
|
1419
|
+
const publishMode = options?.publishMode ?? 'patch';
|
|
1420
|
+
const { republishRevokedSeed, forceFullSnapshot } = await publishForcesFullSnapshot(item, publishMode);
|
|
1421
|
+
const acc = {
|
|
1422
|
+
publishMode,
|
|
1423
|
+
seedCount: 0,
|
|
1424
|
+
newSeedCount: 0,
|
|
1425
|
+
newVersionCount: 0,
|
|
1426
|
+
attestationCount: 0,
|
|
1427
|
+
uploadCount: 0,
|
|
1428
|
+
uploadBytes: 0,
|
|
1429
|
+
unpublishedRelatedItems: [],
|
|
1430
|
+
};
|
|
1431
|
+
const graph = await getPublishDraftGraph(item, { forceFullSnapshot });
|
|
1432
|
+
const { drafts } = graph;
|
|
1433
|
+
const seenUploads = new Set();
|
|
1434
|
+
const visited = new Set();
|
|
1435
|
+
for (const owner of [item, ...drafts.map((d) => d.item)]) {
|
|
1436
|
+
await summarizeItem(owner, publishMode, forceFullSnapshot, acc, seenUploads, visited, graph);
|
|
1437
|
+
}
|
|
1438
|
+
await collectUnpublishedEmbeddedImages(item, acc.unpublishedRelatedItems);
|
|
1439
|
+
// summarizeItem counts the root as an existing seed (it has a seedUid).
|
|
1440
|
+
if (republishRevokedSeed)
|
|
1441
|
+
acc.newSeedCount += 1;
|
|
1442
|
+
return acc;
|
|
1443
|
+
};
|
|
1118
1444
|
|
|
1119
|
-
export { BaseDb, BaseFileManager, BaseFileManager as FileManager, HTML_EMBEDDED_MAX_IMAGES_PER_DOC, HTML_EMBEDDED_MAX_IMAGE_BYTES, HTML_EMBEDDED_MAX_TOTAL_BYTES, HtmlEmbeddedDataUriLimitError, Item, ModelPropertyDataTypes, applyArweaveL1TransactionIdLocal, applyPropertyAttestationUidsFromPublish, clearHtmlEmbeddedImageCoPublishRows, estimateDataUriByteLength, extractDataUriImagesFromHtml, getArweaveUrlForTransaction, getAttesterForSeed, getMetadataAttestationUidsForSeedUid, getPublishPendingDiff, getRelatedItemsForPublish, getSeedPublishState, getSegmentedItemProperties, getVersionsForSeedUid, htmlEmbeddedImageCoPublish, isDataType, metadata, normalizeDataType, normalizePublisher, normalizeRelationPropertyValue, prepareHtmlEmbeddedImagesForPublish, replaceDataUrisInParsedHtml, resolveEffectiveHtmlEmbeddedDataUriPolicy, resolveSeedIdsFromRefString, rewriteHtmlEmbeddedImagesOnDisk, seeds, shouldAttestProperty, summarizePublishWork, updateVersionUid, versions, waitForEntityIdle };
|
|
1445
|
+
export { BaseDb, BaseFileManager, BaseFileManager as FileManager, HTML_EMBEDDED_MAX_IMAGES_PER_DOC, HTML_EMBEDDED_MAX_IMAGE_BYTES, HTML_EMBEDDED_MAX_TOTAL_BYTES, HtmlEmbeddedDataUriLimitError, HtmlSeedPropertyRefError, Item, ModelPropertyDataTypes, SEED_PROPERTY_REF_PREFIX, applyArweaveL1TransactionIdLocal, applyPropertyAttestationUidsFromPublish, clearHtmlEmbeddedImageCoPublishRows, compareMetadataRowsLatestFirst, estimateDataUriByteLength, extractDataUriImagesFromHtml, findSeedPropertyRefsInHtml, generateId, getArweaveUrlForTransaction, getAttesterForSeed, getMetadataAttestationUidsForSeedUid, getPublishDraftGraph, getPublishPendingDiff, getRelatedItemsForPublish, getSeedPublishState, getSegmentedItemProperties, getUnpublishedRelatedItems, getVersionsForSeedUid, htmlEmbeddedImageCoPublish, isDataType, metadata, normalizeDataType, normalizePublisher, normalizeRelationPropertyValue, prepareHtmlEmbeddedImagesForPublish, replaceDataUrisInParsedHtml, replaceSeedPropertyRefsInHtml, resolveEffectiveHtmlEmbeddedDataUriPolicy, resolveSeedIdsFromRefString, rewriteHtmlEmbeddedImagesOnDisk, seeds, shouldAttestProperty, summarizePublishWork, updateVersionUid, versions, waitForEntityIdle };
|
|
1120
1446
|
//# sourceMappingURL=main.js.map
|