@seedprotocol/sdk 0.7.5-next.850.g9ab585b → 0.7.5

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.
Files changed (118) hide show
  1. package/dist/{BasePathResolver-CsZHPrk9.js → BasePathResolver-CBTXCMFL.js} +20 -6
  2. package/dist/BasePathResolver-CBTXCMFL.js.map +1 -0
  3. package/dist/{ClientManager-DETTj0_z.js → ClientManager-DRf4uuei.js} +348 -222
  4. package/dist/ClientManager-DRf4uuei.js.map +1 -0
  5. package/dist/{Item-TMrVEPeX.js → Item-DTJPMjFk.js} +241 -157
  6. package/dist/Item-DTJPMjFk.js.map +1 -0
  7. package/dist/{ModelProperty-Bw6N8OMK.js → ModelProperty-Dto5C0om.js} +66 -31
  8. package/dist/ModelProperty-Dto5C0om.js.map +1 -0
  9. package/dist/{Schema-VLenyJDy.js → Schema-8DxGcORY.js} +39 -37
  10. package/dist/{Schema-VLenyJDy.js.map → Schema-8DxGcORY.js.map} +1 -1
  11. package/dist/{SchemaValidationService-CLGadxgf.js → SchemaValidationService-CE92y1TT.js} +6 -6
  12. package/dist/{SchemaValidationService-CLGadxgf.js.map → SchemaValidationService-CE92y1TT.js.map} +1 -1
  13. package/dist/{backfillMetadataPropertyIds-C8fSvzy2.js → backfillMetadataPropertyIds-CRqp-BqX.js} +3 -3
  14. package/dist/{backfillMetadataPropertyIds-C8fSvzy2.js.map → backfillMetadataPropertyIds-CRqp-BqX.js.map} +1 -1
  15. package/dist/{configurePlatform-C3E0BS3u.js → configurePlatform-D4aGjKNk.js} +2 -2
  16. package/dist/{configurePlatform-C3E0BS3u.js.map → configurePlatform-D4aGjKNk.js.map} +1 -1
  17. package/dist/{detachRowsBeforeDelete-D1gTseFW.js → detachRowsBeforeDelete-BVetHtn2.js} +2 -2
  18. package/dist/{detachRowsBeforeDelete-D1gTseFW.js.map → detachRowsBeforeDelete-BVetHtn2.js.map} +1 -1
  19. package/dist/discardNewDraft-CEOouygG.js +78 -0
  20. package/dist/discardNewDraft-CEOouygG.js.map +1 -0
  21. package/dist/{eas-A82zVNQ9.js → eas-D7jvWMnI.js} +3 -3
  22. package/dist/{eas-A82zVNQ9.js.map → eas-D7jvWMnI.js.map} +1 -1
  23. package/dist/{errors-CWKup8tw.js → errors-CIrbsN_i.js} +46 -39
  24. package/dist/errors-CIrbsN_i.js.map +1 -0
  25. package/dist/{getItem-ChieGxJV.js → getItem-CxU_kT5W.js} +4 -4
  26. package/dist/{getItem-ChieGxJV.js.map → getItem-CxU_kT5W.js.map} +1 -1
  27. package/dist/{getPublishPayload-CWfjl8PM.js → getPublishPayload-DTjOKd3y.js} +13 -13
  28. package/dist/{getPublishPayload-CWfjl8PM.js.map → getPublishPayload-DTjOKd3y.js.map} +1 -1
  29. package/dist/{getPublishUploads-cLbSEXLk.js → getPublishUploads-CVTBo_OV.js} +506 -45
  30. package/dist/getPublishUploads-CVTBo_OV.js.map +1 -0
  31. package/dist/{index-CXkcz4hT.js → index-CMxEil8T.js} +8 -8
  32. package/dist/index-CMxEil8T.js.map +1 -0
  33. package/dist/{index-CURf9L4d.js → index-DWK-LOUY.js} +2 -2
  34. package/dist/index-DWK-LOUY.js.map +1 -0
  35. package/dist/{index.browser-47W0fJPw.js → index.browser-shRXMeB3.js} +11 -11
  36. package/dist/{index.browser-47W0fJPw.js.map → index.browser-shRXMeB3.js.map} +1 -1
  37. package/dist/{index.node-BiQhZQvH.js → index.node-DAKJNYp5.js} +20 -6
  38. package/dist/index.node-DAKJNYp5.js.map +1 -0
  39. package/dist/main.js +89 -504
  40. package/dist/main.js.map +1 -1
  41. package/dist/{mimeTypes-DHAHC4eZ.js → mimeTypes-C9r76DCH.js} +7 -2
  42. package/dist/{mimeTypes-DHAHC4eZ.js.map → mimeTypes-C9r76DCH.js.map} +1 -1
  43. package/dist/node.js +10 -10
  44. package/dist/platform.browser.js +6 -6
  45. package/dist/platform.node.js +4 -4
  46. package/dist/{property-tgPI5hMu.js → property-lz9yIpyA.js} +6 -6
  47. package/dist/{property-tgPI5hMu.js.map → property-lz9yIpyA.js.map} +1 -1
  48. package/dist/{propertyValidationRules-BLVxTejW.js → propertyValidationRules-LuIwoQoJ.js} +6 -6
  49. package/dist/{propertyValidationRules-BLVxTejW.js.map → propertyValidationRules-LuIwoQoJ.js.map} +1 -1
  50. package/dist/{publishDraftGraph-FAfecR_4.js → publishDraftGraph-CgSLPKvQ.js} +6 -6
  51. package/dist/{publishDraftGraph-FAfecR_4.js.map → publishDraftGraph-CgSLPKvQ.js.map} +1 -1
  52. package/dist/{resetAmbiguousLegacyItemData-kz2PYdZi.js → resetAmbiguousLegacyItemData-CuamkAAh.js} +2 -2
  53. package/dist/{resetAmbiguousLegacyItemData-kz2PYdZi.js.map → resetAmbiguousLegacyItemData-CuamkAAh.js.map} +1 -1
  54. package/dist/{resolveModelForSyncedSeed-Dm1E4ebt.js → resolveModelForSyncedSeed-BbSctSvz.js} +2 -2
  55. package/dist/{resolveModelForSyncedSeed-Dm1E4ebt.js.map → resolveModelForSyncedSeed-BbSctSvz.js.map} +1 -1
  56. package/dist/src/Item/Item.d.ts +9 -1
  57. package/dist/src/Item/Item.d.ts.map +1 -1
  58. package/dist/src/Item/errors.d.ts +3 -1
  59. package/dist/src/Item/errors.d.ts.map +1 -1
  60. package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
  61. package/dist/src/ItemProperty/service/actors/saveValueToDb/saveItemStorage.d.ts.map +1 -1
  62. package/dist/src/Model/Model.d.ts.map +1 -1
  63. package/dist/src/Model/service/actors/createModelProperties.d.ts.map +1 -1
  64. package/dist/src/ModelProperty/ModelProperty.d.ts +17 -0
  65. package/dist/src/ModelProperty/ModelProperty.d.ts.map +1 -1
  66. package/dist/src/Schema/Schema.d.ts.map +1 -1
  67. package/dist/src/client/ClientManager.d.ts +2 -2
  68. package/dist/src/client/ClientManager.d.ts.map +1 -1
  69. package/dist/src/client/actors/platformClassesInit.d.ts.map +1 -1
  70. package/dist/src/client/clientManagerMachine.d.ts.map +1 -1
  71. package/dist/src/db/alignRowPublishers.d.ts +25 -0
  72. package/dist/src/db/alignRowPublishers.d.ts.map +1 -0
  73. package/dist/src/db/read/getPublishUploads.d.ts.map +1 -1
  74. package/dist/src/db/read/getSchemaUidForModel.d.ts.map +1 -1
  75. package/dist/src/db/read/getSeedPublisher.d.ts +7 -0
  76. package/dist/src/db/read/getSeedPublisher.d.ts.map +1 -0
  77. package/dist/src/db/read/summarizePublishWork.d.ts.map +1 -1
  78. package/dist/src/db/write/applyArweaveL1TransactionIdLocal.d.ts +5 -3
  79. package/dist/src/db/write/applyArweaveL1TransactionIdLocal.d.ts.map +1 -1
  80. package/dist/src/db/write/claimUnpublishedDrafts.d.ts +4 -2
  81. package/dist/src/db/write/claimUnpublishedDrafts.d.ts.map +1 -1
  82. package/dist/src/db/write/createMetadata.d.ts.map +1 -1
  83. package/dist/src/db/write/createNewItem.d.ts.map +1 -1
  84. package/dist/src/db/write/createSeed.d.ts.map +1 -1
  85. package/dist/src/db/write/createVersion.d.ts.map +1 -1
  86. package/dist/src/db/write/discardNewDraft.d.ts +8 -0
  87. package/dist/src/db/write/discardNewDraft.d.ts.map +1 -0
  88. package/dist/src/db/write/restoreDataItemIdsOverwrittenByL1.d.ts +18 -0
  89. package/dist/src/db/write/restoreDataItemIdsOverwrittenByL1.d.ts.map +1 -0
  90. package/dist/src/db/write/updateItemPropertyValue.d.ts.map +1 -1
  91. package/dist/src/helpers/db.d.ts.map +1 -1
  92. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts +13 -2
  93. package/dist/src/helpers/htmlEmbeddedDataUriPublish.d.ts.map +1 -1
  94. package/dist/src/helpers/ownership.d.ts +9 -12
  95. package/dist/src/helpers/ownership.d.ts.map +1 -1
  96. package/dist/src/helpers/publishConfig.d.ts +9 -4
  97. package/dist/src/helpers/publishConfig.d.ts.map +1 -1
  98. package/dist/src/index.d.ts +1 -0
  99. package/dist/src/index.d.ts.map +1 -1
  100. package/dist/src/node/db/Db.d.ts.map +1 -1
  101. package/dist/{syncDbWithEas-CMCAihFh.js → syncDbWithEas-CrAY9Rl2.js} +13 -13
  102. package/dist/{syncDbWithEas-CMCAihFh.js.map → syncDbWithEas-CrAY9Rl2.js.map} +1 -1
  103. package/dist/{tabEvents-BEAmMncP.js → tabEvents-BGBYV65P.js} +4 -4
  104. package/dist/{tabEvents-BEAmMncP.js.map → tabEvents-BGBYV65P.js.map} +1 -1
  105. package/dist/{tolerantWebAccess-CqiDGEyR.js → tolerantWebAccess-DVHCEulL.js} +7 -7
  106. package/dist/{tolerantWebAccess-CqiDGEyR.js.map → tolerantWebAccess-DVHCEulL.js.map} +1 -1
  107. package/dist/{updateSeedRevokedAt-Bw3uEStt.js → updateSeedRevokedAt-Dy5J8CfQ.js} +3 -3
  108. package/dist/{updateSeedRevokedAt-Bw3uEStt.js.map → updateSeedRevokedAt-Dy5J8CfQ.js.map} +1 -1
  109. package/package.json +5 -5
  110. package/dist/BasePathResolver-CsZHPrk9.js.map +0 -1
  111. package/dist/ClientManager-DETTj0_z.js.map +0 -1
  112. package/dist/Item-TMrVEPeX.js.map +0 -1
  113. package/dist/ModelProperty-Bw6N8OMK.js.map +0 -1
  114. package/dist/errors-CWKup8tw.js.map +0 -1
  115. package/dist/getPublishUploads-cLbSEXLk.js.map +0 -1
  116. package/dist/index-CURf9L4d.js.map +0 -1
  117. package/dist/index-CXkcz4hT.js.map +0 -1
  118. package/dist/index.node-BiQhZQvH.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { waitFor, fromCallback, setup, assign, stateIn, createActor, isMachineSnapshot } from 'xstate';
2
- import { E as BaseDb, C as versions, m as metadata, A as seeds, F as resolveStorageNameToSchemaName, a_ as toSchemaPropertyName, z as schemas, s as models, q as modelSchemas, aY as getOwnedAddressesFromDb, a3 as ZERO_BYTES32, aG as normalizeAddressList, ak as normalizeHexAddress, aD as getAddressesForItemsFilter, a7 as INTERNAL_PROPERTY_NAMES, K as BaseFileManager, a$ as getStorageTransactionIdForSeedUid, b0 as convertTxIdToImage, i as isDataType, af as normalizePublisher, n as normalizeDataType, b1 as getMetadataPropertyNamesForQuery, aC as ensureImageLocal, au as ImageSize, b2 as downloadTransactionIdWithDedupe, b3 as resolveMetadataRecord, u as properties, M as ModelPropertyDataTypes, aj as generateId, aa as INTERNAL_DATA_TYPES, r as modelUids, ab as listRelationEasPropertyName, ac as easPropertyNameForPublish, N as resolveItemModelFileId, b4 as getPropertyIdForSchemaFileId, L as getPropertyIdForModelAndName, al as toMetadataPropertyName, b5 as getDataTypeFromString, b6 as getMimeType, ar as INTERNAL_STORAGE_MODEL_FILE_IDS, W as getItemStorageSubdir, X as getItemStorageLocalFileName, g as normalizePropertyRecordSchema, b7 as listRelationStoragePropertyName, b8 as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, $ as getCorrectId, H as eventEmitter, b9 as getAlternatePropertyNameForInstanceLookup, a8 as isStorageSeedRef } from './BasePathResolver-CsZHPrk9.js';
2
+ import { B as BaseDb, F as versions, m as metadata, C as seeds, G as resolveStorageNameToSchemaName, a_ as toSchemaPropertyName, A as schemas, t as models, r as modelSchemas, aY as getOwnedAddressesFromDb, a5 as ZERO_BYTES32, aG as normalizeAddressList, am as normalizeHexAddress, aD as getAddressesForItemsFilter, a9 as INTERNAL_PROPERTY_NAMES, h as BaseFileManager, a$ as getStorageTransactionIdForSeedUid, b0 as convertTxIdToImage, i as isDataType, ah as normalizePublisher, n as normalizeDataType, b1 as getMetadataPropertyNamesForQuery, aC as ensureImageLocal, au as ImageSize, b2 as downloadTransactionIdWithDedupe, b3 as resolveMetadataRecord, v as properties, M as ModelPropertyDataTypes, al as generateId, ac as INTERNAL_DATA_TYPES, s as modelUids, ad as listRelationEasPropertyName, ae as easPropertyNameForPublish, N as resolveItemModelFileId, b4 as getPropertyIdForSchemaFileId, L as getPropertyIdForModelAndName, an as toMetadataPropertyName, b5 as getDataTypeFromString, b6 as getMimeType, _ as INTERNAL_STORAGE_MODEL_FILE_IDS, a2 as getItemStorageSubdir, a3 as getItemStorageLocalFileName, g as normalizePropertyRecordSchema, b7 as listRelationStoragePropertyName, b8 as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, R as getCorrectId, I as eventEmitter, b9 as getAlternatePropertyNameForInstanceLookup, aa as isStorageSeedRef } from './BasePathResolver-CBTXCMFL.js';
3
3
  import { or, isNull, eq, max, count, and, getTableColumns, sql, desc, inArray, isNotNull, gt } from 'drizzle-orm';
4
4
  import debug from 'debug';
5
5
  import { BehaviorSubject } from 'rxjs';
@@ -7,7 +7,7 @@ import pluralize from 'pluralize';
7
7
  import { startCase, upperFirst, camelCase, orderBy } from 'lodash-es';
8
8
  import { isValidEasAttestationUid, easName, isPlaceholderUid, BaseQueryClient, BaseEasClient, GET_SCHEMAS, getEasSchemaUidForSchemaDefinition, getSchemaUidForModelFromCache, setSchemaUidForModel, cachedSchemaLookup, getEasSchemaUidForExactDefinition } from '@seedprotocol/eas';
9
9
  import { fetchArweaveRawTextAcrossGateways } from '@seedprotocol/arweave';
10
- import { d as notifyFileSaved, f as withTabLock } from './tabEvents-BEAmMncP.js';
10
+ import { d as notifyFileSaved, f as withTabLock } from './tabEvents-BGBYV65P.js';
11
11
  import { modelPropertiesToObject } from './model-oHA3YhOd.js';
12
12
 
13
13
  /**
@@ -580,7 +580,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
580
580
  const itemPropertyMod = await Promise.resolve().then(function () { return ItemProperty$1; });
581
581
  const { ItemProperty } = itemPropertyMod;
582
582
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
583
- const _mod_0 = await import('./errors-CWKup8tw.js');
583
+ const _mod_0 = await import('./errors-CIrbsN_i.js');
584
584
  const _ns_0 = _mod_0.h;
585
585
  const { Model } = _ns_0;
586
586
  // Resolve Model and build property schemas (use getByNameAsync for models not yet in cache)
@@ -598,7 +598,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
598
598
  const schemaNameToTry = schemaName ?? model?.schemaName;
599
599
  if (schemaNameToTry) {
600
600
  try {
601
- const _mod_1 = await import('./Schema-VLenyJDy.js');
601
+ const _mod_1 = await import('./Schema-8DxGcORY.js');
602
602
  const _ns_1 = _mod_1.b;
603
603
  const { Schema } = _ns_1;
604
604
  const schemaInstance = Schema.create(schemaNameToTry, { waitForReady: false });
@@ -614,8 +614,8 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
614
614
  }
615
615
  if (Object.keys(propertySchemas).length === 0) {
616
616
  try {
617
- const _mod_2 = await import('./ClientManager-DETTj0_z.js');
618
- const _ns_2 = _mod_2.L;
617
+ const _mod_2 = await import('./ClientManager-DRf4uuei.js');
618
+ const _ns_2 = _mod_2.M;
619
619
  const { loadAllSchemasFromDb } = _ns_2;
620
620
  const allSchemas = await loadAllSchemasFromDb();
621
621
  for (const { schema: schemaFile } of allSchemas) {
@@ -635,10 +635,10 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
635
635
  }
636
636
  if (Object.keys(propertySchemas).length === 0) {
637
637
  try {
638
- const _mod_3 = await import('./ClientManager-DETTj0_z.js');
639
- const _ns_3 = _mod_3.L;
638
+ const _mod_3 = await import('./ClientManager-DRf4uuei.js');
639
+ const _ns_3 = _mod_3.M;
640
640
  const { listCompleteSchemaFiles } = _ns_3;
641
- const _mod_4 = await import('./BasePathResolver-CsZHPrk9.js');
641
+ const _mod_4 = await import('./BasePathResolver-CBTXCMFL.js');
642
642
  const _ns_4 = _mod_4.bc;
643
643
  const { BaseFileManager } = _ns_4;
644
644
  const schemaFiles = await listCompleteSchemaFiles();
@@ -659,7 +659,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
659
659
  }
660
660
  }
661
661
  if (Object.keys(propertySchemas).length === 0) {
662
- const schemaMod = await import('./index-CXkcz4hT.js');
662
+ const schemaMod = await import('./index-CMxEil8T.js');
663
663
  const { ModelPropertyDataTypes } = schemaMod;
664
664
  const KNOWN_MODEL_FALLBACKS = {
665
665
  Post: {
@@ -676,7 +676,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
676
676
  }
677
677
  }
678
678
  // Fallbacks above may return schema-file shape ({ type, model, items }); normalize to dataType/ref/refValueType.
679
- const { normalizePropertyRecordSchema } = await import('./property-tgPI5hMu.js');
679
+ const { normalizePropertyRecordSchema } = await import('./property-lz9yIpyA.js');
680
680
  propertySchemas = Object.fromEntries(Object.entries(propertySchemas).map(([name, def]) => [name, normalizePropertyRecordSchema(def)]));
681
681
  // Collapse rows that map to the same instance key (e.g. authorIdentityIds + authors -> authors).
682
682
  // ItemProperty.create cache does not sync propertyValue on hit; processing order would otherwise
@@ -709,7 +709,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
709
709
  // Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
710
710
  let propSchema = propertySchemas[propertyName];
711
711
  if (!propSchema && isRefTypeFromMeta) {
712
- const schemaMod = await import('./index-CXkcz4hT.js');
712
+ const schemaMod = await import('./index-CMxEil8T.js');
713
713
  const { ModelPropertyDataTypes } = schemaMod;
714
714
  propSchema = {
715
715
  dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
@@ -1595,14 +1595,14 @@ function publisherIsInOwnedSet(publisher, ownedAddresses) {
1595
1595
  }
1596
1596
  /**
1597
1597
  * Shared ownership predicate.
1598
- * - Session has owned addresses: only a publisher in that set is owned (null is never owned).
1599
- * - Session has no owned addresses: local unsealed drafts are owned so pre-connect authoring works.
1598
+ * - A local unsealed draft (never given a publisher) is owned whatever the owned addresses are:
1599
+ * it belongs to no wallet yet, and the next wallet to connect claims it (claimUnpublishedDrafts).
1600
+ * - Any other row is owned when its publisher (or attester) is in the owned addresses.
1600
1601
  */
1601
1602
  function isSeedRowOwned(row, ownedAddresses) {
1602
1603
  const publisher = resolvePublisherFromSeedRow(row);
1603
- if (ownedAddresses.length === 0) {
1604
- return isLocalUnsealedDraft({ ...row, publisher: publisher ?? row.publisher });
1605
- }
1604
+ if (isLocalUnsealedDraft({ ...row, publisher: publisher ?? row.publisher }))
1605
+ return true;
1606
1606
  return publisherIsInOwnedSet(publisher, ownedAddresses);
1607
1607
  }
1608
1608
  /**
@@ -1635,8 +1635,8 @@ function localUnsealedDraftSql() {
1635
1635
  }
1636
1636
  /**
1637
1637
  * SQL for `addressFilter: 'owned'`: a row passes exactly when {@link isSeedRowOwned} is true.
1638
- * - Empty owned → local unsealed drafts (pre-connect authoring), not every row.
1639
- * - Owned set → `lower(trim(publisher))` in the set, or, when publisher is blank, the
1638
+ * - Local unsealed drafts always pass.
1639
+ * - Otherwise `lower(trim(publisher))` is in the owned set, or, when publisher is blank, the
1640
1640
  * `attestationRaw.attester` ({@link resolvePublisherFromSeedRow}). `json_valid` guards
1641
1641
  * `json_extract`, which throws on malformed JSON.
1642
1642
  */
@@ -1646,17 +1646,13 @@ function ownedSeedsSql(ownedAddresses) {
1646
1646
  return localUnsealedDraftSql();
1647
1647
  }
1648
1648
  const attester = sql `CASE WHEN json_valid(${seeds.attestationRaw}) THEN lower(trim(json_extract(${seeds.attestationRaw}, '$.attester'))) END`;
1649
- return or(inArray(sql `lower(trim(${seeds.publisher}))`, normalized), and(isBlankSql(seeds.publisher), inArray(attester, normalized)));
1649
+ return or(localUnsealedDraftSql(), inArray(sql `lower(trim(${seeds.publisher}))`, normalized), and(isBlankSql(seeds.publisher), inArray(attester, normalized)));
1650
1650
  }
1651
1651
  /**
1652
- * Checks if the current user owns the item (publisher is in persisted owned addresses).
1653
- *
1654
- * When the session has owned addresses, only a matching publisher is owned —
1655
- * `publisher IS NULL` is not treated as owned. Call `claimUnpublishedDrafts`
1656
- * after connect to stamp local drafts.
1657
- *
1658
- * When owned is empty, local unsealed drafts (no publisher, no real uid, no
1659
- * attestationRaw) are still owned so create/edit works before a wallet is connected.
1652
+ * Checks if the current user owns the item: its publisher is in the persisted owned addresses,
1653
+ * or it's a local unsealed draft (no publisher, no real uid, no attestationRaw). Such a draft
1654
+ * was made with no wallet connected and is editable until `claimUnpublishedDrafts`, which
1655
+ * connecting a wallet calls, gives it that wallet as publisher.
1660
1656
  *
1661
1657
  * Does not include `getAdditionalSyncAddresses` (those are extra EAS indexers,
1662
1658
  * not wallets the user controls).
@@ -1715,7 +1711,7 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
1715
1711
  conditions.push(eq(seeds.type, easName(modelName)));
1716
1712
  }
1717
1713
  if (!modelFileId && schemaName && modelName) {
1718
- const _mod_5 = await import('./BasePathResolver-CsZHPrk9.js');
1714
+ const _mod_5 = await import('./BasePathResolver-CBTXCMFL.js');
1719
1715
  const _ns_5 = _mod_5.bf;
1720
1716
  const { resolveModelRecord } = _ns_5;
1721
1717
  modelFileId = (await resolveModelRecord(modelName, { schemaName }))?.schemaFileId ?? undefined;
@@ -1998,7 +1994,7 @@ const resolveRelatedValue = fromCallback(({ sendBack, input: { context } }) => {
1998
1994
  const { isRelation, propertyValue, propertyName, seedUid, propertyRecordSchema, populatedFromDb, schemaUid, } = context;
1999
1995
  const _resolveRelatedValue = async () => {
2000
1996
  // Use dynamic import to break circular dependency
2001
- const schemaMod = await import('./index-CXkcz4hT.js');
1997
+ const schemaMod = await import('./index-CMxEil8T.js');
2002
1998
  const { ModelPropertyDataTypes } = schemaMod;
2003
1999
  if (!propertyValue || !isRelation || populatedFromDb) {
2004
2000
  return;
@@ -2433,7 +2429,7 @@ async function readHtmlBodyFromChildStorageArweave(seedLocalId) {
2433
2429
  /* offline / bad tx id */
2434
2430
  }
2435
2431
  try {
2436
- const _mod_6 = await import('./BasePathResolver-CsZHPrk9.js');
2432
+ const _mod_6 = await import('./BasePathResolver-CBTXCMFL.js');
2437
2433
  const _ns_6 = _mod_6.bh;
2438
2434
  const { downloadTransactionIdWithDedupe } = _ns_6;
2439
2435
  await downloadTransactionIdWithDedupe(txId);
@@ -2494,7 +2490,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
2494
2490
  // to use dynamically imported ModelPropertyDataTypes
2495
2491
  const _hydrateFromDb = async () => {
2496
2492
  // Use dynamic import to break circular dependency
2497
- const schemaMod = await import('./index-CXkcz4hT.js');
2493
+ const schemaMod = await import('./index-CMxEil8T.js');
2498
2494
  const { ModelPropertyDataTypes } = schemaMod;
2499
2495
  const appDb = BaseDb.getAppDb();
2500
2496
  const whereClauses = [];
@@ -2775,11 +2771,11 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
2775
2771
  const modelNameForNew = context.modelName;
2776
2772
  if (modelNameForNew) {
2777
2773
  try {
2778
- const _mod_7 = await import('./errors-CWKup8tw.js');
2774
+ const _mod_7 = await import('./errors-CIrbsN_i.js');
2779
2775
  const _ns_7 = _mod_7.h;
2780
2776
  const { Model } = _ns_7;
2781
2777
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
2782
- const _mod_8 = await import('./BasePathResolver-CsZHPrk9.js');
2778
+ const _mod_8 = await import('./BasePathResolver-CBTXCMFL.js');
2783
2779
  const _ns_8 = _mod_8.bf;
2784
2780
  const { resolveItemModelFileId } = _ns_8;
2785
2781
  const normalizedModelName = upperFirst(camelCase(modelNameForNew));
@@ -2833,7 +2829,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
2833
2829
  // It ends up in the context below, and later lookups by name (Model.getByName) can't match it.
2834
2830
  const modelName = context.modelName || (metadataRecord.modelType ? upperFirst(camelCase(metadataRecord.modelType)) : undefined);
2835
2831
  // Model names are only unique per schema: pin lookups to the item's own model row.
2836
- const _mod_9 = await import('./BasePathResolver-CsZHPrk9.js');
2832
+ const _mod_9 = await import('./BasePathResolver-CBTXCMFL.js');
2837
2833
  const _ns_9 = _mod_9.bf;
2838
2834
  const { resolveItemModelFileId, resolveModelRecord } = _ns_9;
2839
2835
  const modelFileId = await resolveItemModelFileId({
@@ -2878,7 +2874,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
2878
2874
  required: propRecord.required ?? undefined,
2879
2875
  };
2880
2876
  // Validation rules (enum, pattern, ...) aren't in the properties table
2881
- const { resolvePropertyValidationRules } = await import('./propertyValidationRules-BLVxTejW.js');
2877
+ const { resolvePropertyValidationRules } = await import('./propertyValidationRules-LuIwoQoJ.js');
2882
2878
  const validation = await resolvePropertyValidationRules(normalizedModelName, propertyName, {
2883
2879
  modelFileId: modelRecord?.schemaFileId ?? modelFileId,
2884
2880
  });
@@ -2895,7 +2891,7 @@ const loadOrCreateProperty = fromCallback(({ sendBack, input: { context } }) =>
2895
2891
  }
2896
2892
  if (!propertyRecordSchema && modelName) {
2897
2893
  try {
2898
- const _mod_10 = await import('./errors-CWKup8tw.js');
2894
+ const _mod_10 = await import('./errors-CIrbsN_i.js');
2899
2895
  const _ns_10 = _mod_10.h;
2900
2896
  const { Model } = _ns_10;
2901
2897
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -3117,6 +3113,27 @@ const getVersionData = async ({ localId, seedLocalId, uid, }) => {
3117
3113
  return queryRows[0];
3118
3114
  };
3119
3115
 
3116
+ /**
3117
+ * The publisher a seed's version and property rows take: the seed's own (its `publisher`, else the
3118
+ * attester of its stored attestation). Undefined for a draft that belongs to no wallet yet; those
3119
+ * rows are then claimed together with their seed (claimUnpublishedDrafts).
3120
+ */
3121
+ async function getSeedPublisher(seedLocalId) {
3122
+ if (!seedLocalId)
3123
+ return undefined;
3124
+ const appDb = BaseDb.getAppDb();
3125
+ if (!appDb)
3126
+ return undefined;
3127
+ const [row] = await appDb
3128
+ .select({ publisher: seeds.publisher, attestationRaw: seeds.attestationRaw, uid: seeds.uid })
3129
+ .from(seeds)
3130
+ .where(eq(seeds.localId, seedLocalId))
3131
+ .limit(1);
3132
+ if (!row)
3133
+ return undefined;
3134
+ return normalizePublisher(resolvePublisherFromSeedRow(row));
3135
+ }
3136
+
3120
3137
  const logger$2 = debug('seedSdk:write:updateItemPropertyValue');
3121
3138
  const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, newValue, seedUid, seedLocalId, modelName, refSeedType, refResolvedValue, refResolvedDisplayValue, versionLocalId, versionUid, schemaUid, localStorageDir, dataType, refValueType, }) => {
3122
3139
  if (!localIdParam && !seedLocalId) {
@@ -3168,10 +3185,13 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
3168
3185
  }
3169
3186
  if (rows && rows.length > 0) {
3170
3187
  const { localId, uid, propertyName: propertyNameFromDb, propertyValue: propertyValueFromDb, modelType, seedUid, seedLocalId: seedLocalIdFromDb, versionLocalId, versionUid, schemaUid, easDataType, localStorageDir: localStorageDirFromDb, refSeedType: refSeedTypeFromDb, refResolvedValue: refResolvedValueFromDb, refResolvedDisplayValue: refResolvedDisplayValueFromDb, } = rows[0];
3188
+ // Stored model types are the model's EAS name (ADR 0008): `blog_post` for BlogPost.
3189
+ const modelTypeForName = modelName ? easName(modelName) : undefined;
3171
3190
  if (propertyValueFromDb === newValue &&
3172
- modelType === modelName?.toLowerCase() &&
3173
- refSeedTypeFromDb === refSeedType &&
3174
- refResolvedValueFromDb === refResolvedValue) {
3191
+ modelType === modelTypeForName &&
3192
+ // The DB holds null where callers leave a field out (plain values pass no ref fields).
3193
+ (refSeedTypeFromDb ?? null) === (refSeedType ?? null) &&
3194
+ (refResolvedValueFromDb ?? null) === (refResolvedValue ?? null)) {
3175
3195
  logger$2(`[db/write] [updateItemPropertyValue] value is the same as most recent record for property: ${propertyNameFromDb}`);
3176
3196
  return;
3177
3197
  }
@@ -3204,11 +3224,14 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
3204
3224
  const versionDataFromDb = versionLocalId ? await getVersionData({ localId: versionLocalId }) : null;
3205
3225
  // Here we don't have a local-only record so we need to create a new one
3206
3226
  const newLocalId = generateId();
3227
+ // The row belongs to its seed's wallet, like createMetadata's.
3228
+ const publisher = await getSeedPublisher(seedLocalIdFromDb ?? seedLocalId);
3207
3229
  await appDb.insert(metadata).values({
3208
3230
  localId: newLocalId,
3231
+ ...(publisher && { publisher }),
3209
3232
  propertyName: propertyNameFromDb,
3210
3233
  propertyValue: safeNewValue ?? null,
3211
- modelType: modelType || modelName?.toLowerCase() || null,
3234
+ modelType: modelType || modelTypeForName || null,
3212
3235
  seedUid: seedDataFromDb?.uid || null,
3213
3236
  seedLocalId: seedLocalIdFromDb,
3214
3237
  versionLocalId,
@@ -3240,11 +3263,13 @@ const updateItemPropertyValue = async ({ localId: localIdParam, propertyName, ne
3240
3263
  versionUid = versionData.uid;
3241
3264
  }
3242
3265
  }
3266
+ const publisher = await getSeedPublisher(seedLocalId);
3243
3267
  await appDb.insert(metadata).values({
3244
3268
  localId: newLocalId,
3269
+ ...(publisher && { publisher }),
3245
3270
  propertyName,
3246
3271
  propertyValue: safeNewValue ?? null,
3247
- modelType: modelName?.toLowerCase() || '',
3272
+ modelType: modelName ? easName(modelName) : '',
3248
3273
  seedUid: seedUid || null,
3249
3274
  seedLocalId: seedLocalId || '',
3250
3275
  versionLocalId: versionLocalId || '',
@@ -3329,9 +3354,9 @@ const analyzeInput = fromCallback(({ sendBack, input: { context, event } }) => {
3329
3354
  return false;
3330
3355
  }
3331
3356
  // Use dynamic import to break circular dependency
3332
- const schemaMod = await import('./index-CXkcz4hT.js');
3357
+ const schemaMod = await import('./index-CMxEil8T.js');
3333
3358
  const { ModelPropertyDataTypes } = schemaMod;
3334
- const { SchemaValidationService } = await import('./SchemaValidationService-CLGadxgf.js');
3359
+ const { SchemaValidationService } = await import('./SchemaValidationService-CE92y1TT.js');
3335
3360
  let propertyName = propertyNameRaw;
3336
3361
  if (!propertyName) {
3337
3362
  throw new Error('propertyName is required');
@@ -3522,21 +3547,22 @@ const getEasSchemaUidForModel = async (modelName) => {
3522
3547
  return uid;
3523
3548
  }
3524
3549
  }
3525
- const modeType = modelName.toLowerCase();
3550
+ // The name publish registers the model's schema under (ADR 0008): `blog_post` for BlogPost.
3551
+ const modelType = easName(modelName);
3526
3552
  let easSchemaUid;
3527
3553
  try {
3528
3554
  // Misses are cached too (most local models have no EAS schema).
3529
- easSchemaUid = await cachedSchemaLookup(`model:${modeType}`, async () => {
3555
+ easSchemaUid = await cachedSchemaLookup(`model:${modelType}`, async () => {
3530
3556
  const queryClient = BaseQueryClient.getQueryClient();
3531
3557
  const easClient = BaseEasClient.getEasClient();
3532
3558
  const modelSchemaQuery = await queryClient.fetchQuery({
3533
- queryKey: [`getEasSchemaUidForModel`, modeType],
3559
+ queryKey: [`getEasSchemaUidForModel`, modelType],
3534
3560
  queryFn: async () => easClient.request(GET_SCHEMAS, {
3535
3561
  where: {
3536
3562
  schemaNames: {
3537
3563
  some: {
3538
3564
  name: {
3539
- equals: modeType,
3565
+ equals: modelType,
3540
3566
  },
3541
3567
  },
3542
3568
  },
@@ -3563,7 +3589,15 @@ const createSeed = async ({ type, seedUid, modelFileId }) => {
3563
3589
  // if the EAS schema hasn't been published yet
3564
3590
  const appDb = BaseDb.getAppDb();
3565
3591
  const newSeedLocalId = generateId();
3566
- const publisher = normalizePublisher(await getPublisherForNewSeedsWithTimeout());
3592
+ // When nothing supplies a publisher (no getter, as in Node scripts, or no wallet connected yet)
3593
+ // and exactly one owned address is set, the draft is that address's. With several, which one would
3594
+ // publish isn't known: the draft gets none, stays editable, and the next wallet to connect claims it.
3595
+ let publisher = normalizePublisher(await getPublisherForNewSeedsWithTimeout());
3596
+ if (!publisher) {
3597
+ const owned = await getOwnedAddressesFromDb();
3598
+ if (owned.length === 1)
3599
+ publisher = normalizePublisher(owned[0]);
3600
+ }
3567
3601
  await appDb.insert(seeds).values({
3568
3602
  localId: newSeedLocalId,
3569
3603
  type,
@@ -3579,7 +3613,8 @@ const createSeed = async ({ type, seedUid, modelFileId }) => {
3579
3613
  const createVersion = async ({ seedLocalId, seedUid, seedType, uid, }) => {
3580
3614
  const appDb = BaseDb.getAppDb();
3581
3615
  const newVersionLocalId = generateId();
3582
- const publisher = normalizePublisher(await getPublisherForNewSeedsWithTimeout());
3616
+ // A version belongs to its seed's wallet (none yet for a draft made with no wallet connected).
3617
+ const publisher = await getSeedPublisher(seedLocalId);
3583
3618
  await appDb.insert(versions).values({
3584
3619
  localId: newVersionLocalId,
3585
3620
  createdAt: Date.now(),
@@ -3603,7 +3638,8 @@ class MetadataValidationError extends Error {
3603
3638
  const createMetadata = async (metadataValues, propertyRecordSchema, options) => {
3604
3639
  const appDb = BaseDb.getAppDb();
3605
3640
  metadataValues.localId = generateId();
3606
- const publisher = normalizePublisher(await getPublisherForNewSeedsWithTimeout());
3641
+ // A property row belongs to its seed's wallet (none yet for a draft made with no wallet connected).
3642
+ const publisher = await getSeedPublisher(metadataValues.seedLocalId);
3607
3643
  if (publisher) {
3608
3644
  metadataValues.publisher = publisher;
3609
3645
  }
@@ -3643,7 +3679,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
3643
3679
  propertyRecordSchema?.validation &&
3644
3680
  metadataValues.propertyValue != null &&
3645
3681
  metadataValues.propertyValue !== '') {
3646
- const { SchemaValidationService } = await import('./SchemaValidationService-CLGadxgf.js');
3682
+ const { SchemaValidationService } = await import('./SchemaValidationService-CE92y1TT.js');
3647
3683
  const validationService = new SchemaValidationService();
3648
3684
  const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
3649
3685
  ? normalizeDataType(String(propertyRecordSchema.refValueType))
@@ -4256,7 +4292,7 @@ const saveRelation = fromCallback(({ sendBack, input: { context, event } }) => {
4256
4292
  }
4257
4293
  const _saveRelation = async () => {
4258
4294
  // Use dynamic import to break circular dependency
4259
- const schemaMod = await import('./index-CXkcz4hT.js');
4295
+ const schemaMod = await import('./index-CMxEil8T.js');
4260
4296
  const { ModelPropertyDataTypes } = schemaMod;
4261
4297
  if (!propertyNameRaw) {
4262
4298
  throw new Error('propertyName is required');
@@ -4490,7 +4526,7 @@ const saveItemStorage = fromCallback(({ sendBack, input: { context, event } }) =
4490
4526
  return createMetadata({
4491
4527
  propertyName,
4492
4528
  propertyValue: filename,
4493
- modelType: (modelName ?? knownRow?.modelType ?? '').toLowerCase() || undefined,
4529
+ modelType: (modelName ? easName(modelName) : knownRow?.modelType) || undefined,
4494
4530
  seedLocalId: draftSeedLocalId,
4495
4531
  seedUid: draftSeedUid,
4496
4532
  versionLocalId,
@@ -4975,10 +5011,10 @@ const getPropertyData = async ({ propertyName, seedLocalId, seedUid, modelName,
4975
5011
  let names = [...getMetadataPropertyNamesForQuery(propertyName)];
4976
5012
  if (modelName) {
4977
5013
  try {
4978
- const _mod_11 = await import('./errors-CWKup8tw.js');
5014
+ const _mod_11 = await import('./errors-CIrbsN_i.js');
4979
5015
  const _ns_11 = _mod_11.h;
4980
5016
  const { Model } = _ns_11;
4981
- const _mod_12 = await import('./BasePathResolver-CsZHPrk9.js');
5017
+ const _mod_12 = await import('./BasePathResolver-CBTXCMFL.js');
4982
5018
  const _ns_12 = _mod_12.bf;
4983
5019
  const { resolveItemModelFileId } = _ns_12;
4984
5020
  // Model names are only unique per schema: use the seed's own model when it is recorded.
@@ -5179,8 +5215,8 @@ const HTML_PROP_SEED_UID_RE = /^0x[a-fA-F0-9]{64}$/;
5179
5215
  */
5180
5216
  const resolvePropertyRecordSchemaFromSchemaData = async (modelName, propertyName, modelType, schemaName) => {
5181
5217
  try {
5182
- const _mod_13 = await import('./ClientManager-DETTj0_z.js');
5183
- const _ns_13 = _mod_13.L;
5218
+ const _mod_13 = await import('./ClientManager-DRf4uuei.js');
5219
+ const _ns_13 = _mod_13.M;
5184
5220
  const { loadAllSchemasFromDb } = _ns_13;
5185
5221
  const allSchemas = await loadAllSchemasFromDb();
5186
5222
  const modelNameAlt = modelType ? upperFirst(camelCase(modelType)) : '';
@@ -5233,11 +5269,11 @@ hints = {}) => {
5233
5269
  return undefined;
5234
5270
  }
5235
5271
  try {
5236
- const _mod_14 = await import('./errors-CWKup8tw.js');
5272
+ const _mod_14 = await import('./errors-CIrbsN_i.js');
5237
5273
  const _ns_14 = _mod_14.h;
5238
5274
  const { Model } = _ns_14;
5239
5275
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
5240
- const _mod_15 = await import('./BasePathResolver-CsZHPrk9.js');
5276
+ const _mod_15 = await import('./BasePathResolver-CBTXCMFL.js');
5241
5277
  const _ns_15 = _mod_15.bf;
5242
5278
  const { resolveItemModelFileId } = _ns_15;
5243
5279
  const modelFileId = await resolveItemModelFileId(hints);
@@ -5397,7 +5433,7 @@ class ItemProperty {
5397
5433
  return;
5398
5434
  }
5399
5435
  // Use dynamic import to break circular dependency
5400
- const schemaMod = await import('./index-CXkcz4hT.js');
5436
+ const schemaMod = await import('./index-CMxEil8T.js');
5401
5437
  const { ModelPropertyDataTypes } = schemaMod;
5402
5438
  const { context } = snapshot;
5403
5439
  const { propertyRecordSchema } = context;
@@ -5474,7 +5510,11 @@ class ItemProperty {
5474
5510
  }
5475
5511
  }
5476
5512
  if (exists && isFile) {
5477
- renderValue = await BaseFileManager.readFileAsString(filePath);
5513
+ // A File's value is its content URL (a blob URL in browsers, file:// in Node), as saveFile
5514
+ // and hydrateFromDb set it. Reading the text here made the value change from the URL to
5515
+ // the file's contents a moment after every save or load.
5516
+ renderValue =
5517
+ context.refResolvedDisplayValue ?? (await BaseFileManager.getContentUrlFromPath(filePath));
5478
5518
  }
5479
5519
  if (!exists) {
5480
5520
  // Keep filename for display when File object is present but not yet saved to disk
@@ -5568,7 +5608,7 @@ class ItemProperty {
5568
5608
  const normalizedRefValueType = normalizeDataType(propertyRecordSchema?.refValueType);
5569
5609
  const propertyNames = getMetadataPropertyNamesForQuery(propertyName, normalizedDataType, normalizedRefValueType);
5570
5610
  const propertyNameVariant = propertyNames.length > 1 ? propertyNames[1] : undefined;
5571
- const _mod_16 = await import('./index-CURf9L4d.js');
5611
+ const _mod_16 = await import('./index-DWK-LOUY.js');
5572
5612
  const _ns_16 = _mod_16.s;
5573
5613
  const seedSchemaMod = _ns_16;
5574
5614
  const { metadata } = seedSchemaMod;
@@ -5792,7 +5832,7 @@ class ItemProperty {
5792
5832
  const ctx = this._service.getSnapshot().context;
5793
5833
  let modelFileId;
5794
5834
  try {
5795
- const _mod_17 = await import('./BasePathResolver-CsZHPrk9.js');
5835
+ const _mod_17 = await import('./BasePathResolver-CBTXCMFL.js');
5796
5836
  const _ns_17 = _mod_17.bf;
5797
5837
  const { resolveItemModelFileId } = _ns_17;
5798
5838
  modelFileId = await resolveItemModelFileId({
@@ -6155,7 +6195,7 @@ class ItemProperty {
6155
6195
  const propertiesData = await getItemProperties({ seedLocalId, seedUid });
6156
6196
  const instances = [];
6157
6197
  const seenNormalized = new Set();
6158
- const _mod_18 = await import('./BasePathResolver-CsZHPrk9.js');
6198
+ const _mod_18 = await import('./BasePathResolver-CBTXCMFL.js');
6159
6199
  const _ns_18 = _mod_18.bf;
6160
6200
  const { resolveItemModelFileId } = _ns_18;
6161
6201
  const itemModelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
@@ -6173,7 +6213,7 @@ class ItemProperty {
6173
6213
  }
6174
6214
  else if (baseName) {
6175
6215
  try {
6176
- const _mod_19 = await import('./errors-CWKup8tw.js');
6216
+ const _mod_19 = await import('./errors-CIrbsN_i.js');
6177
6217
  const _ns_19 = _mod_19.h;
6178
6218
  const { Model } = _ns_19;
6179
6219
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -6190,7 +6230,7 @@ class ItemProperty {
6190
6230
  }
6191
6231
  if (modelName && propertyName) {
6192
6232
  try {
6193
- const _mod_20 = await import('./errors-CWKup8tw.js');
6233
+ const _mod_20 = await import('./errors-CIrbsN_i.js');
6194
6234
  const _ns_20 = _mod_20.h;
6195
6235
  const { Model } = _ns_20;
6196
6236
  const { modelPropertiesToObject } = await import('./model-oHA3YhOd.js');
@@ -6522,7 +6562,7 @@ class ItemProperty {
6522
6562
  if (!propertyName || (!seedLocalId && !seedUid))
6523
6563
  return;
6524
6564
  if (db) {
6525
- const _mod_21 = await import('./index-CURf9L4d.js');
6565
+ const _mod_21 = await import('./index-DWK-LOUY.js');
6526
6566
  const _ns_21 = _mod_21.s;
6527
6567
  const seedSchemaMod = _ns_21;
6528
6568
  const { metadata } = seedSchemaMod;
@@ -6567,7 +6607,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
6567
6607
  }
6568
6608
  const seedType = easName(modelName);
6569
6609
  // Dynamic import to break circular dependency
6570
- const _mod_22 = await import('./errors-CWKup8tw.js');
6610
+ const _mod_22 = await import('./errors-CIrbsN_i.js');
6571
6611
  const _ns_22 = _mod_22.h;
6572
6612
  const modelMod = _ns_22;
6573
6613
  const { Model } = modelMod;
@@ -6575,57 +6615,69 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
6575
6615
  const propertySchemas = model?.properties ? modelPropertiesToObject(model.properties) : undefined;
6576
6616
  modelFileId ?? (modelFileId = model?.id);
6577
6617
  const newSeedId = await createSeed({ type: seedType, modelFileId });
6578
- const newVersionId = await createVersion({ seedLocalId: newSeedId, seedType: easName(modelName) });
6579
- // Build set of all properties to create metadata for: union of model schema + propertyData
6580
- // This ensures we create metadata for ALL model properties even when creating with no initial values
6581
- // (fixes first-item persistence: loadOrCreateItem needs metadata rows to run createItemPropertyInstances)
6582
- const allPropertyNames = new Set(Object.keys(propertyData));
6583
- if (propertySchemas) {
6584
- for (const name of Object.keys(propertySchemas)) {
6585
- allPropertyNames.add(name);
6586
- }
6587
- }
6588
- for (const propertyName of allPropertyNames) {
6589
- const propertyValue = propertyData[propertyName];
6590
- const propertyRecordSchema = propertySchemas?.[propertyName];
6591
- // ItemStorage content lives in the property's file (`<seedLocalId><extension>`), as a save puts
6592
- // it; the row records where. Stored verbatim in the row, publish would never upload it.
6593
- const isItemStorageValue = propertyRecordSchema?.storageType === 'ItemStorage' &&
6594
- propertyValue != null &&
6595
- propertyValue !== '';
6596
- const insertRow = (storageFields) => createMetadata({
6618
+ try {
6619
+ return await writeVersionAndRows(newSeedId);
6620
+ }
6621
+ catch (error) {
6622
+ // The rows are separate inserts (no transaction): remove what was written so a failure leaves
6623
+ // no half-made draft.
6624
+ const { discardNewDraft } = await import('./discardNewDraft-CEOouygG.js');
6625
+ await discardNewDraft(newSeedId).catch(() => undefined);
6626
+ throw error;
6627
+ }
6628
+ async function writeVersionAndRows(newSeedId) {
6629
+ const newVersionId = await createVersion({ seedLocalId: newSeedId, seedType: easName(modelName) });
6630
+ // Build set of all properties to create metadata for: union of model schema + propertyData
6631
+ // This ensures we create metadata for ALL model properties even when creating with no initial values
6632
+ // (fixes first-item persistence: loadOrCreateItem needs metadata rows to run createItemPropertyInstances)
6633
+ const allPropertyNames = new Set(Object.keys(propertyData));
6634
+ if (propertySchemas) {
6635
+ for (const name of Object.keys(propertySchemas)) {
6636
+ allPropertyNames.add(name);
6637
+ }
6638
+ }
6639
+ for (const propertyName of allPropertyNames) {
6640
+ const propertyValue = propertyData[propertyName];
6641
+ const propertyRecordSchema = propertySchemas?.[propertyName];
6642
+ // ItemStorage content lives in the property's file (`<seedLocalId><extension>`), as a save puts
6643
+ // it; the row records where. Stored verbatim in the row, publish would never upload it.
6644
+ const isItemStorageValue = propertyRecordSchema?.storageType === 'ItemStorage' &&
6645
+ propertyValue != null &&
6646
+ propertyValue !== '';
6647
+ const insertRow = (storageFields) => createMetadata({
6648
+ seedLocalId: newSeedId,
6649
+ versionLocalId: newVersionId,
6650
+ propertyName,
6651
+ propertyValue: storageFields ? undefined : propertyValue,
6652
+ ...storageFields,
6653
+ modelName,
6654
+ }, propertyRecordSchema, { skipValidation: true, modelFileId });
6655
+ if (!isItemStorageValue) {
6656
+ await insertRow();
6657
+ continue;
6658
+ }
6659
+ // File and row under the file's lock, like every writer of a local draft's file (see
6660
+ // withItemStorageFileLock). The seed is new, so nothing else should be writing it yet.
6661
+ const target = {
6662
+ seedId: newSeedId,
6663
+ localStorageDir: propertyRecordSchema.localStorageDir,
6664
+ filenameSuffix: propertyRecordSchema.filenameSuffix,
6665
+ };
6666
+ await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
6667
+ const written = await writeItemStorageFile(target, propertyValue);
6668
+ await insertRow({
6669
+ refResolvedValue: written.fileName,
6670
+ localStorageDir: written.localStorageDir,
6671
+ refValueType: 'file',
6672
+ });
6673
+ });
6674
+ }
6675
+ return {
6676
+ modelName,
6597
6677
  seedLocalId: newSeedId,
6598
6678
  versionLocalId: newVersionId,
6599
- propertyName,
6600
- propertyValue: storageFields ? undefined : propertyValue,
6601
- ...storageFields,
6602
- modelName,
6603
- }, propertyRecordSchema, { skipValidation: true, modelFileId });
6604
- if (!isItemStorageValue) {
6605
- await insertRow();
6606
- continue;
6607
- }
6608
- // File and row under the file's lock, like every writer of a local draft's file (see
6609
- // withItemStorageFileLock). The seed is new, so nothing else should be writing it yet.
6610
- const target = {
6611
- seedId: newSeedId,
6612
- localStorageDir: propertyRecordSchema.localStorageDir,
6613
- filenameSuffix: propertyRecordSchema.filenameSuffix,
6614
6679
  };
6615
- await withItemStorageFileLock(getItemStorageFilePath(target), async () => {
6616
- const written = await writeItemStorageFile(target, propertyValue);
6617
- await insertRow({
6618
- refResolvedValue: written.fileName,
6619
- localStorageDir: written.localStorageDir,
6620
- refValueType: 'file',
6621
- });
6622
- });
6623
6680
  }
6624
- return {
6625
- modelName,
6626
- seedLocalId: newSeedId,
6627
- versionLocalId: newVersionId,
6628
- };
6629
6681
  };
6630
6682
 
6631
6683
  /**
@@ -6750,7 +6802,7 @@ const getModel = () => {
6750
6802
  // the fragile `import(...).then(n => n.X)` chunk-namespace pattern.
6751
6803
  if (!modelImportPromise) {
6752
6804
  modelImportPromise = (async () => {
6753
- const _mod_23 = await import('./errors-CWKup8tw.js');
6805
+ const _mod_23 = await import('./errors-CIrbsN_i.js');
6754
6806
  const _ns_23 = _mod_23.h;
6755
6807
  const mod = _ns_23;
6756
6808
  ModelClass = mod.Model;
@@ -6918,14 +6970,16 @@ class Item {
6918
6970
  };
6919
6971
  this.getPublishUploads = async (options) => {
6920
6972
  // Use dynamic import to break circular dependency
6921
- const getPublishUploadsMod = await import('./getPublishUploads-cLbSEXLk.js');
6973
+ const _mod_24 = await import('./getPublishUploads-CVTBo_OV.js');
6974
+ const _ns_24 = _mod_24.o;
6975
+ const getPublishUploadsMod = _ns_24;
6922
6976
  const { getPublishUploads } = getPublishUploadsMod;
6923
6977
  return await getPublishUploads(this, [], undefined, options);
6924
6978
  };
6925
6979
  this.getPublishPayload = async (uploadedTransactions, options) => {
6926
- const _mod_24 = await import('./getPublishPayload-CWfjl8PM.js');
6927
- const _ns_24 = _mod_24.g;
6928
- const getPublishPayloadMod = _ns_24;
6980
+ const _mod_25 = await import('./getPublishPayload-DTjOKd3y.js');
6981
+ const _ns_25 = _mod_25.g;
6982
+ const getPublishPayloadMod = _ns_25;
6929
6983
  const { getPublishPayload } = getPublishPayloadMod;
6930
6984
  return await getPublishPayload(this, uploadedTransactions, options);
6931
6985
  };
@@ -7185,17 +7239,20 @@ class Item {
7185
7239
  }
7186
7240
  }
7187
7241
  }
7242
+ /** Drops one holder's reference. Returns true while other holders still have the instance. */
7188
7243
  static releaseItemInstanceCacheHold(instance) {
7189
7244
  const keys = this.collectInstanceCacheKeysForInstance(instance);
7190
7245
  if (keys.length === 0)
7191
- return;
7246
+ return false;
7192
7247
  const entry = this.instanceCache.get(keys[0]);
7193
7248
  entry.refCount -= 1;
7194
7249
  if (entry.refCount <= 0) {
7195
7250
  for (const k of keys) {
7196
7251
  this.instanceCache.delete(k);
7197
7252
  }
7253
+ return false;
7198
7254
  }
7255
+ return true;
7199
7256
  }
7200
7257
  /**
7201
7258
  * Idle, and not the shell the item machine can be in when it reaches `idle` before
@@ -7459,18 +7516,18 @@ class Item {
7459
7516
  const db = BaseDb.getAppDb();
7460
7517
  if (db && props.modelName) {
7461
7518
  // Model names are only unique per schema: resolve the exact models row from the most specific scope.
7462
- const _mod_25 = await import('./BasePathResolver-CsZHPrk9.js');
7463
- const _ns_25 = _mod_25.bf;
7464
- const { resolveModelRecord } = _ns_25;
7519
+ const _mod_26 = await import('./BasePathResolver-CBTXCMFL.js');
7520
+ const _ns_26 = _mod_26.bf;
7521
+ const { resolveModelRecord } = _ns_26;
7465
7522
  const modelRecord = await resolveModelRecord(props.modelName, {
7466
7523
  modelFileId: props.modelFileId ?? modelInstance?.id,
7467
7524
  schemaName: schemaName ?? modelInstance?.schemaName,
7468
7525
  });
7469
7526
  const modelRecords = modelRecord ? [modelRecord] : [];
7470
7527
  if (!modelRecord) {
7471
- const _mod_26 = await import('./errors-CWKup8tw.js');
7472
- const _ns_26 = _mod_26.j;
7473
- const { UnknownModelError } = _ns_26;
7528
+ const _mod_27 = await import('./errors-CIrbsN_i.js');
7529
+ const _ns_27 = _mod_27.j;
7530
+ const { UnknownModelError } = _ns_27;
7474
7531
  throw new UnknownModelError(props.modelName, schemaName ?? modelInstance?.schemaName);
7475
7532
  }
7476
7533
  if (modelRecord?.schemaFileId) {
@@ -7479,12 +7536,12 @@ class Item {
7479
7536
  // Scope the constructor's Model lookup to this model's schema (as getItemData does on reload),
7480
7537
  // so a same-named model cached from another schema can't supply the property set.
7481
7538
  if (modelRecord && !props.schemaName) {
7482
- const _mod_27 = await import('./BasePathResolver-CsZHPrk9.js');
7483
- const _ns_27 = _mod_27.be;
7484
- const { modelSchemas } = _ns_27;
7485
- const _mod_28 = await import('./BasePathResolver-CsZHPrk9.js');
7486
- const _ns_28 = _mod_28.bd;
7487
- const { schemas: schemasTable } = _ns_28;
7539
+ const _mod_28 = await import('./BasePathResolver-CBTXCMFL.js');
7540
+ const _ns_28 = _mod_28.be;
7541
+ const { modelSchemas } = _ns_28;
7542
+ const _mod_29 = await import('./BasePathResolver-CBTXCMFL.js');
7543
+ const _ns_29 = _mod_29.bd;
7544
+ const { schemas: schemasTable } = _ns_29;
7488
7545
  const schemaRows = await db
7489
7546
  .select({ schemaName: schemasTable.name })
7490
7547
  .from(modelSchemas)
@@ -7653,22 +7710,35 @@ class Item {
7653
7710
  return proxiedInstance;
7654
7711
  try {
7655
7712
  await this.waitForItemInstanceReadyForRead(proxiedInstance, readyTimeout);
7713
+ await this.savePipelineValues(proxiedInstance, pipelineValues, readyTimeout);
7656
7714
  }
7657
7715
  catch (err) {
7658
- try {
7659
- proxiedInstance.unload();
7660
- }
7661
- catch {
7662
- /* best-effort cache cleanup */
7663
- }
7716
+ // A rejected create leaves nothing behind, so a retry doesn't make a second draft.
7717
+ await this.discardCreatedItem(proxiedInstance, seedLocalId);
7664
7718
  throw err;
7665
7719
  }
7666
- await this.savePipelineValues(proxiedInstance, pipelineValues, readyTimeout);
7667
7720
  return proxiedInstance;
7668
7721
  }
7722
+ /** Stops a just-created item and deletes what create wrote (see discardNewDraft). */
7723
+ static async discardCreatedItem(item, seedLocalId) {
7724
+ try {
7725
+ this.dropCachedInstancesForSeedIds([seedLocalId]);
7726
+ }
7727
+ catch {
7728
+ /* best-effort cache cleanup */
7729
+ }
7730
+ try {
7731
+ const { discardNewDraft } = await import('./discardNewDraft-CEOouygG.js');
7732
+ await discardNewDraft(seedLocalId);
7733
+ }
7734
+ catch (error) {
7735
+ itemLogger(`Item.create: could not remove the draft ${seedLocalId} after a failure:`, error);
7736
+ }
7737
+ }
7669
7738
  /**
7670
7739
  * Run each File/Image/Html/ItemStorage initial value through its ItemProperty save pipeline (sequentially, to
7671
- * avoid SQLite write contention). Rejects on the first failure; the item itself has been created.
7740
+ * avoid SQLite write contention). Rejects on the first failure, with ItemCreateValidationError when the
7741
+ * value breaks its property's rules; Item.create then removes the item.
7672
7742
  */
7673
7743
  static async savePipelineValues(item, pipelineValues, timeout) {
7674
7744
  for (const [propertyName, value] of pipelineValues) {
@@ -7681,6 +7751,14 @@ class Item {
7681
7751
  await property.save();
7682
7752
  }
7683
7753
  catch (error) {
7754
+ if (error instanceof ItemPropertySaveValidationError) {
7755
+ const _mod_30 = await import('./errors-CIrbsN_i.js');
7756
+ const _ns_30 = _mod_30.j;
7757
+ const { ItemCreateValidationError } = _ns_30;
7758
+ const created = new ItemCreateValidationError(item.modelName, error.validationErrors.map((e) => ({ property: propertyName, code: e.code, message: e.message })));
7759
+ created.cause = error;
7760
+ throw created;
7761
+ }
7684
7762
  throw new Error(`Item.create: failed to save ${item.modelName}.${propertyName} for item ${item.seedLocalId}: ` +
7685
7763
  (error instanceof Error ? error.message : String(error)), { cause: error });
7686
7764
  }
@@ -7841,9 +7919,9 @@ class Item {
7841
7919
  if (!appDb || Item.instanceCache.size === 0) {
7842
7920
  return;
7843
7921
  }
7844
- const _mod_29 = await import('./index-CURf9L4d.js');
7845
- const _ns_29 = _mod_29.s;
7846
- const { metadata } = _ns_29;
7922
+ const _mod_31 = await import('./index-DWK-LOUY.js');
7923
+ const _ns_31 = _mod_31.s;
7924
+ const { metadata } = _ns_31;
7847
7925
  const { eq, and } = await import('drizzle-orm');
7848
7926
  const dedupedInstances = new Map();
7849
7927
  for (const entry of Item.instanceCache.values()) {
@@ -8004,11 +8082,11 @@ class Item {
8004
8082
  }
8005
8083
  /** Throws ItemCreateValidationError for unknown keys and values that break their property's rules. */
8006
8084
  static async assertValidCreateValues(props, propertyNames, dataTypeByPropertyName, skipKeys) {
8007
- const _mod_30 = await import('./errors-CWKup8tw.js');
8008
- const _ns_30 = _mod_30.j;
8009
- const { ItemCreateValidationError } = _ns_30;
8010
- const { getPropertySchema } = await import('./property-tgPI5hMu.js');
8011
- const { SchemaValidationService } = await import('./SchemaValidationService-CLGadxgf.js');
8085
+ const _mod_32 = await import('./errors-CIrbsN_i.js');
8086
+ const _ns_32 = _mod_32.j;
8087
+ const { ItemCreateValidationError } = _ns_32;
8088
+ const { getPropertySchema } = await import('./property-lz9yIpyA.js');
8089
+ const { SchemaValidationService } = await import('./SchemaValidationService-CE92y1TT.js');
8012
8090
  const validationService = new SchemaValidationService();
8013
8091
  const modelName = props.modelName;
8014
8092
  const known = new Set(propertyNames);
@@ -8045,7 +8123,7 @@ class Item {
8045
8123
  // Not JSON: validated as given, and rejected as a non-array
8046
8124
  }
8047
8125
  }
8048
- const { resolvePropertyValidationRules } = await import('./propertyValidationRules-BLVxTejW.js');
8126
+ const { resolvePropertyValidationRules } = await import('./propertyValidationRules-LuIwoQoJ.js');
8049
8127
  const rules = propertySchema?.validation ??
8050
8128
  (await resolvePropertyValidationRules(modelName, key, {
8051
8129
  modelFileId: props.modelFileId,
@@ -8376,9 +8454,9 @@ class Item {
8376
8454
  itemActor.send(event);
8377
8455
  };
8378
8456
  try {
8379
- const _mod_31 = await import('./index-CURf9L4d.js');
8380
- const _ns_31 = _mod_31.s;
8381
- const seedSchemaMod = _ns_31;
8457
+ const _mod_33 = await import('./index-DWK-LOUY.js');
8458
+ const _ns_33 = _mod_33.s;
8459
+ const seedSchemaMod = _ns_33;
8382
8460
  const { seeds, versions, metadata } = seedSchemaMod;
8383
8461
  const drizzleMod = await import('drizzle-orm');
8384
8462
  const { eq, and } = drizzleMod;
@@ -8667,9 +8745,15 @@ class Item {
8667
8745
  });
8668
8746
  }
8669
8747
  }
8748
+ /**
8749
+ * Releases this holder's reference. Item.create, Item.find and createById return the same cached
8750
+ * instance to every caller, so the instance is stopped only when the last holder unloads it.
8751
+ */
8670
8752
  unload() {
8671
8753
  try {
8672
- Item.releaseItemInstanceCacheHold(this);
8754
+ // Others (e.g. another hook showing the same item) still use it: keep it running.
8755
+ if (Item.releaseItemInstanceCacheHold(this))
8756
+ return;
8673
8757
  unloadEntity(this, {
8674
8758
  getCacheKeys: () => [],
8675
8759
  caches: [],
@@ -8740,5 +8824,5 @@ var Item$1 = /*#__PURE__*/Object.freeze({
8740
8824
  Item: Item
8741
8825
  });
8742
8826
 
8743
- export { unloadEntity as $, getPublishExecutor as A, getRevokeExecutor as B, ClientManagerState as C, DEFAULT_READY_TIMEOUT_MS as D, getUploadExecutor as E, getVersionData$1 as F, isLocalUnsealedDraft as G, isSeedRowOwned as H, Item as I, localUnsealedDraftSql as J, ownedPublisherSql as K, ownedSeedsSql as L, METADATA_LATEST_FIRST_ORDER_SQL as M, pickLatestMetadataRowPerProperty as N, OwnershipError as O, PUBLISH_NOT_CONFIGURED_MESSAGE as P, placeholderUidSql as Q, propertyMachine as R, publisherInAddressListSql as S, publisherIsInOwnedSet as T, setAdditionalSyncAddresses as U, setGetPublisherForNewSeeds as V, setPublishExecutor as W, setRevokeExecutor as X, setUploadExecutor as Y, getInvariantSafePropertyDescriptor as Z, clearDestroySubscriptions as _, ItemProperty as a, ClientManagerEvents as a0, withLockedItemStorageRow as a1, getItemStorageFilePath as a2, writeItemStorageFile as a3, resolvePublisherFromSeedRow as a4, getPropertyData$1 as a5, Item$1 as a6, ItemPropertySaveValidationError as b, compareMetadataRowsLatestFirst as c, assertItemOwned as d, getEasSchemaUidForModel as e, getLatestPublishedVersionRow as f, getItemData as g, isVersionRevoked as h, isItemOwned as i, chunkValues as j, getGetAdditionalSyncAddresses as k, waitForEntityIdle as l, createReactiveProxy as m, findEntity as n, forceRemoveFromCaches as o, parseListPropertyValueFromStorage as p, runDestroyLifecycle as q, rowsPerInsert as r, selectInBatches as s, isPublishedMetadataRow as t, MachineIds as u, createNewItem as v, writeInBatches as w, getEasSchemaForItemProperty as x, getGetPublisherForNewSeeds as y, getMetadataLatest as z };
8744
- //# sourceMappingURL=Item-TMrVEPeX.js.map
8827
+ export { unloadEntity as $, getPublishExecutor as A, getRevokeExecutor as B, ClientManagerState as C, DEFAULT_READY_TIMEOUT_MS as D, getUploadExecutor as E, getVersionData$1 as F, isLocalUnsealedDraft as G, isSeedRowOwned as H, Item as I, localUnsealedDraftSql as J, ownedPublisherSql as K, ownedSeedsSql as L, METADATA_LATEST_FIRST_ORDER_SQL as M, pickLatestMetadataRowPerProperty as N, OwnershipError as O, PUBLISH_NOT_CONFIGURED_MESSAGE as P, placeholderUidSql as Q, propertyMachine as R, publisherInAddressListSql as S, publisherIsInOwnedSet as T, setAdditionalSyncAddresses as U, setGetPublisherForNewSeeds as V, setPublishExecutor as W, setRevokeExecutor as X, setUploadExecutor as Y, getInvariantSafePropertyDescriptor as Z, clearDestroySubscriptions as _, ItemProperty as a, ClientManagerEvents as a0, withLockedItemStorageRow as a1, getItemStorageFilePath as a2, writeItemStorageFile as a3, resolvePublisherFromSeedRow as a4, getPropertyData$1 as a5, Item$1 as a6, ItemPropertySaveValidationError as b, assertItemOwned as c, waitForEntityIdle as d, compareMetadataRowsLatestFirst as e, getEasSchemaUidForModel as f, getItemData as g, getLatestPublishedVersionRow as h, isItemOwned as i, isVersionRevoked as j, chunkValues as k, getGetAdditionalSyncAddresses as l, createReactiveProxy as m, findEntity as n, forceRemoveFromCaches as o, parseListPropertyValueFromStorage as p, runDestroyLifecycle as q, rowsPerInsert as r, selectInBatches as s, isPublishedMetadataRow as t, MachineIds as u, createNewItem as v, writeInBatches as w, getEasSchemaForItemProperty as x, getGetPublisherForNewSeeds as y, getMetadataLatest as z };
8828
+ //# sourceMappingURL=Item-DTJPMjFk.js.map