@seedprotocol/sdk 0.7.9-next.1306.g4ff6582 → 0.7.10-next.1344.g3828e8a
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/README.md +1 -1
- package/dist/{BaseFileManager-BAlySv8w.js → BaseFileManager-DLou1TZS.js} +5 -1
- package/dist/BaseFileManager-DLou1TZS.js.map +1 -0
- package/dist/{Item-Bf4kWKpH.js → Item-CXLcIHsi.js} +559 -346
- package/dist/Item-CXLcIHsi.js.map +1 -0
- package/dist/{ModelProperty-BlaEgb_U.js → ModelProperty-B3mfR6u4.js} +35 -35
- package/dist/{ModelProperty-BlaEgb_U.js.map → ModelProperty-B3mfR6u4.js.map} +1 -1
- package/dist/{Schema-J_1f6p0c.js → Schema-BeUyEmte.js} +18 -18
- package/dist/{Schema-J_1f6p0c.js.map → Schema-BeUyEmte.js.map} +1 -1
- package/dist/{SchemaValidationService-CnmKyzR-.js → SchemaValidationService-C1xqJFxI.js} +5 -5
- package/dist/{SchemaValidationService-CnmKyzR-.js.map → SchemaValidationService-C1xqJFxI.js.map} +1 -1
- package/dist/{errors-C1qUEZ7A.js → browserSupport-C64rX-2I.js} +38 -2
- package/dist/browserSupport-C64rX-2I.js.map +1 -0
- package/dist/{configurePlatform-CiOJ1R3q.js → configurePlatform-WkmvqeTO.js} +2 -2
- package/dist/{configurePlatform-CiOJ1R3q.js.map → configurePlatform-WkmvqeTO.js.map} +1 -1
- package/dist/{detachRowsBeforeDelete-sEaUwlOU.js → detachRowsBeforeDelete-BZr_0iZU.js} +2 -2
- package/dist/{detachRowsBeforeDelete-sEaUwlOU.js.map → detachRowsBeforeDelete-BZr_0iZU.js.map} +1 -1
- package/dist/dist/{BaseFileManager-BAlySv8w.d.ts → BaseFileManager-DLou1TZS.d.ts} +3 -1
- package/dist/dist/BaseFileManager-DLou1TZS.d.ts.map +1 -0
- package/dist/dist/{configurePlatform-CiOJ1R3q.d.ts → configurePlatform-WkmvqeTO.d.ts} +1 -1
- package/dist/dist/configurePlatform-WkmvqeTO.d.ts.map +1 -0
- package/dist/dist/{index-D0V-mjCV.d.ts → index-BjWk0x4-.d.ts} +1 -1
- package/dist/dist/{index-D0V-mjCV.d.ts.map → index-BjWk0x4-.d.ts.map} +1 -1
- package/dist/dist/{index.node-CYPemH-t.d.ts → index.node-BfiBriEq.d.ts} +7 -1
- package/dist/dist/{index.node-CYPemH-t.d.ts.map → index.node-BfiBriEq.d.ts.map} +1 -1
- package/dist/dist/platform.node.d.ts +2 -2
- package/dist/{eas-wB_fQ8Tc.js → eas-DpHg66jR.js} +5 -5
- package/dist/{eas-wB_fQ8Tc.js.map → eas-DpHg66jR.js.map} +1 -1
- package/dist/{errors-DLSoqSHG.js → errors-DpC9W4i3.js} +84 -45
- package/dist/{errors-DLSoqSHG.js.map → errors-DpC9W4i3.js.map} +1 -1
- package/dist/{getPublishPayload-BnIwpwz1.js → getPublishPayload-yidQCgY_.js} +8 -8
- package/dist/{getPublishPayload-BnIwpwz1.js.map → getPublishPayload-yidQCgY_.js.map} +1 -1
- package/dist/{getPublishPendingDiff-D6_-A5ns.js → getPublishPendingDiff-D__9bh6d.js} +7 -7
- package/dist/{getPublishPendingDiff-D6_-A5ns.js.map → getPublishPendingDiff-D__9bh6d.js.map} +1 -1
- package/dist/{getPublishUploads-sS6JfPgz.js → getPublishUploads-BdZmYCo2.js} +7 -7
- package/dist/{getPublishUploads-sS6JfPgz.js.map → getPublishUploads-BdZmYCo2.js.map} +1 -1
- package/dist/{index-CYGWPoOx.js → index-BMHqJ4kN.js} +7 -7
- package/dist/index-BMHqJ4kN.js.map +1 -0
- package/dist/{index-D0V-mjCV.js → index-BjWk0x4-.js} +2 -2
- package/dist/index-BjWk0x4-.js.map +1 -0
- package/dist/{index-DmTtj1nk.js → index-CVYB2g7a.js} +402 -20
- package/dist/index-CVYB2g7a.js.map +1 -0
- package/dist/{index-BVBmz_cc.js → index-uDLe9y9H.js} +7 -7
- package/dist/index-uDLe9y9H.js.map +1 -0
- package/dist/{index.browser-CUmBVYen.js → index.browser-OACFlpMH.js} +46 -10
- package/dist/index.browser-OACFlpMH.js.map +1 -0
- package/dist/{index.node-CYPemH-t.js → index.node-BfiBriEq.js} +31 -4
- package/dist/index.node-BfiBriEq.js.map +1 -0
- package/dist/main.js +17 -16
- package/dist/main.js.map +1 -1
- package/dist/{modelPropertyRecordSchemas-C7UgA5TH.js → modelPropertyRecordSchemas-BGvtTyaG.js} +5 -5
- package/dist/{modelPropertyRecordSchemas-C7UgA5TH.js.map → modelPropertyRecordSchemas-BGvtTyaG.js.map} +1 -1
- package/dist/node.js +8 -8
- package/dist/platform.browser.js +6 -6
- package/dist/platform.node.js +4 -4
- package/dist/{property-BxUYznH0.js → property-QjljUeb9.js} +8 -8
- package/dist/{property-BxUYznH0.js.map → property-QjljUeb9.js.map} +1 -1
- package/dist/{publishGraph-EcB40Uii.js → publishGraph-CP8IROkb.js} +5 -5
- package/dist/{publishGraph-EcB40Uii.js.map → publishGraph-CP8IROkb.js.map} +1 -1
- package/dist/{readHtmlBodyForStorageSeed-D6KPtWoR.js → readHtmlBodyForStorageSeed-D3OPk2iU.js} +10 -10
- package/dist/{readHtmlBodyForStorageSeed-D6KPtWoR.js.map → readHtmlBodyForStorageSeed-D3OPk2iU.js.map} +1 -1
- package/dist/src/Item/Item.d.ts +26 -5
- package/dist/src/Item/Item.d.ts.map +1 -1
- package/dist/src/ItemProperty/ItemProperty.d.ts +20 -5
- package/dist/src/ItemProperty/ItemProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/loadProperty.d.ts.map +1 -1
- package/dist/src/ItemProperty/propertyWrite.d.ts.map +1 -1
- package/dist/src/ItemProperty/service/actors/hydrateFromDb.d.ts.map +1 -1
- package/dist/src/archive/exportArchive.d.ts +57 -0
- package/dist/src/archive/exportArchive.d.ts.map +1 -0
- package/dist/src/browser/db/Db.d.ts +5 -0
- package/dist/src/browser/db/Db.d.ts.map +1 -1
- package/dist/src/browser/helpers/FileManager.d.ts.map +1 -1
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts +12 -1
- package/dist/src/browser/helpers/tolerantWebAccess.d.ts.map +1 -1
- package/dist/src/client/ClientManager.d.ts +14 -4
- package/dist/src/client/ClientManager.d.ts.map +1 -1
- package/dist/src/db/Db/BaseDb.d.ts +2 -0
- package/dist/src/db/Db/BaseDb.d.ts.map +1 -1
- package/dist/src/helpers/FileManager/errors.d.ts +11 -0
- package/dist/src/helpers/FileManager/errors.d.ts.map +1 -1
- package/dist/src/helpers/browserSupport.d.ts +23 -0
- package/dist/src/helpers/browserSupport.d.ts.map +1 -0
- package/dist/src/helpers/cachedPropertyRefresh.d.ts +6 -6
- package/dist/src/helpers/cachedPropertyRefresh.d.ts.map +1 -1
- package/dist/src/helpers/entity/entityCache.d.ts +34 -3
- package/dist/src/helpers/entity/entityCache.d.ts.map +1 -1
- package/dist/src/helpers/entity/entityLifecycle.d.ts +21 -3
- package/dist/src/helpers/entity/entityLifecycle.d.ts.map +1 -1
- package/dist/src/helpers/propertyDefinition.d.ts +2 -0
- package/dist/src/helpers/propertyDefinition.d.ts.map +1 -1
- package/dist/src/helpers/tabCoordinator.d.ts +9 -2
- package/dist/src/helpers/tabCoordinator.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/interfaces/IDb.d.ts +6 -0
- package/dist/src/interfaces/IDb.d.ts.map +1 -1
- package/dist/src/node/db/Db.d.ts +6 -0
- package/dist/src/node/db/Db.d.ts.map +1 -1
- package/dist/src/outbox/conflicts.d.ts.map +1 -1
- package/dist/src/outbox/outbox.d.ts +6 -0
- package/dist/src/outbox/outbox.d.ts.map +1 -1
- package/dist/src/types/index.d.ts +16 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/{syncDbWithEas-CA7PvBgu.js → syncDbWithEas-CDjSNrVR.js} +14 -14
- package/dist/{syncDbWithEas-CA7PvBgu.js.map → syncDbWithEas-CDjSNrVR.js.map} +1 -1
- package/dist/{tabEvents-CaVmngqr.js → tabEvents-BHPY5I08.js} +38 -12
- package/dist/tabEvents-BHPY5I08.js.map +1 -0
- package/dist/{tolerantWebAccess-BJqViq08.js → tolerantWebAccess-hDq9ZGXH.js} +53 -13
- package/dist/tolerantWebAccess-hDq9ZGXH.js.map +1 -0
- package/dist/{updateSeedRevokedAt-BL9Bg-G7.js → updateSeedRevokedAt-BMwBnlnC.js} +3 -3
- package/dist/{updateSeedRevokedAt-BL9Bg-G7.js.map → updateSeedRevokedAt-BMwBnlnC.js.map} +1 -1
- package/package.json +10 -12
- package/dist/BaseFileManager-BAlySv8w.js.map +0 -1
- package/dist/Item-Bf4kWKpH.js.map +0 -1
- package/dist/dist/BaseFileManager-BAlySv8w.d.ts.map +0 -1
- package/dist/dist/configurePlatform-CiOJ1R3q.d.ts.map +0 -1
- package/dist/errors-C1qUEZ7A.js.map +0 -1
- package/dist/index-BVBmz_cc.js.map +0 -1
- package/dist/index-CYGWPoOx.js.map +0 -1
- package/dist/index-D0V-mjCV.js.map +0 -1
- package/dist/index-DmTtj1nk.js.map +0 -1
- package/dist/index.browser-CUmBVYen.js.map +0 -1
- package/dist/index.node-CYPemH-t.js.map +0 -1
- package/dist/tabEvents-CaVmngqr.js.map +0 -1
- package/dist/tolerantWebAccess-BJqViq08.js.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b0 as PROPERTY_NAMES_EXEMPT_FROM_ID_SUFFIX_STRIP, n as normalizeDataType, v as INTERNAL_DATA_TYPES, af as MachineIds, O as resolveItemModelFileId, l as resolveModelRecordByNameOrType, A as AmbiguousModelError, m as generateId, b1 as TAB_ID, aN as onTabMessage, ax as whenLeaderTab, ap as isLeaderTab, aM as postTabMessage, j as findSeedRow, b2 as getModelSchemaName, K as selectInBatches, aY as getOwnedAddressesFromDb, Z as ZERO_BYTES32, ar as normalizeAddressList, J as normalizeHexAddress, am as getAddressesForItemsFilter, a0 as INTERNAL_PROPERTY_NAMES, a7 as convertTxIdToImage, i as isDataType, R as getExtensionForMimeType, b3 as normalizeMimeType, aA as sniffMimeType, Y as getItemStorageSubdir, ad as ImageSize, b4 as findFileInDir, b5 as getStorageSubdirForDataType, g as normalizePropertyRecordSchema, h as eventEmitter, b6 as timingMarks, a4 as getPropertyDefinition, aU as tryWithTabLock, b7 as withTabLock, M as ModelPropertyDataTypes, aC as createSessionObjectUrl, U as INTERNAL_STORAGE_MODEL_FILE_IDS, b8 as revokeSessionObjectUrl, b9 as getPropertyDefinitionsByFileId, aw as whenDbReady, ba as timed, av as watchEntityRows, a5 as propertyDefinitionFromRow, bb as isSessionObjectUrl, a6 as addCachedPropertyRefresher, x as normalizePublisher, _ as getItemStorageLocalFileName, bc as timingNow, bd as timingSince, be as timingLogger, bf as timedDb } from './tabEvents-BHPY5I08.js';
|
|
2
2
|
import { fromCallback, setup, assign, and as and$1, stateIn, createActor, waitFor, isMachineSnapshot } from 'xstate';
|
|
3
3
|
import debug from 'debug';
|
|
4
4
|
import pluralize from 'pluralize';
|
|
5
5
|
import { easName, isValidEasAttestationUid, isPlaceholderUid, getEasSchemaUidForSchemaDefinition, getSchemaUidForModelFromCache, setSchemaUidForModel, cachedSchemaLookup, getEasModelSchemasForNames, getEasSchemaUidForExactDefinition } from '@seedprotocol/eas';
|
|
6
6
|
import { sql, inArray, or, eq, and, isNull, getTableColumns, asc, lt, isNotNull, max, count, gt, desc, ne } from 'drizzle-orm';
|
|
7
|
-
import { m as metadata, l as properties, B as BaseDb, d as models, p as pendingWrites, x as isSqliteBusyError, v as versions, s as seeds, w as BaseFileManager, b as modelUids, r as publishProcesses, e as arweaveL1FinalizeJobs, h as htmlEmbeddedImageCoPublish } from './BaseFileManager-
|
|
7
|
+
import { m as metadata, l as properties, B as BaseDb, d as models, p as pendingWrites, x as isSqliteBusyError, v as versions, s as seeds, w as BaseFileManager, b as modelUids, r as publishProcesses, e as arweaveL1FinalizeJobs, h as htmlEmbeddedImageCoPublish } from './BaseFileManager-DLou1TZS.js';
|
|
8
8
|
import { BehaviorSubject } from 'rxjs';
|
|
9
9
|
import { orderBy } from 'lodash-es';
|
|
10
10
|
import { normalizeRelationPropertyValue, resolveSeedIdsFromRefString, BaseArweaveClient } from '@seedprotocol/arweave';
|
|
@@ -496,7 +496,7 @@ const runPublish = fromCallback(({ sendBack, input: { context, item: itemFromEve
|
|
|
496
496
|
// item.publish() sends its own instance; look it up only if startPublish came without one.
|
|
497
497
|
const loaded = itemFromEvent
|
|
498
498
|
? undefined
|
|
499
|
-
: (await (await Promise.resolve().then(function () { return Item$1; })).Item.find({ seedLocalId }));
|
|
499
|
+
: (await (await Promise.resolve().then(function () { return Item$1; })).Item.find({ seedLocalId, hold: true }));
|
|
500
500
|
const item = itemFromEvent ?? loaded;
|
|
501
501
|
if (!item) {
|
|
502
502
|
sendBack({ type: 'publishError', error: new Error(`Item not found: ${seedLocalId}`) });
|
|
@@ -1078,6 +1078,9 @@ function outboxOpResult(op) {
|
|
|
1078
1078
|
// --- Draining ---------------------------------------------------------------------------------
|
|
1079
1079
|
let started = false;
|
|
1080
1080
|
let paused = false;
|
|
1081
|
+
/** Set by stopOutbox (client.stop) until the next startOutbox. */
|
|
1082
|
+
let stopped = false;
|
|
1083
|
+
let stopTabMessages;
|
|
1081
1084
|
let draining;
|
|
1082
1085
|
let drainAgain = false;
|
|
1083
1086
|
let retryTimer;
|
|
@@ -1091,7 +1094,8 @@ function startOutbox() {
|
|
|
1091
1094
|
if (started)
|
|
1092
1095
|
return;
|
|
1093
1096
|
started = true;
|
|
1094
|
-
|
|
1097
|
+
stopped = false;
|
|
1098
|
+
stopTabMessages = onTabMessage((message) => {
|
|
1095
1099
|
if (message.type === 'outbox-nudge' && isLeaderTab())
|
|
1096
1100
|
scheduleDrain();
|
|
1097
1101
|
if (message.type === 'outbox-settled')
|
|
@@ -1101,7 +1105,7 @@ function startOutbox() {
|
|
|
1101
1105
|
}
|
|
1102
1106
|
/** Drains soon in this tab (if it leads); calls made while a drain runs make it run once more. */
|
|
1103
1107
|
function scheduleDrain() {
|
|
1104
|
-
if (!isLeaderTab())
|
|
1108
|
+
if (stopped || !isLeaderTab())
|
|
1105
1109
|
return;
|
|
1106
1110
|
if (draining) {
|
|
1107
1111
|
drainAgain = true;
|
|
@@ -1112,7 +1116,7 @@ function scheduleDrain() {
|
|
|
1112
1116
|
do {
|
|
1113
1117
|
drainAgain = false;
|
|
1114
1118
|
await drainOutbox();
|
|
1115
|
-
} while (drainAgain && !paused);
|
|
1119
|
+
} while (drainAgain && !paused && !stopped);
|
|
1116
1120
|
}
|
|
1117
1121
|
catch (error) {
|
|
1118
1122
|
logger$8('drain failed', error);
|
|
@@ -1455,6 +1459,24 @@ async function getOutboxOps(opIds) {
|
|
|
1455
1459
|
return [];
|
|
1456
1460
|
return BaseDb.getAppDb().select().from(pendingWrites).where(inArray(pendingWrites.opId, opIds));
|
|
1457
1461
|
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Stops draining in this tab (client.stop): no new drain starts, retries are dropped, and this
|
|
1464
|
+
* resolves once a drain that was running has finished. Ops stay pending in the database; the next
|
|
1465
|
+
* startOutbox (any write after init) resumes them, as after a reload.
|
|
1466
|
+
*/
|
|
1467
|
+
async function stopOutbox() {
|
|
1468
|
+
started = false;
|
|
1469
|
+
stopped = true;
|
|
1470
|
+
stopTabMessages?.();
|
|
1471
|
+
stopTabMessages = undefined;
|
|
1472
|
+
if (retryTimer !== undefined) {
|
|
1473
|
+
clearTimeout(retryTimer);
|
|
1474
|
+
retryTimer = undefined;
|
|
1475
|
+
}
|
|
1476
|
+
notBefore.clear();
|
|
1477
|
+
while (draining)
|
|
1478
|
+
await draining;
|
|
1479
|
+
}
|
|
1458
1480
|
|
|
1459
1481
|
/** A storage op's row fields, from either op shape. */
|
|
1460
1482
|
function storageValueRowOf(value) {
|
|
@@ -2213,8 +2235,8 @@ const getItemsData = async ({ modelName, modelFileId, schemaName, deleted, inclu
|
|
|
2213
2235
|
conditions.push(eq(seeds.type, easName(modelName)));
|
|
2214
2236
|
}
|
|
2215
2237
|
if (!modelFileId && schemaName && modelName) {
|
|
2216
|
-
const _mod_0 = await import('./tabEvents-
|
|
2217
|
-
const _ns_0 = _mod_0.
|
|
2238
|
+
const _mod_0 = await import('./tabEvents-BHPY5I08.js');
|
|
2239
|
+
const _ns_0 = _mod_0.bh;
|
|
2218
2240
|
const { resolveModelRecord } = _ns_0;
|
|
2219
2241
|
modelFileId = (await resolveModelRecord(modelName, { schemaName }))?.schemaFileId ?? undefined;
|
|
2220
2242
|
if (!modelFileId)
|
|
@@ -2469,7 +2491,7 @@ const resolveRelatedValue = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
2469
2491
|
const { isRelation, propertyValue, propertyName, propertyRecordSchema, populatedFromDb, } = context;
|
|
2470
2492
|
const _resolveRelatedValue = async () => {
|
|
2471
2493
|
// Use dynamic import to break circular dependency
|
|
2472
|
-
const schemaMod = await import('./index-
|
|
2494
|
+
const schemaMod = await import('./index-uDLe9y9H.js');
|
|
2473
2495
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
2474
2496
|
if (!propertyValue || !isRelation || populatedFromDb) {
|
|
2475
2497
|
return;
|
|
@@ -2983,7 +3005,7 @@ async function resolveStorageRef(kind, row) {
|
|
|
2983
3005
|
}
|
|
2984
3006
|
if (kind === 'html') {
|
|
2985
3007
|
if (!out.refResolvedValue && out.propertyValue) {
|
|
2986
|
-
const { resolveHtmlStorageSeedLocalId } = await import('./readHtmlBodyForStorageSeed-
|
|
3008
|
+
const { resolveHtmlStorageSeedLocalId } = await import('./readHtmlBodyForStorageSeed-D3OPk2iU.js');
|
|
2987
3009
|
const localId = await resolveHtmlStorageSeedLocalId(out.propertyValue);
|
|
2988
3010
|
if (localId)
|
|
2989
3011
|
out.refResolvedValue = `${localId}.html`;
|
|
@@ -3032,7 +3054,7 @@ async function resolveStorageDisplay(kind, row, options = {}) {
|
|
|
3032
3054
|
}
|
|
3033
3055
|
}
|
|
3034
3056
|
if (!renderValue && options.fetch && ref.propertyValue) {
|
|
3035
|
-
const { readHtmlBodyForStorageSeedPropertyValue } = await import('./readHtmlBodyForStorageSeed-
|
|
3057
|
+
const { readHtmlBodyForStorageSeedPropertyValue } = await import('./readHtmlBodyForStorageSeed-D3OPk2iU.js');
|
|
3036
3058
|
renderValue = await readHtmlBodyForStorageSeedPropertyValue(ref.propertyValue);
|
|
3037
3059
|
}
|
|
3038
3060
|
return { ref, filePath, renderValue };
|
|
@@ -3044,15 +3066,15 @@ async function resolveStorageDisplay(kind, row, options = {}) {
|
|
|
3044
3066
|
: BaseFileManager.pathExists(BaseFileManager.getFilesPath(dir, name)).then((exists) => exists ? BaseFileManager.getFilesPath(dir, name) : undefined);
|
|
3045
3067
|
// ensureImageLocal also makes the smallest size variant when the original is already there
|
|
3046
3068
|
if (kind === 'image' && options.fetch) {
|
|
3047
|
-
const _mod_1 = await import('./tabEvents-
|
|
3048
|
-
const _ns_1 = _mod_1.
|
|
3069
|
+
const _mod_1 = await import('./tabEvents-BHPY5I08.js');
|
|
3070
|
+
const _ns_1 = _mod_1.bo;
|
|
3049
3071
|
const { ensureImageLocal } = _ns_1;
|
|
3050
3072
|
await ensureImageLocal({ transactionId: name, fileName: name, widths: [ImageSize.EXTRA_SMALL] });
|
|
3051
3073
|
}
|
|
3052
3074
|
let filePath = await find();
|
|
3053
3075
|
if (!filePath && kind === 'file' && options.fetch) {
|
|
3054
|
-
const _mod_2 = await import('./tabEvents-
|
|
3055
|
-
const _ns_2 = _mod_2.
|
|
3076
|
+
const _mod_2 = await import('./tabEvents-BHPY5I08.js');
|
|
3077
|
+
const _ns_2 = _mod_2.bm;
|
|
3056
3078
|
const { downloadTransactionIdWithDedupe } = _ns_2;
|
|
3057
3079
|
await downloadTransactionIdWithDedupe(name);
|
|
3058
3080
|
filePath = await find();
|
|
@@ -3086,7 +3108,7 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3086
3108
|
}
|
|
3087
3109
|
const _hydrateFromDb = async () => {
|
|
3088
3110
|
const normalizedDataType = normalizeDataType(propertyRecordSchema?.dataType);
|
|
3089
|
-
const
|
|
3111
|
+
const read = () => currentPropertyRow({ seedLocalId, seedUid }, {
|
|
3090
3112
|
propertyId: context.propertyId,
|
|
3091
3113
|
propertyName,
|
|
3092
3114
|
modelName,
|
|
@@ -3094,10 +3116,15 @@ const hydrateFromDb = fromCallback(({ sendBack, input: { context } }) => {
|
|
|
3094
3116
|
dataType: normalizedDataType,
|
|
3095
3117
|
refValueType: normalizeDataType(propertyRecordSchema?.refValueType),
|
|
3096
3118
|
});
|
|
3119
|
+
let row = await read();
|
|
3097
3120
|
if (!row)
|
|
3098
3121
|
return;
|
|
3099
3122
|
const { getPropertyConflict } = await Promise.resolve().then(function () { return conflicts; });
|
|
3100
3123
|
const conflict = await getPropertyConflict(row.seedLocalId ?? seedLocalId, propertyName);
|
|
3124
|
+
// Sync records a conflict and moves its draft to newest in one transaction: a row read before
|
|
3125
|
+
// the conflict may be the synced one
|
|
3126
|
+
if (conflict)
|
|
3127
|
+
row = (await read()) ?? row;
|
|
3101
3128
|
// Only with a definition: without one, a row's refSeedType alone doesn't decide the display here
|
|
3102
3129
|
const kind = propertyRecordSchema ? storedValueKind(propertyRecordSchema) : undefined;
|
|
3103
3130
|
let { refResolvedValue, localStorageDir } = row;
|
|
@@ -3480,12 +3507,12 @@ async function keepLocalDraftsOverSyncedRows(synced) {
|
|
|
3480
3507
|
const now = Date.now();
|
|
3481
3508
|
const remoteAt = remote.attestationCreatedAt ?? 0;
|
|
3482
3509
|
const createdAt = Math.max(draft.createdAt ?? 0, remoteAt + 1);
|
|
3483
|
-
// Written
|
|
3510
|
+
// Written with the conflict: the change feed has no trigger on pending_writes, so this write
|
|
3484
3511
|
// is what makes a loaded property re-read and pick the conflict up (ADR 0020).
|
|
3485
|
-
const keepDraftNewest = async (recordedConflict) => {
|
|
3512
|
+
const keepDraftNewest = async (on, recordedConflict) => {
|
|
3486
3513
|
if (createdAt === draft.createdAt && !recordedConflict)
|
|
3487
3514
|
return;
|
|
3488
|
-
await
|
|
3515
|
+
await on.update(metadata).set({ createdAt }).where(eq(metadata.localId, draft.localId));
|
|
3489
3516
|
};
|
|
3490
3517
|
// The attested value the draft replaced: the newest attested row that sync didn't just write
|
|
3491
3518
|
const base = candidates
|
|
@@ -3495,7 +3522,7 @@ async function keepLocalDraftsOverSyncedRows(synced) {
|
|
|
3495
3522
|
const remoteValue = remote.propertyValue ?? null;
|
|
3496
3523
|
const localValue = draft.propertyValue ?? null;
|
|
3497
3524
|
if (remoteValue === localValue || remoteValue === baseValue) {
|
|
3498
|
-
await keepDraftNewest(false);
|
|
3525
|
+
await keepDraftNewest(db, false);
|
|
3499
3526
|
continue;
|
|
3500
3527
|
}
|
|
3501
3528
|
const opId = generateId();
|
|
@@ -3508,19 +3535,23 @@ async function keepLocalDraftsOverSyncedRows(synced) {
|
|
|
3508
3535
|
remoteUid: remote.uid,
|
|
3509
3536
|
opId,
|
|
3510
3537
|
};
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3538
|
+
// One transaction: a reader that sees the conflict also sees the draft as the newest row, or it
|
|
3539
|
+
// could show the synced value beside the conflict
|
|
3540
|
+
await BaseDb.transaction(async (tx) => {
|
|
3541
|
+
await tx.insert(pendingWrites).values({
|
|
3542
|
+
opId,
|
|
3543
|
+
seedLocalId: draft.seedLocalId,
|
|
3544
|
+
propertyName: draft.propertyName,
|
|
3545
|
+
kind: 'set',
|
|
3546
|
+
value: JSON.stringify({ newValue: localValue }),
|
|
3547
|
+
baseRowId: draft.localId,
|
|
3548
|
+
createdAt: now,
|
|
3549
|
+
status: 'applied',
|
|
3550
|
+
appliedAt: now,
|
|
3551
|
+
conflict: JSON.stringify(conflict),
|
|
3552
|
+
});
|
|
3553
|
+
await keepDraftNewest(tx, true);
|
|
3522
3554
|
});
|
|
3523
|
-
await keepDraftNewest(true);
|
|
3524
3555
|
eventEmitter.emit('itemProperty.conflict', conflict);
|
|
3525
3556
|
}
|
|
3526
3557
|
}
|
|
@@ -3535,194 +3566,6 @@ var conflicts = /*#__PURE__*/Object.freeze({
|
|
|
3535
3566
|
recordPropertyEdit: recordPropertyEdit
|
|
3536
3567
|
});
|
|
3537
3568
|
|
|
3538
|
-
/**
|
|
3539
|
-
* The cache behind an entity class (ADR 0014). `peek` takes no hold; `hold`, `add({ hold: true })`
|
|
3540
|
-
* and `holdInstance` take one each, and `release` gives one back. Entries are found by key or by
|
|
3541
|
-
* actor, so a raw instance and its proxy find the same entry.
|
|
3542
|
-
*/
|
|
3543
|
-
class EntityCache {
|
|
3544
|
-
constructor() {
|
|
3545
|
-
this.byKey = new Map();
|
|
3546
|
-
this.byActor = new WeakMap();
|
|
3547
|
-
}
|
|
3548
|
-
/** Cache `instance` under `keys` (empty and duplicate keys are skipped). Returns its entry. */
|
|
3549
|
-
add(instance, keys, options) {
|
|
3550
|
-
const existing = this.entryOf(instance);
|
|
3551
|
-
if (existing) {
|
|
3552
|
-
if (options.hold)
|
|
3553
|
-
existing.refCount += 1;
|
|
3554
|
-
for (const key of keys)
|
|
3555
|
-
if (key)
|
|
3556
|
-
this.addKey(instance, key);
|
|
3557
|
-
return existing;
|
|
3558
|
-
}
|
|
3559
|
-
const entry = {
|
|
3560
|
-
instance,
|
|
3561
|
-
refCount: options.hold ? 1 : 0,
|
|
3562
|
-
keys: new Set(),
|
|
3563
|
-
};
|
|
3564
|
-
this.byActor.set(instance.getService(), entry);
|
|
3565
|
-
for (const key of keys)
|
|
3566
|
-
if (key)
|
|
3567
|
-
this.addKey(instance, key);
|
|
3568
|
-
return entry;
|
|
3569
|
-
}
|
|
3570
|
-
/** The cached instance under `key`, without taking a hold. */
|
|
3571
|
-
peek(key) {
|
|
3572
|
-
return key ? this.byKey.get(key)?.instance : undefined;
|
|
3573
|
-
}
|
|
3574
|
-
/** The cached instance under `key`, taking a hold the caller releases with `release`. */
|
|
3575
|
-
hold(key) {
|
|
3576
|
-
const entry = key ? this.byKey.get(key) : undefined;
|
|
3577
|
-
if (!entry)
|
|
3578
|
-
return undefined;
|
|
3579
|
-
entry.refCount += 1;
|
|
3580
|
-
return entry.instance;
|
|
3581
|
-
}
|
|
3582
|
-
/** Take a hold on a cached instance. False when it isn't cached (unloaded, evicted). */
|
|
3583
|
-
holdInstance(instance) {
|
|
3584
|
-
const entry = this.entryOf(instance);
|
|
3585
|
-
if (!entry)
|
|
3586
|
-
return false;
|
|
3587
|
-
entry.refCount += 1;
|
|
3588
|
-
return true;
|
|
3589
|
-
}
|
|
3590
|
-
/**
|
|
3591
|
-
* Give back one hold. True when the instance should be torn down: its last hold went, or it
|
|
3592
|
-
* isn't cached at all (evicted while the caller held it).
|
|
3593
|
-
*/
|
|
3594
|
-
release(instance) {
|
|
3595
|
-
const entry = this.entryOf(instance);
|
|
3596
|
-
if (!entry)
|
|
3597
|
-
return true;
|
|
3598
|
-
entry.refCount -= 1;
|
|
3599
|
-
return entry.refCount <= 0;
|
|
3600
|
-
}
|
|
3601
|
-
entryOf(instance) {
|
|
3602
|
-
return this.byActor.get(instance.getService());
|
|
3603
|
-
}
|
|
3604
|
-
has(instance) {
|
|
3605
|
-
return this.entryOf(instance) !== undefined;
|
|
3606
|
-
}
|
|
3607
|
-
/**
|
|
3608
|
-
* Store the instance under one more key. A key held by another instance moves to this one:
|
|
3609
|
-
* the newest instance for a name or uid wins.
|
|
3610
|
-
*/
|
|
3611
|
-
addKey(instance, key) {
|
|
3612
|
-
const entry = this.entryOf(instance);
|
|
3613
|
-
if (!entry || !key)
|
|
3614
|
-
return;
|
|
3615
|
-
const previous = this.byKey.get(key);
|
|
3616
|
-
if (previous === entry)
|
|
3617
|
-
return;
|
|
3618
|
-
previous?.keys.delete(key);
|
|
3619
|
-
this.byKey.set(key, entry);
|
|
3620
|
-
entry.keys.add(key);
|
|
3621
|
-
}
|
|
3622
|
-
removeKey(instance, key) {
|
|
3623
|
-
const entry = this.entryOf(instance);
|
|
3624
|
-
if (!entry || !entry.keys.has(key))
|
|
3625
|
-
return;
|
|
3626
|
-
entry.keys.delete(key);
|
|
3627
|
-
if (this.byKey.get(key) === entry)
|
|
3628
|
-
this.byKey.delete(key);
|
|
3629
|
-
}
|
|
3630
|
-
/** Replace every key of the instance (a rename, an id that changed). */
|
|
3631
|
-
setKeys(instance, keys) {
|
|
3632
|
-
const entry = this.entryOf(instance);
|
|
3633
|
-
if (!entry)
|
|
3634
|
-
return;
|
|
3635
|
-
const next = new Set(keys.filter((key) => !!key));
|
|
3636
|
-
for (const key of [...entry.keys])
|
|
3637
|
-
if (!next.has(key))
|
|
3638
|
-
this.removeKey(instance, key);
|
|
3639
|
-
for (const key of next)
|
|
3640
|
-
this.addKey(instance, key);
|
|
3641
|
-
}
|
|
3642
|
-
keysOf(instance) {
|
|
3643
|
-
return [...(this.entryOf(instance)?.keys ?? [])];
|
|
3644
|
-
}
|
|
3645
|
-
/** Drop the instance under all its keys. Teardown (entityLifecycle) also releases its children. */
|
|
3646
|
-
remove(instance) {
|
|
3647
|
-
const entry = this.entryOf(instance);
|
|
3648
|
-
if (!entry)
|
|
3649
|
-
return undefined;
|
|
3650
|
-
for (const key of entry.keys) {
|
|
3651
|
-
if (this.byKey.get(key) === entry)
|
|
3652
|
-
this.byKey.delete(key);
|
|
3653
|
-
}
|
|
3654
|
-
entry.keys.clear();
|
|
3655
|
-
this.byActor.delete(instance.getService());
|
|
3656
|
-
return entry;
|
|
3657
|
-
}
|
|
3658
|
-
/** Every cached instance once, optionally filtered. */
|
|
3659
|
-
instances(filter) {
|
|
3660
|
-
const seen = new Set();
|
|
3661
|
-
const result = [];
|
|
3662
|
-
for (const entry of this.byKey.values()) {
|
|
3663
|
-
if (seen.has(entry))
|
|
3664
|
-
continue;
|
|
3665
|
-
seen.add(entry);
|
|
3666
|
-
if (!filter || filter(entry.instance))
|
|
3667
|
-
result.push(entry.instance);
|
|
3668
|
-
}
|
|
3669
|
-
return result;
|
|
3670
|
-
}
|
|
3671
|
-
get size() {
|
|
3672
|
-
return this.instances().length;
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3675
|
-
/**
|
|
3676
|
-
* Evictions and destroys, by scope (`schema:<name>`, `model:<id>`). Work that reads a row and then
|
|
3677
|
-
* creates an instance from it (a lookup by id) can't be cancelled by stopping actors: capture
|
|
3678
|
-
* `evictionLog.now()` before the read, and skip creating when `evictedSince(scopes, then)`. A scope
|
|
3679
|
-
* also counts as evicted while its destroy runs, since its rows still exist until the delete commits.
|
|
3680
|
-
*/
|
|
3681
|
-
const evictionLog = {
|
|
3682
|
-
generation: 0,
|
|
3683
|
-
last: new Map(),
|
|
3684
|
-
running: new Map(),
|
|
3685
|
-
now() {
|
|
3686
|
-
return this.generation;
|
|
3687
|
-
},
|
|
3688
|
-
/** Record an eviction of these scopes. Call the returned function once a destroy's rows are gone. */
|
|
3689
|
-
evict(scopes) {
|
|
3690
|
-
this.generation += 1;
|
|
3691
|
-
for (const scope of scopes) {
|
|
3692
|
-
this.last.set(scope, this.generation);
|
|
3693
|
-
this.running.set(scope, (this.running.get(scope) ?? 0) + 1);
|
|
3694
|
-
}
|
|
3695
|
-
let finished = false;
|
|
3696
|
-
return () => {
|
|
3697
|
-
if (finished)
|
|
3698
|
-
return;
|
|
3699
|
-
finished = true;
|
|
3700
|
-
// Work that read a row during the destroy and checks after it must still see the eviction
|
|
3701
|
-
this.generation += 1;
|
|
3702
|
-
for (const scope of scopes) {
|
|
3703
|
-
this.last.set(scope, this.generation);
|
|
3704
|
-
const remaining = (this.running.get(scope) ?? 1) - 1;
|
|
3705
|
-
if (remaining > 0)
|
|
3706
|
-
this.running.set(scope, remaining);
|
|
3707
|
-
else
|
|
3708
|
-
this.running.delete(scope);
|
|
3709
|
-
}
|
|
3710
|
-
};
|
|
3711
|
-
},
|
|
3712
|
-
/** True when a scope is being destroyed, or was evicted after `since`. */
|
|
3713
|
-
evictedSince(scopes, since) {
|
|
3714
|
-
for (const scope of scopes) {
|
|
3715
|
-
if (!scope)
|
|
3716
|
-
continue;
|
|
3717
|
-
if (this.running.has(scope))
|
|
3718
|
-
return true;
|
|
3719
|
-
if (this.generation !== since && (this.last.get(scope) ?? 0) > since)
|
|
3720
|
-
return true;
|
|
3721
|
-
}
|
|
3722
|
-
return false;
|
|
3723
|
-
},
|
|
3724
|
-
};
|
|
3725
|
-
|
|
3726
3569
|
/**
|
|
3727
3570
|
* Default timeout for create/find/all with waitForReady. Loads that touch OPFS and the DB can take
|
|
3728
3571
|
* several seconds on slow devices and CI runners; a load that is really stuck still errors.
|
|
@@ -3813,6 +3656,17 @@ async function waitForEntityReady(instance, options = {}) {
|
|
|
3813
3656
|
throw cause instanceof Error ? cause : new EntityLoadError('Entity failed to load', { cause });
|
|
3814
3657
|
}
|
|
3815
3658
|
}
|
|
3659
|
+
/**
|
|
3660
|
+
* A write or publish on an instance that was unloaded (no hold kept it past the grace period,
|
|
3661
|
+
* or it was destroyed, evicted or dropped by another tab). Look it up again, and hold it while
|
|
3662
|
+
* using it.
|
|
3663
|
+
*/
|
|
3664
|
+
class EntityUnloadedError extends Error {
|
|
3665
|
+
constructor(message) {
|
|
3666
|
+
super(message);
|
|
3667
|
+
this.name = 'EntityUnloadedError';
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3816
3670
|
/** Run `dispose` when the entity is torn down (unsubscribe a watch, revoke an object URL). */
|
|
3817
3671
|
function onEntityTeardown(instance, dispose) {
|
|
3818
3672
|
const lifecycle = lifecycleOf(instance);
|
|
@@ -3844,9 +3698,10 @@ function teardownEntity(instance, cache) {
|
|
|
3844
3698
|
lifecycle.error = new EntityLoadError('Entity was unloaded before it finished loading');
|
|
3845
3699
|
lifecycle.settle();
|
|
3846
3700
|
}
|
|
3701
|
+
// At once: the parent already waited out its grace period, or was destroyed or evicted
|
|
3847
3702
|
for (const release of lifecycle.children.values()) {
|
|
3848
3703
|
try {
|
|
3849
|
-
release();
|
|
3704
|
+
release({ immediate: true });
|
|
3850
3705
|
}
|
|
3851
3706
|
catch {
|
|
3852
3707
|
// A child that fails to release must not keep the rest held
|
|
@@ -3871,9 +3726,12 @@ function teardownEntity(instance, cache) {
|
|
|
3871
3726
|
// Already stopped
|
|
3872
3727
|
}
|
|
3873
3728
|
}
|
|
3874
|
-
/**
|
|
3875
|
-
|
|
3876
|
-
|
|
3729
|
+
/**
|
|
3730
|
+
* Give back one hold. With the last one the entity is torn down after the grace period (at once
|
|
3731
|
+
* with `immediate`, or when the grace period is 0); a hold taken meanwhile keeps it.
|
|
3732
|
+
*/
|
|
3733
|
+
function releaseEntity(instance, cache, options) {
|
|
3734
|
+
if (cache.release(instance, options))
|
|
3877
3735
|
teardownEntity(instance, cache);
|
|
3878
3736
|
}
|
|
3879
3737
|
/**
|
|
@@ -3886,6 +3744,14 @@ function evictEntities(cache, filter) {
|
|
|
3886
3744
|
teardownEntity(instance, cache);
|
|
3887
3745
|
return evicted;
|
|
3888
3746
|
}
|
|
3747
|
+
/**
|
|
3748
|
+
* Stop and drop every cached entity of every class, whoever holds it (client.stop()). Reaches the
|
|
3749
|
+
* caches through EntityCache.all, so callers needn't import the entity classes.
|
|
3750
|
+
*/
|
|
3751
|
+
function evictAllEntities() {
|
|
3752
|
+
for (const cache of EntityCache.all)
|
|
3753
|
+
evictEntities(cache, () => true);
|
|
3754
|
+
}
|
|
3889
3755
|
/**
|
|
3890
3756
|
* Delete an entity's rows. By default it leaves the cache first, so no lookup returns it meanwhile;
|
|
3891
3757
|
* with `leaveCache: 'after'` it stays cached until the rows are gone, so a lookup that read a row
|
|
@@ -3923,7 +3789,7 @@ function holdChild(parent, child, childCache) {
|
|
|
3923
3789
|
return true;
|
|
3924
3790
|
if (!childCache.holdInstance(child))
|
|
3925
3791
|
return false;
|
|
3926
|
-
lifecycle.children.set(key, () => releaseEntity(child, childCache));
|
|
3792
|
+
lifecycle.children.set(key, (options) => releaseEntity(child, childCache, options));
|
|
3927
3793
|
return true;
|
|
3928
3794
|
}
|
|
3929
3795
|
function releaseChildHold(parent, child) {
|
|
@@ -3940,6 +3806,258 @@ function heldChildActors(parent) {
|
|
|
3940
3806
|
return [...lifecycleOf(parent).children.keys()];
|
|
3941
3807
|
}
|
|
3942
3808
|
|
|
3809
|
+
/** Default for `SeedConfig.entityCache.unloadGraceMs`. */
|
|
3810
|
+
const DEFAULT_UNLOAD_GRACE_MS = 60000;
|
|
3811
|
+
let defaultUnloadGraceMs = DEFAULT_UNLOAD_GRACE_MS;
|
|
3812
|
+
let configuredUnloadGraceMs;
|
|
3813
|
+
/** How long an instance no one holds stays cached before it is torn down. 0: no grace period. */
|
|
3814
|
+
function entityUnloadGraceMs() {
|
|
3815
|
+
return configuredUnloadGraceMs ?? defaultUnloadGraceMs;
|
|
3816
|
+
}
|
|
3817
|
+
/** `client.init` sets the configured value; `undefined` (client stop, or none given) uses the default. */
|
|
3818
|
+
function setEntityUnloadGraceMs(ms) {
|
|
3819
|
+
configuredUnloadGraceMs = ms === undefined ? undefined : Math.max(0, ms);
|
|
3820
|
+
}
|
|
3821
|
+
/**
|
|
3822
|
+
* The cache behind an entity class (ADR 0014). `peek` takes no hold; `hold`, `add({ hold: true })`
|
|
3823
|
+
* and `holdInstance` take one each, and `release` gives one back. Entries are found by key or by
|
|
3824
|
+
* actor, so a raw instance and its proxy find the same entry.
|
|
3825
|
+
*
|
|
3826
|
+
* An entry with no holds (its last one released, or added or looked up without one) is torn down
|
|
3827
|
+
* after the grace period (`entityUnloadGraceMs`) unless a hold is taken first, which keeps the same
|
|
3828
|
+
* instance. With a grace period of 0, the last release tears it down at once and an entry that
|
|
3829
|
+
* never had a hold stays cached until it is evicted. Removing an entry (teardown, destroy,
|
|
3830
|
+
* eviction) cancels its timer.
|
|
3831
|
+
*/
|
|
3832
|
+
class EntityCache {
|
|
3833
|
+
constructor() {
|
|
3834
|
+
this.byKey = new Map();
|
|
3835
|
+
this.byActor = new WeakMap();
|
|
3836
|
+
EntityCache.all.add(this);
|
|
3837
|
+
}
|
|
3838
|
+
/** Cache `instance` under `keys` (empty and duplicate keys are skipped). Returns its entry. */
|
|
3839
|
+
add(instance, keys, options) {
|
|
3840
|
+
const existing = this.entryOf(instance);
|
|
3841
|
+
if (existing) {
|
|
3842
|
+
if (options.hold)
|
|
3843
|
+
this.addHold(existing);
|
|
3844
|
+
for (const key of keys)
|
|
3845
|
+
if (key)
|
|
3846
|
+
this.addKey(instance, key);
|
|
3847
|
+
return existing;
|
|
3848
|
+
}
|
|
3849
|
+
const entry = {
|
|
3850
|
+
instance,
|
|
3851
|
+
refCount: options.hold ? 1 : 0,
|
|
3852
|
+
keys: new Set(),
|
|
3853
|
+
};
|
|
3854
|
+
this.byActor.set(instance.getService(), entry);
|
|
3855
|
+
for (const key of keys)
|
|
3856
|
+
if (key)
|
|
3857
|
+
this.addKey(instance, key);
|
|
3858
|
+
if (!options.hold)
|
|
3859
|
+
this.keepUnheld(instance);
|
|
3860
|
+
return entry;
|
|
3861
|
+
}
|
|
3862
|
+
/** The cached instance under `key`, without taking a hold. */
|
|
3863
|
+
peek(key) {
|
|
3864
|
+
return key ? this.byKey.get(key)?.instance : undefined;
|
|
3865
|
+
}
|
|
3866
|
+
/** The cached instance under `key`, taking a hold the caller releases with `release`. */
|
|
3867
|
+
hold(key) {
|
|
3868
|
+
const entry = key ? this.byKey.get(key) : undefined;
|
|
3869
|
+
if (!entry)
|
|
3870
|
+
return undefined;
|
|
3871
|
+
this.addHold(entry);
|
|
3872
|
+
return entry.instance;
|
|
3873
|
+
}
|
|
3874
|
+
/** Take a hold on a cached instance. False when it isn't cached (unloaded, evicted). */
|
|
3875
|
+
holdInstance(instance) {
|
|
3876
|
+
const entry = this.entryOf(instance);
|
|
3877
|
+
if (!entry)
|
|
3878
|
+
return false;
|
|
3879
|
+
this.addHold(entry);
|
|
3880
|
+
return true;
|
|
3881
|
+
}
|
|
3882
|
+
/**
|
|
3883
|
+
* Give back one hold. True when the instance should be torn down now: its last hold went and
|
|
3884
|
+
* there is no grace period (or `immediate`), or it isn't cached at all (evicted while the caller
|
|
3885
|
+
* held it). After the last hold with a grace period, the teardown is scheduled instead. An
|
|
3886
|
+
* instance with no holds (a caller that never held it) is left as it is.
|
|
3887
|
+
*/
|
|
3888
|
+
release(instance, options = {}) {
|
|
3889
|
+
const entry = this.entryOf(instance);
|
|
3890
|
+
if (!entry)
|
|
3891
|
+
return true;
|
|
3892
|
+
if (entry.refCount <= 0)
|
|
3893
|
+
return false;
|
|
3894
|
+
entry.refCount -= 1;
|
|
3895
|
+
if (entry.refCount > 0)
|
|
3896
|
+
return false;
|
|
3897
|
+
if (options.immediate || entityUnloadGraceMs() === 0)
|
|
3898
|
+
return true;
|
|
3899
|
+
this.scheduleUnload(entry);
|
|
3900
|
+
return false;
|
|
3901
|
+
}
|
|
3902
|
+
/**
|
|
3903
|
+
* An instance a caller looked up without a hold: when no one holds it, restart its grace period,
|
|
3904
|
+
* so it stays cached that long after its last use. Does nothing without a grace period.
|
|
3905
|
+
*/
|
|
3906
|
+
keepUnheld(instance) {
|
|
3907
|
+
const entry = this.entryOf(instance);
|
|
3908
|
+
if (entry && entry.refCount <= 0 && entityUnloadGraceMs() > 0)
|
|
3909
|
+
this.scheduleUnload(entry);
|
|
3910
|
+
}
|
|
3911
|
+
addHold(entry) {
|
|
3912
|
+
entry.refCount += 1;
|
|
3913
|
+
this.cancelUnload(entry);
|
|
3914
|
+
}
|
|
3915
|
+
scheduleUnload(entry) {
|
|
3916
|
+
this.cancelUnload(entry);
|
|
3917
|
+
const teardown = () => {
|
|
3918
|
+
this.cancelUnload(entry);
|
|
3919
|
+
if (this.byActor.get(entry.instance.getService()) === entry && entry.refCount <= 0) {
|
|
3920
|
+
teardownEntity(entry.instance, this);
|
|
3921
|
+
}
|
|
3922
|
+
};
|
|
3923
|
+
const timer = setTimeout(teardown, entityUnloadGraceMs());
|
|
3924
|
+
timer.unref?.();
|
|
3925
|
+
entry.unloadTimer = timer;
|
|
3926
|
+
}
|
|
3927
|
+
cancelUnload(entry) {
|
|
3928
|
+
if (entry.unloadTimer === undefined)
|
|
3929
|
+
return;
|
|
3930
|
+
clearTimeout(entry.unloadTimer);
|
|
3931
|
+
entry.unloadTimer = undefined;
|
|
3932
|
+
}
|
|
3933
|
+
entryOf(instance) {
|
|
3934
|
+
return this.byActor.get(instance.getService());
|
|
3935
|
+
}
|
|
3936
|
+
has(instance) {
|
|
3937
|
+
return this.entryOf(instance) !== undefined;
|
|
3938
|
+
}
|
|
3939
|
+
/**
|
|
3940
|
+
* Store the instance under one more key. A key held by another instance moves to this one:
|
|
3941
|
+
* the newest instance for a name or uid wins.
|
|
3942
|
+
*/
|
|
3943
|
+
addKey(instance, key) {
|
|
3944
|
+
const entry = this.entryOf(instance);
|
|
3945
|
+
if (!entry || !key)
|
|
3946
|
+
return;
|
|
3947
|
+
const previous = this.byKey.get(key);
|
|
3948
|
+
if (previous === entry)
|
|
3949
|
+
return;
|
|
3950
|
+
previous?.keys.delete(key);
|
|
3951
|
+
this.byKey.set(key, entry);
|
|
3952
|
+
entry.keys.add(key);
|
|
3953
|
+
}
|
|
3954
|
+
removeKey(instance, key) {
|
|
3955
|
+
const entry = this.entryOf(instance);
|
|
3956
|
+
if (!entry || !entry.keys.has(key))
|
|
3957
|
+
return;
|
|
3958
|
+
entry.keys.delete(key);
|
|
3959
|
+
if (this.byKey.get(key) === entry)
|
|
3960
|
+
this.byKey.delete(key);
|
|
3961
|
+
}
|
|
3962
|
+
/** Replace every key of the instance (a rename, an id that changed). */
|
|
3963
|
+
setKeys(instance, keys) {
|
|
3964
|
+
const entry = this.entryOf(instance);
|
|
3965
|
+
if (!entry)
|
|
3966
|
+
return;
|
|
3967
|
+
const next = new Set(keys.filter((key) => !!key));
|
|
3968
|
+
for (const key of [...entry.keys])
|
|
3969
|
+
if (!next.has(key))
|
|
3970
|
+
this.removeKey(instance, key);
|
|
3971
|
+
for (const key of next)
|
|
3972
|
+
this.addKey(instance, key);
|
|
3973
|
+
}
|
|
3974
|
+
keysOf(instance) {
|
|
3975
|
+
return [...(this.entryOf(instance)?.keys ?? [])];
|
|
3976
|
+
}
|
|
3977
|
+
/** Drop the instance under all its keys. Teardown (entityLifecycle) also releases its children. */
|
|
3978
|
+
remove(instance) {
|
|
3979
|
+
const entry = this.entryOf(instance);
|
|
3980
|
+
if (!entry)
|
|
3981
|
+
return undefined;
|
|
3982
|
+
this.cancelUnload(entry);
|
|
3983
|
+
for (const key of entry.keys) {
|
|
3984
|
+
if (this.byKey.get(key) === entry)
|
|
3985
|
+
this.byKey.delete(key);
|
|
3986
|
+
}
|
|
3987
|
+
entry.keys.clear();
|
|
3988
|
+
this.byActor.delete(instance.getService());
|
|
3989
|
+
return entry;
|
|
3990
|
+
}
|
|
3991
|
+
/** Every cached instance once, optionally filtered. */
|
|
3992
|
+
instances(filter) {
|
|
3993
|
+
const seen = new Set();
|
|
3994
|
+
const result = [];
|
|
3995
|
+
for (const entry of this.byKey.values()) {
|
|
3996
|
+
if (seen.has(entry))
|
|
3997
|
+
continue;
|
|
3998
|
+
seen.add(entry);
|
|
3999
|
+
if (!filter || filter(entry.instance))
|
|
4000
|
+
result.push(entry.instance);
|
|
4001
|
+
}
|
|
4002
|
+
return result;
|
|
4003
|
+
}
|
|
4004
|
+
get size() {
|
|
4005
|
+
return this.instances().length;
|
|
4006
|
+
}
|
|
4007
|
+
}
|
|
4008
|
+
/** Every cache made, one per entity class; client.stop() evicts them all (evictAllEntities). */
|
|
4009
|
+
EntityCache.all = new Set();
|
|
4010
|
+
/**
|
|
4011
|
+
* Evictions and destroys, by scope (`schema:<name>`, `model:<id>`). Work that reads a row and then
|
|
4012
|
+
* creates an instance from it (a lookup by id) can't be cancelled by stopping actors: capture
|
|
4013
|
+
* `evictionLog.now()` before the read, and skip creating when `evictedSince(scopes, then)`. A scope
|
|
4014
|
+
* also counts as evicted while its destroy runs, since its rows still exist until the delete commits.
|
|
4015
|
+
*/
|
|
4016
|
+
const evictionLog = {
|
|
4017
|
+
generation: 0,
|
|
4018
|
+
last: new Map(),
|
|
4019
|
+
running: new Map(),
|
|
4020
|
+
now() {
|
|
4021
|
+
return this.generation;
|
|
4022
|
+
},
|
|
4023
|
+
/** Record an eviction of these scopes. Call the returned function once a destroy's rows are gone. */
|
|
4024
|
+
evict(scopes) {
|
|
4025
|
+
this.generation += 1;
|
|
4026
|
+
for (const scope of scopes) {
|
|
4027
|
+
this.last.set(scope, this.generation);
|
|
4028
|
+
this.running.set(scope, (this.running.get(scope) ?? 0) + 1);
|
|
4029
|
+
}
|
|
4030
|
+
let finished = false;
|
|
4031
|
+
return () => {
|
|
4032
|
+
if (finished)
|
|
4033
|
+
return;
|
|
4034
|
+
finished = true;
|
|
4035
|
+
// Work that read a row during the destroy and checks after it must still see the eviction
|
|
4036
|
+
this.generation += 1;
|
|
4037
|
+
for (const scope of scopes) {
|
|
4038
|
+
this.last.set(scope, this.generation);
|
|
4039
|
+
const remaining = (this.running.get(scope) ?? 1) - 1;
|
|
4040
|
+
if (remaining > 0)
|
|
4041
|
+
this.running.set(scope, remaining);
|
|
4042
|
+
else
|
|
4043
|
+
this.running.delete(scope);
|
|
4044
|
+
}
|
|
4045
|
+
};
|
|
4046
|
+
},
|
|
4047
|
+
/** True when a scope is being destroyed, or was evicted after `since`. */
|
|
4048
|
+
evictedSince(scopes, since) {
|
|
4049
|
+
for (const scope of scopes) {
|
|
4050
|
+
if (!scope)
|
|
4051
|
+
continue;
|
|
4052
|
+
if (this.running.has(scope))
|
|
4053
|
+
return true;
|
|
4054
|
+
if (this.generation !== since && (this.last.get(scope) ?? 0) > since)
|
|
4055
|
+
return true;
|
|
4056
|
+
}
|
|
4057
|
+
return false;
|
|
4058
|
+
},
|
|
4059
|
+
};
|
|
4060
|
+
|
|
3943
4061
|
const logger$4 = debug('seedSdk:itemProperty:loadProperty');
|
|
3944
4062
|
/**
|
|
3945
4063
|
* Load a property's value and definition: its current row (with a pending outbox value over it,
|
|
@@ -3970,15 +4088,14 @@ async function loadProperty(context) {
|
|
|
3970
4088
|
});
|
|
3971
4089
|
timing.mark('metadata');
|
|
3972
4090
|
if (!metadataRecord) {
|
|
3973
|
-
//
|
|
3974
|
-
//
|
|
3975
|
-
// getPublishPayload can route and attest the property (e.g. title, description).
|
|
4091
|
+
// No row yet: its first assignment writes one. The definition still comes from the model,
|
|
4092
|
+
// since the setter checks and routes values by it (planPropertyWrite).
|
|
3976
4093
|
let propertyRecordSchema = undefined;
|
|
3977
4094
|
const modelNameForNew = context.modelName;
|
|
3978
4095
|
if (modelNameForNew) {
|
|
3979
4096
|
try {
|
|
3980
|
-
const _mod_3 = await import('./tabEvents-
|
|
3981
|
-
const _ns_3 = _mod_3.
|
|
4097
|
+
const _mod_3 = await import('./tabEvents-BHPY5I08.js');
|
|
4098
|
+
const _ns_3 = _mod_3.bh;
|
|
3982
4099
|
const { resolveItemModelFileId, modelNameForType } = _ns_3;
|
|
3983
4100
|
const itemModelFileId = await resolveItemModelFileId({
|
|
3984
4101
|
modelFileId: context.modelFileId,
|
|
@@ -4017,8 +4134,8 @@ async function loadProperty(context) {
|
|
|
4017
4134
|
// Load propertyRecordSchema from database to make ItemProperty independent from Model
|
|
4018
4135
|
let propertyRecordSchema = undefined;
|
|
4019
4136
|
// Model names are only unique per schema: pin lookups to the item's own model row.
|
|
4020
|
-
const _mod_4 = await import('./tabEvents-
|
|
4021
|
-
const _ns_4 = _mod_4.
|
|
4137
|
+
const _mod_4 = await import('./tabEvents-BHPY5I08.js');
|
|
4138
|
+
const _ns_4 = _mod_4.bh;
|
|
4022
4139
|
const { resolveItemModelFileId, modelNameForType } = _ns_4;
|
|
4023
4140
|
const modelFileId = await resolveItemModelFileId({
|
|
4024
4141
|
modelFileId: context.modelFileId,
|
|
@@ -4122,11 +4239,11 @@ async function loadPropertyDefinition(db, { propertyId, modelName, modelFileId,
|
|
|
4122
4239
|
}
|
|
4123
4240
|
if (!modelName)
|
|
4124
4241
|
return undefined;
|
|
4125
|
-
const { loadModelPropertyRecordSchemas } = await import('./modelPropertyRecordSchemas-
|
|
4242
|
+
const { loadModelPropertyRecordSchemas } = await import('./modelPropertyRecordSchemas-BGvtTyaG.js');
|
|
4126
4243
|
const definition = (await loadModelPropertyRecordSchemas(modelName, modelFileId, db)).get(propertyName);
|
|
4127
4244
|
if (definition)
|
|
4128
4245
|
return definition;
|
|
4129
|
-
const _mod_5 = await import('./errors-
|
|
4246
|
+
const _mod_5 = await import('./errors-DpC9W4i3.js');
|
|
4130
4247
|
const _ns_5 = _mod_5.a4;
|
|
4131
4248
|
const { Model } = _ns_5;
|
|
4132
4249
|
const { modelPropertiesToObject } = await Promise.resolve().then(function () { return model; });
|
|
@@ -4232,13 +4349,17 @@ let validationLoading;
|
|
|
4232
4349
|
function whenValidationLoaded() {
|
|
4233
4350
|
if (validationService)
|
|
4234
4351
|
return Promise.resolve();
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4352
|
+
// async/await, not import().then: rollup's dynamic-import rewrite (rollup.config.mjs) only
|
|
4353
|
+
// neutralizes the minified chunk-export read (`.then(n => n._)`) in this form
|
|
4354
|
+
validationLoading ?? (validationLoading = (async () => {
|
|
4355
|
+
try {
|
|
4356
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-C1xqJFxI.js');
|
|
4357
|
+
validationService = new SchemaValidationService();
|
|
4358
|
+
}
|
|
4359
|
+
finally {
|
|
4360
|
+
validationLoading = undefined;
|
|
4361
|
+
}
|
|
4362
|
+
})());
|
|
4242
4363
|
return validationLoading;
|
|
4243
4364
|
}
|
|
4244
4365
|
const isValidationLoaded = () => validationService !== undefined;
|
|
@@ -4467,17 +4588,17 @@ hints = {}) => {
|
|
|
4467
4588
|
}
|
|
4468
4589
|
try {
|
|
4469
4590
|
if (hints.propertyId != null) {
|
|
4470
|
-
const _mod_6 = await import('./tabEvents-
|
|
4471
|
-
const _ns_6 = _mod_6.
|
|
4591
|
+
const _mod_6 = await import('./tabEvents-BHPY5I08.js');
|
|
4592
|
+
const _ns_6 = _mod_6.bi;
|
|
4472
4593
|
const { getPropertyDefinition } = _ns_6;
|
|
4473
4594
|
const definition = await getPropertyDefinition(hints.propertyId);
|
|
4474
4595
|
if (definition)
|
|
4475
4596
|
return definition;
|
|
4476
4597
|
}
|
|
4477
|
-
const _mod_7 = await import('./tabEvents-
|
|
4478
|
-
const _ns_7 = _mod_7.
|
|
4598
|
+
const _mod_7 = await import('./tabEvents-BHPY5I08.js');
|
|
4599
|
+
const _ns_7 = _mod_7.bh;
|
|
4479
4600
|
const { resolveItemModelFileId } = _ns_7;
|
|
4480
|
-
const { getModelPropertyDefinitions, resolvePropertyKey } = await import('./property-
|
|
4601
|
+
const { getModelPropertyDefinitions, resolvePropertyKey } = await import('./property-QjljUeb9.js');
|
|
4481
4602
|
const modelFileId = (await resolveItemModelFileId(hints)) ?? undefined;
|
|
4482
4603
|
const name = modelName || ((await modelTypeToModelName(modelType)) ?? '');
|
|
4483
4604
|
// An ambiguous bare name reads nothing here; the in-memory model below may still know it
|
|
@@ -4485,7 +4606,7 @@ hints = {}) => {
|
|
|
4485
4606
|
const key = resolvePropertyKey(definitions, propertyName);
|
|
4486
4607
|
if (key)
|
|
4487
4608
|
return definitions[key];
|
|
4488
|
-
const _mod_8 = await import('./errors-
|
|
4609
|
+
const _mod_8 = await import('./errors-DpC9W4i3.js');
|
|
4489
4610
|
const _ns_8 = _mod_8.a4;
|
|
4490
4611
|
const { Model } = _ns_8;
|
|
4491
4612
|
const { modelPropertiesToObject } = await Promise.resolve().then(function () { return model; });
|
|
@@ -4506,8 +4627,8 @@ hints = {}) => {
|
|
|
4506
4627
|
const modelTypeToModelName = async (modelType) => {
|
|
4507
4628
|
if (!modelType)
|
|
4508
4629
|
return undefined;
|
|
4509
|
-
const _mod_9 = await import('./tabEvents-
|
|
4510
|
-
const _ns_9 = _mod_9.
|
|
4630
|
+
const _mod_9 = await import('./tabEvents-BHPY5I08.js');
|
|
4631
|
+
const _ns_9 = _mod_9.bh;
|
|
4511
4632
|
const { modelNameForType } = _ns_9;
|
|
4512
4633
|
return modelNameForType(modelType).catch(() => undefined);
|
|
4513
4634
|
};
|
|
@@ -4670,7 +4791,7 @@ class ItemProperty {
|
|
|
4670
4791
|
return;
|
|
4671
4792
|
}
|
|
4672
4793
|
// Use dynamic import to break circular dependency
|
|
4673
|
-
const schemaMod = await import('./index-
|
|
4794
|
+
const schemaMod = await import('./index-uDLe9y9H.js');
|
|
4674
4795
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
4675
4796
|
const { context } = snapshot;
|
|
4676
4797
|
const { propertyRecordSchema } = context;
|
|
@@ -4883,7 +5004,7 @@ class ItemProperty {
|
|
|
4883
5004
|
// The change feed reports writes by stored name: watch every name this property's rows have
|
|
4884
5005
|
const propertyNames = [...property.names];
|
|
4885
5006
|
if (propertyId != null) {
|
|
4886
|
-
const _mod_10 = await import('./index-
|
|
5007
|
+
const _mod_10 = await import('./index-BjWk0x4-.js');
|
|
4887
5008
|
const _ns_10 = _mod_10.s;
|
|
4888
5009
|
const { metadata } = _ns_10;
|
|
4889
5010
|
const { eq: eqOp } = await import('drizzle-orm');
|
|
@@ -4923,12 +5044,17 @@ class ItemProperty {
|
|
|
4923
5044
|
// A pending edit settles the conflict when it applies, so an overlaid row shows none.
|
|
4924
5045
|
// `assignSeq` marks a read begun before an assignment in this tab: it may predate that op,
|
|
4925
5046
|
// which the context already shows, so the feed drops it.
|
|
5047
|
+
// Sync records a conflict and moves its draft to newest in one transaction, so a row read
|
|
5048
|
+
// before the conflict may be the synced one: read the row again once a conflict shows.
|
|
4926
5049
|
const readRow = async () => {
|
|
4927
5050
|
const assignSeq = this._assignSeq;
|
|
4928
|
-
const
|
|
5051
|
+
const read = () => currentPropertyRow({ seedLocalId, seedUid }, { match: property, propertyName }, { overlay: true, db });
|
|
5052
|
+
let row = await read();
|
|
4929
5053
|
if (!row)
|
|
4930
5054
|
return row;
|
|
4931
5055
|
const conflict = row.overlaid ? null : await getPropertyConflict(row.seedLocalId ?? seedLocalId, propertyName);
|
|
5056
|
+
if (conflict)
|
|
5057
|
+
row = (await read()) ?? row;
|
|
4932
5058
|
return { ...row, conflict, assignSeq };
|
|
4933
5059
|
};
|
|
4934
5060
|
// In the browser the feed watch below reads the row at once, so only Node (no change feed)
|
|
@@ -5057,6 +5183,33 @@ class ItemProperty {
|
|
|
5057
5183
|
});
|
|
5058
5184
|
}
|
|
5059
5185
|
}
|
|
5186
|
+
/** Takes a property definition read from its row, as the constructor takes the initial one. */
|
|
5187
|
+
_applyDefinition(propertyRecordSchema) {
|
|
5188
|
+
this._service.send({ type: 'updateContext', propertyRecordSchema });
|
|
5189
|
+
this._dataType = normalizeDataType(propertyRecordSchema.dataType);
|
|
5190
|
+
const isList = isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.List);
|
|
5191
|
+
this._isList = isList;
|
|
5192
|
+
this._isRelation = isList
|
|
5193
|
+
? !!propertyRecordSchema.ref
|
|
5194
|
+
: isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.Relation);
|
|
5195
|
+
}
|
|
5196
|
+
/**
|
|
5197
|
+
* Gives cached instances of these properties their rows' current definitions, after a schema
|
|
5198
|
+
* change wrote the rows (refreshCachedProperties). An instance keeps the definition it loaded
|
|
5199
|
+
* with otherwise: Node has no live query, and the browser's arrives some time after the write.
|
|
5200
|
+
*/
|
|
5201
|
+
static async refreshDefinitions(propertyFileIds) {
|
|
5202
|
+
const instances = this.cache.instances().filter((instance) => !isActorStopped(instance._service));
|
|
5203
|
+
if (instances.length === 0)
|
|
5204
|
+
return;
|
|
5205
|
+
const definitions = await getPropertyDefinitionsByFileId(propertyFileIds);
|
|
5206
|
+
for (const instance of instances) {
|
|
5207
|
+
const fileId = instance._getSnapshotContext().propertyRecordSchema?.id;
|
|
5208
|
+
const definition = fileId ? definitions.get(fileId) : undefined;
|
|
5209
|
+
if (definition)
|
|
5210
|
+
instance._applyDefinition(definition);
|
|
5211
|
+
}
|
|
5212
|
+
}
|
|
5060
5213
|
/**
|
|
5061
5214
|
* Set up liveQuery subscription to watch for property schema changes in the properties table.
|
|
5062
5215
|
* When ModelProperty dataType (or other schema fields) changes in the database, ItemProperty
|
|
@@ -5077,8 +5230,8 @@ class ItemProperty {
|
|
|
5077
5230
|
const ctx = this._service.getSnapshot().context;
|
|
5078
5231
|
let modelFileId;
|
|
5079
5232
|
try {
|
|
5080
|
-
const _mod_11 = await import('./tabEvents-
|
|
5081
|
-
const _ns_11 = _mod_11.
|
|
5233
|
+
const _mod_11 = await import('./tabEvents-BHPY5I08.js');
|
|
5234
|
+
const _ns_11 = _mod_11.bh;
|
|
5082
5235
|
const { resolveItemModelFileId } = _ns_11;
|
|
5083
5236
|
modelFileId = await resolveItemModelFileId({
|
|
5084
5237
|
modelFileId: ctx.modelFileId,
|
|
@@ -5131,29 +5284,7 @@ class ItemProperty {
|
|
|
5131
5284
|
const required = row.required;
|
|
5132
5285
|
const propertyRecordSchema = propertyDefinitionFromRow({ ...row, required: required == null ? null : !!required }, refModelName);
|
|
5133
5286
|
logger(`[ItemProperty._setupPropertySchemaLiveQuery] Schema updated for ${propertyName}: dataType=${row.dataType}`);
|
|
5134
|
-
this.
|
|
5135
|
-
type: 'updateContext',
|
|
5136
|
-
propertyRecordSchema,
|
|
5137
|
-
});
|
|
5138
|
-
// Update instance fields to match new schema (mirror constructor logic)
|
|
5139
|
-
this._dataType = normalizeDataType(propertyRecordSchema.dataType);
|
|
5140
|
-
if (isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.Relation)) {
|
|
5141
|
-
;
|
|
5142
|
-
this._isRelation = true;
|
|
5143
|
-
}
|
|
5144
|
-
else {
|
|
5145
|
-
;
|
|
5146
|
-
this._isRelation = false;
|
|
5147
|
-
}
|
|
5148
|
-
if (isDataType(propertyRecordSchema.dataType, ModelPropertyDataTypes.List)) {
|
|
5149
|
-
;
|
|
5150
|
-
this._isList = true;
|
|
5151
|
-
this._isRelation = !!(propertyRecordSchema.ref);
|
|
5152
|
-
}
|
|
5153
|
-
else {
|
|
5154
|
-
;
|
|
5155
|
-
this._isList = false;
|
|
5156
|
-
}
|
|
5287
|
+
this._applyDefinition(propertyRecordSchema);
|
|
5157
5288
|
},
|
|
5158
5289
|
error: (error) => {
|
|
5159
5290
|
logger(`[ItemProperty._setupPropertySchemaLiveQuery] LiveQuery error: ${error}`);
|
|
@@ -5205,6 +5336,8 @@ class ItemProperty {
|
|
|
5205
5336
|
if (cached) {
|
|
5206
5337
|
if (holds)
|
|
5207
5338
|
this.cache.holdInstance(cached);
|
|
5339
|
+
else
|
|
5340
|
+
this.cache.keepUnheld(cached);
|
|
5208
5341
|
for (const key of [keyByLocal, keyByUid])
|
|
5209
5342
|
this.cache.addKey(cached, key);
|
|
5210
5343
|
this.syncFromRow(cached, props);
|
|
@@ -5337,8 +5470,11 @@ class ItemProperty {
|
|
|
5337
5470
|
}
|
|
5338
5471
|
return undefined;
|
|
5339
5472
|
}
|
|
5340
|
-
/**
|
|
5341
|
-
|
|
5473
|
+
/**
|
|
5474
|
+
* The property's instance, loaded from its row when it isn't cached. Takes no hold unless
|
|
5475
|
+
* `hold: true` (release it with `unload()`).
|
|
5476
|
+
*/
|
|
5477
|
+
static async find({ propertyName, seedLocalId, seedUid, modelName: modelNameOption, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false, }) {
|
|
5342
5478
|
if ((!seedLocalId && !seedUid) || !propertyName) {
|
|
5343
5479
|
return undefined;
|
|
5344
5480
|
}
|
|
@@ -5355,8 +5491,10 @@ class ItemProperty {
|
|
|
5355
5491
|
return undefined;
|
|
5356
5492
|
for (const key of [keyByLocal, keyByUid])
|
|
5357
5493
|
this.cache.addKey(cached, key);
|
|
5358
|
-
if (hold
|
|
5494
|
+
if (hold)
|
|
5359
5495
|
this.cache.holdInstance(cached);
|
|
5496
|
+
else
|
|
5497
|
+
this.cache.keepUnheld(cached);
|
|
5360
5498
|
return cached;
|
|
5361
5499
|
};
|
|
5362
5500
|
foundProperty = fromCache();
|
|
@@ -5400,10 +5538,10 @@ class ItemProperty {
|
|
|
5400
5538
|
/**
|
|
5401
5539
|
* Get all ItemProperty instances for an item.
|
|
5402
5540
|
* Loads property data via getItemProperties, creates instances via create, optionally waits for idle.
|
|
5403
|
-
* Takes
|
|
5541
|
+
* Takes no holds unless `hold: true`, as `find`.
|
|
5404
5542
|
*/
|
|
5405
5543
|
static async all(params, options) {
|
|
5406
|
-
const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold } = options ?? {};
|
|
5544
|
+
const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false } = options ?? {};
|
|
5407
5545
|
const { seedLocalId, seedUid } = params;
|
|
5408
5546
|
if (!seedLocalId && !seedUid) {
|
|
5409
5547
|
return [];
|
|
@@ -5411,8 +5549,8 @@ class ItemProperty {
|
|
|
5411
5549
|
const propertiesData = await getItemProperties({ seedLocalId, seedUid });
|
|
5412
5550
|
const instances = [];
|
|
5413
5551
|
const seenNormalized = new Set();
|
|
5414
|
-
const _mod_12 = await import('./tabEvents-
|
|
5415
|
-
const _ns_12 = _mod_12.
|
|
5552
|
+
const _mod_12 = await import('./tabEvents-BHPY5I08.js');
|
|
5553
|
+
const _ns_12 = _mod_12.bh;
|
|
5416
5554
|
const { resolveItemModelFileId } = _ns_12;
|
|
5417
5555
|
const itemModelFileId = await resolveItemModelFileId({ seedLocalId, seedUid });
|
|
5418
5556
|
// One lookup per model type, not per property
|
|
@@ -5433,7 +5571,7 @@ class ItemProperty {
|
|
|
5433
5571
|
// (`textId` → `text`, `authorIdentityIds` → `authors`)
|
|
5434
5572
|
const definitionsKey = JSON.stringify([modelName, modelFileId ?? null]);
|
|
5435
5573
|
if (modelName && !definitionsByModel.has(definitionsKey)) {
|
|
5436
|
-
const { getModelPropertyDefinitions } = await import('./property-
|
|
5574
|
+
const { getModelPropertyDefinitions } = await import('./property-QjljUeb9.js');
|
|
5437
5575
|
definitionsByModel.set(definitionsKey,
|
|
5438
5576
|
// No model row: the stored name decides
|
|
5439
5577
|
getModelPropertyDefinitions(modelName, { modelFileId }).then(Object.fromEntries, () => ({})));
|
|
@@ -5607,7 +5745,7 @@ class ItemProperty {
|
|
|
5607
5745
|
const { seedLocalId, propertyName } = this._getSnapshotContext();
|
|
5608
5746
|
if (!seedLocalId || !propertyName)
|
|
5609
5747
|
return;
|
|
5610
|
-
const { appendOutboxOpAndWait, markPropertyConflictsResolved, startItemOutbox, throwItemWriteError } = await import('./index-
|
|
5748
|
+
const { appendOutboxOpAndWait, markPropertyConflictsResolved, startItemOutbox, throwItemWriteError } = await import('./index-BMHqJ4kN.js');
|
|
5611
5749
|
if (choice === 'remote') {
|
|
5612
5750
|
startItemOutbox();
|
|
5613
5751
|
await appendOutboxOpAndWait({
|
|
@@ -5654,6 +5792,7 @@ class ItemProperty {
|
|
|
5654
5792
|
* any tab, else its stored row.
|
|
5655
5793
|
*/
|
|
5656
5794
|
setValue(value) {
|
|
5795
|
+
this._assertLoaded('set');
|
|
5657
5796
|
// An empty Image, File or Html value has nothing to store: it clears the property
|
|
5658
5797
|
if ((value == null || (typeof value === 'string' && value.trim() === '')) && this._holdsStorageSeed(this._getSnapshotContext())) {
|
|
5659
5798
|
this._assign(null, { retract: false });
|
|
@@ -5754,8 +5893,8 @@ class ItemProperty {
|
|
|
5754
5893
|
context = this._getSnapshotContext();
|
|
5755
5894
|
if (!context.seedLocalId) {
|
|
5756
5895
|
// An item known only by its seed uid: its local seed, if it has one
|
|
5757
|
-
const _mod_13 = await import('./tabEvents-
|
|
5758
|
-
const _ns_13 = _mod_13.
|
|
5896
|
+
const _mod_13 = await import('./tabEvents-BHPY5I08.js');
|
|
5897
|
+
const _ns_13 = _mod_13.bg;
|
|
5759
5898
|
const { findSeedRow } = _ns_13;
|
|
5760
5899
|
const seedLocalId = context.seedUid ? (await findSeedRow({ uid: context.seedUid }))?.localId : undefined;
|
|
5761
5900
|
if (!seedLocalId)
|
|
@@ -5794,7 +5933,7 @@ class ItemProperty {
|
|
|
5794
5933
|
/** Waits for an appended op to settle, then shows its row, or the current value if it failed. */
|
|
5795
5934
|
async _followWrite(write, appended, plan) {
|
|
5796
5935
|
try {
|
|
5797
|
-
const { getOutboxOps, outboxOpResult, startItemOutbox, waitForOutboxOp } = await import('./index-
|
|
5936
|
+
const { getOutboxOps, outboxOpResult, startItemOutbox, waitForOutboxOp } = await import('./index-BMHqJ4kN.js');
|
|
5798
5937
|
startItemOutbox();
|
|
5799
5938
|
const opId = await appended;
|
|
5800
5939
|
await waitForOutboxOp(opId);
|
|
@@ -5853,7 +5992,7 @@ class ItemProperty {
|
|
|
5853
5992
|
this._service.send({ type: 'updateContext', ...outcome.applied, isSaving: false });
|
|
5854
5993
|
return;
|
|
5855
5994
|
}
|
|
5856
|
-
const { throwItemWriteError } = await import('./index-
|
|
5995
|
+
const { throwItemWriteError } = await import('./index-BMHqJ4kN.js');
|
|
5857
5996
|
let error = outcome.error;
|
|
5858
5997
|
try {
|
|
5859
5998
|
throwItemWriteError(outcome.error);
|
|
@@ -5919,6 +6058,7 @@ class ItemProperty {
|
|
|
5919
6058
|
* ItemPropertySaveValidationError when the value broke a rule and was not written.
|
|
5920
6059
|
*/
|
|
5921
6060
|
async save() {
|
|
6061
|
+
this._assertLoaded('save');
|
|
5922
6062
|
const ctx = this._getSnapshotContext();
|
|
5923
6063
|
const label = `save ${ctx?.modelName ?? '?'}.${ctx?.propertyName ?? '?'}`;
|
|
5924
6064
|
const { assertItemOwned } = await Promise.resolve().then(function () { return ownership; });
|
|
@@ -5949,6 +6089,14 @@ class ItemProperty {
|
|
|
5949
6089
|
* Every cache key holding this instance: its item's local id and seed uid, and the name it had
|
|
5950
6090
|
* before a rename (List of relation). They share one entry.
|
|
5951
6091
|
*/
|
|
6092
|
+
/** Throws EntityUnloadedError, naming the property and its item, when this instance was unloaded. */
|
|
6093
|
+
_assertLoaded(action) {
|
|
6094
|
+
if (!isEntityTornDown(this))
|
|
6095
|
+
return;
|
|
6096
|
+
const { seedLocalId, seedUid, modelName, propertyName } = this._getSnapshotContext();
|
|
6097
|
+
throw new EntityUnloadedError(`Cannot ${action} ${modelName ?? '?'}.${propertyName ?? '?'} of item ${seedLocalId ?? seedUid ?? '(no id)'}: ` +
|
|
6098
|
+
'this ItemProperty instance was unloaded. Look the item or property up again, and hold it while you use it.');
|
|
6099
|
+
}
|
|
5952
6100
|
/** Releases this caller's hold; the last one stops the property and drops it from the cache. */
|
|
5953
6101
|
unload() {
|
|
5954
6102
|
releaseEntity(this, ItemProperty.cache);
|
|
@@ -5979,7 +6127,7 @@ class ItemProperty {
|
|
|
5979
6127
|
if (db && seedLocalId) {
|
|
5980
6128
|
// Through the outbox (ADR 0019): after the property's pending edits, which would
|
|
5981
6129
|
// otherwise write its rows back
|
|
5982
|
-
const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-
|
|
6130
|
+
const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-BMHqJ4kN.js');
|
|
5983
6131
|
startItemOutbox();
|
|
5984
6132
|
await appendOutboxOpAndWait({
|
|
5985
6133
|
seedLocalId,
|
|
@@ -5989,7 +6137,7 @@ class ItemProperty {
|
|
|
5989
6137
|
}).catch(throwItemWriteError);
|
|
5990
6138
|
}
|
|
5991
6139
|
else if (db) {
|
|
5992
|
-
const _mod_14 = await import('./index-
|
|
6140
|
+
const _mod_14 = await import('./index-BjWk0x4-.js');
|
|
5993
6141
|
const _ns_14 = _mod_14.s;
|
|
5994
6142
|
const seedSchemaMod = _ns_14;
|
|
5995
6143
|
const { metadata } = seedSchemaMod;
|
|
@@ -6018,6 +6166,7 @@ class ItemProperty {
|
|
|
6018
6166
|
}
|
|
6019
6167
|
/** Cached as `Item_<id>_<propertyName>` under its item's local id and seed uid. */
|
|
6020
6168
|
ItemProperty.cache = new EntityCache();
|
|
6169
|
+
addCachedPropertyRefresher((propertyFileIds) => ItemProperty.refreshDefinitions(propertyFileIds));
|
|
6021
6170
|
|
|
6022
6171
|
var ItemProperty$1 = /*#__PURE__*/Object.freeze({
|
|
6023
6172
|
__proto__: null,
|
|
@@ -6221,7 +6370,7 @@ const createMetadata = async (metadataValues, propertyRecordSchema, options) =>
|
|
|
6221
6370
|
propertyRecordSchema?.validation &&
|
|
6222
6371
|
metadataValues.propertyValue != null &&
|
|
6223
6372
|
metadataValues.propertyValue !== '') {
|
|
6224
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
6373
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-C1xqJFxI.js');
|
|
6225
6374
|
const validationService = new SchemaValidationService();
|
|
6226
6375
|
const validationResult = validationService.validatePropertyValue(metadataValues.propertyValue, normalizeDataType(propertyRecordSchema.dataType), propertyRecordSchema.validation, propertyRecordSchema.refValueType
|
|
6227
6376
|
? normalizeDataType(String(propertyRecordSchema.refValueType))
|
|
@@ -6315,7 +6464,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6315
6464
|
}
|
|
6316
6465
|
const seedType = easName(modelName);
|
|
6317
6466
|
// Dynamic import to break circular dependency
|
|
6318
|
-
const _mod_15 = await import('./errors-
|
|
6467
|
+
const _mod_15 = await import('./errors-DpC9W4i3.js');
|
|
6319
6468
|
const _ns_15 = _mod_15.a4;
|
|
6320
6469
|
const modelMod = _ns_15;
|
|
6321
6470
|
const { Model } = modelMod;
|
|
@@ -6373,7 +6522,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6373
6522
|
}
|
|
6374
6523
|
rows.push({ propertyName, propertyValue, propertyRecordSchema, schemaUid: schemaUids.get(propertyName) });
|
|
6375
6524
|
}
|
|
6376
|
-
const { appendOutboxOpAndWait, startItemOutbox } = await import('./index-
|
|
6525
|
+
const { appendOutboxOpAndWait, startItemOutbox } = await import('./index-BMHqJ4kN.js');
|
|
6377
6526
|
startItemOutbox();
|
|
6378
6527
|
const fields = await timed(`${label} seed fields`, () => resolveNewSeedFields(seedType));
|
|
6379
6528
|
const applied = await timed(`${label} outbox apply`, () => appendOutboxOpAndWait({
|
|
@@ -6392,7 +6541,7 @@ const createNewItem = async ({ modelName, modelFileId, ...propertyData }) => {
|
|
|
6392
6541
|
}
|
|
6393
6542
|
catch (error) {
|
|
6394
6543
|
// Staged values of a create that never got appended (once appended, the op's discard does it)
|
|
6395
|
-
const _mod_16 = await import('./errors-
|
|
6544
|
+
const _mod_16 = await import('./errors-DpC9W4i3.js');
|
|
6396
6545
|
const _ns_16 = _mod_16.a7;
|
|
6397
6546
|
const { deleteFiles } = _ns_16;
|
|
6398
6547
|
await deleteFiles(stagedPaths);
|
|
@@ -6468,14 +6617,14 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6468
6617
|
};
|
|
6469
6618
|
// The model's property definitions from their rows; a model created in this session whose
|
|
6470
6619
|
// rows aren't written yet gives its in-memory ones
|
|
6471
|
-
const { getModelPropertyDefinitions } = await import('./property-
|
|
6620
|
+
const { getModelPropertyDefinitions } = await import('./property-QjljUeb9.js');
|
|
6472
6621
|
let propertySchemas = Object.fromEntries(await getModelPropertyDefinitions(modelName, modelScope).catch((err) => {
|
|
6473
6622
|
logger(`No property definitions for ${modelName}: ${err}`);
|
|
6474
6623
|
return [];
|
|
6475
6624
|
}));
|
|
6476
6625
|
if (Object.keys(propertySchemas).length === 0) {
|
|
6477
6626
|
const { modelPropertiesToObject } = await Promise.resolve().then(function () { return model; });
|
|
6478
|
-
const _mod_17 = await import('./errors-
|
|
6627
|
+
const _mod_17 = await import('./errors-DpC9W4i3.js');
|
|
6479
6628
|
const _ns_17 = _mod_17.a4;
|
|
6480
6629
|
const { Model } = _ns_17;
|
|
6481
6630
|
const model$1 = Model.resolve(modelName, modelScope);
|
|
@@ -6503,7 +6652,7 @@ const createItemPropertyInstances = async (metadataRows, seedLocalId, seedUid, m
|
|
|
6503
6652
|
// Infer propertyRecordSchema from metadata when schema is missing (enables persistence)
|
|
6504
6653
|
let propSchema = propertySchemas[propertyName];
|
|
6505
6654
|
if (!propSchema && isRefTypeFromMeta) {
|
|
6506
|
-
const schemaMod = await import('./index-
|
|
6655
|
+
const schemaMod = await import('./index-uDLe9y9H.js');
|
|
6507
6656
|
const { ModelPropertyDataTypes } = schemaMod;
|
|
6508
6657
|
propSchema = {
|
|
6509
6658
|
dataType: refSeedType === 'html' ? ModelPropertyDataTypes.Html
|
|
@@ -6886,7 +7035,7 @@ const getModel = () => {
|
|
|
6886
7035
|
// the fragile `import(...).then(n => n.X)` chunk-namespace pattern.
|
|
6887
7036
|
if (!modelImportPromise) {
|
|
6888
7037
|
modelImportPromise = (async () => {
|
|
6889
|
-
const _mod_18 = await import('./errors-
|
|
7038
|
+
const _mod_18 = await import('./errors-DpC9W4i3.js');
|
|
6890
7039
|
const _ns_18 = _mod_18.a4;
|
|
6891
7040
|
const mod = _ns_18;
|
|
6892
7041
|
ModelClass = mod.Model;
|
|
@@ -7002,6 +7151,7 @@ class Item {
|
|
|
7002
7151
|
});
|
|
7003
7152
|
};
|
|
7004
7153
|
this.unpublish = async () => {
|
|
7154
|
+
this._assertLoaded('unpublish');
|
|
7005
7155
|
const { assertItemOwned } = await Promise.resolve().then(function () { return ownership; });
|
|
7006
7156
|
const { getRevokeExecutor } = await Promise.resolve().then(function () { return publishConfig; });
|
|
7007
7157
|
await assertItemOwned(this);
|
|
@@ -7045,6 +7195,7 @@ class Item {
|
|
|
7045
7195
|
* if it failed. Throws OwnershipError if none of the client's addresses own the item.
|
|
7046
7196
|
*/
|
|
7047
7197
|
this.publish = async (options) => {
|
|
7198
|
+
this._assertLoaded('publish');
|
|
7048
7199
|
const { assertItemOwned } = await Promise.resolve().then(function () { return ownership; });
|
|
7049
7200
|
const { getPublishExecutor, PUBLISH_NOT_CONFIGURED_MESSAGE } = await Promise.resolve().then(function () { return publishConfig; });
|
|
7050
7201
|
await assertItemOwned(this);
|
|
@@ -7085,14 +7236,14 @@ class Item {
|
|
|
7085
7236
|
};
|
|
7086
7237
|
this.getPublishUploads = async (options) => {
|
|
7087
7238
|
// Use dynamic import to break circular dependency
|
|
7088
|
-
const _mod_19 = await import('./getPublishUploads-
|
|
7089
|
-
const _ns_19 = _mod_19.
|
|
7239
|
+
const _mod_19 = await import('./getPublishUploads-BdZmYCo2.js');
|
|
7240
|
+
const _ns_19 = _mod_19.q;
|
|
7090
7241
|
const getPublishUploadsMod = _ns_19;
|
|
7091
7242
|
const { getPublishUploads } = getPublishUploadsMod;
|
|
7092
7243
|
return await getPublishUploads(this, options);
|
|
7093
7244
|
};
|
|
7094
7245
|
this.getPublishPayload = async (uploadedTransactions, options) => {
|
|
7095
|
-
const _mod_20 = await import('./getPublishPayload-
|
|
7246
|
+
const _mod_20 = await import('./getPublishPayload-yidQCgY_.js');
|
|
7096
7247
|
const _ns_20 = _mod_20.c;
|
|
7097
7248
|
const getPublishPayloadMod = _ns_20;
|
|
7098
7249
|
const { getPublishPayload } = getPublishPayloadMod;
|
|
@@ -7241,13 +7392,13 @@ class Item {
|
|
|
7241
7392
|
* Cache a new item under its ids and keep its keys in step with them (a seed uid arrives on
|
|
7242
7393
|
* publish, moves on republish), then start its load.
|
|
7243
7394
|
*/
|
|
7244
|
-
static cacheAndLoad(instance) {
|
|
7395
|
+
static cacheAndLoad(instance, hold = true) {
|
|
7245
7396
|
const keys = () => {
|
|
7246
7397
|
const { seedLocalId, seedUid } = instance._getSnapshotContext();
|
|
7247
7398
|
return [seedLocalId, seedUid];
|
|
7248
7399
|
};
|
|
7249
7400
|
let current = keys().join('\u0000');
|
|
7250
|
-
this.cache.add(instance, keys(), { hold
|
|
7401
|
+
this.cache.add(instance, keys(), { hold });
|
|
7251
7402
|
const idWatch = instance._service.subscribe(() => {
|
|
7252
7403
|
const next = keys();
|
|
7253
7404
|
if (next.join('\u0000') === current || isEntityTornDown(instance))
|
|
@@ -7286,6 +7437,7 @@ class Item {
|
|
|
7286
7437
|
sendUpdate: (target, prop, value) => {
|
|
7287
7438
|
if (prop === 'publisher')
|
|
7288
7439
|
throw new Error('Cannot set item.publisher: publisher is read-only.');
|
|
7440
|
+
target._assertLoaded(`set ${prop} on`);
|
|
7289
7441
|
Item.sendTrackedPropertyUpdate(target, prop, value);
|
|
7290
7442
|
if (prop === 'seedUid' && typeof value === 'string' && value.length > 0) {
|
|
7291
7443
|
target._persistSeedUid(value);
|
|
@@ -7298,6 +7450,7 @@ class Item {
|
|
|
7298
7450
|
return {
|
|
7299
7451
|
get: () => property.value,
|
|
7300
7452
|
set: (value) => {
|
|
7453
|
+
target._assertLoaded(`set ${prop} on`);
|
|
7301
7454
|
property.value = value;
|
|
7302
7455
|
},
|
|
7303
7456
|
};
|
|
@@ -7313,6 +7466,15 @@ class Item {
|
|
|
7313
7466
|
reactiveProxies.set(instance._service, proxy);
|
|
7314
7467
|
return proxy;
|
|
7315
7468
|
}
|
|
7469
|
+
/** Throws EntityUnloadedError, naming the item, when this instance was unloaded. */
|
|
7470
|
+
_assertLoaded(action) {
|
|
7471
|
+
if (!isEntityTornDown(this))
|
|
7472
|
+
return;
|
|
7473
|
+
const { seedLocalId, seedUid, modelName } = this._getSnapshotContext();
|
|
7474
|
+
throw new EntityUnloadedError(`Cannot ${action} ${modelName ?? 'item'} ${seedLocalId ?? seedUid ?? '(no id)'}: this Item instance was ` +
|
|
7475
|
+
'unloaded. Look the item up again (Item.find), and hold it while you use it ' +
|
|
7476
|
+
'(Item.find({ hold: true }) or Item.retain, then unload()).');
|
|
7477
|
+
}
|
|
7316
7478
|
/**
|
|
7317
7479
|
* The ItemProperty a model property name reads and writes on the item: by its name, or by its
|
|
7318
7480
|
* storage name (`html` finds `htmlId` and the other way round). Internal names don't resolve.
|
|
@@ -7407,11 +7569,12 @@ class Item {
|
|
|
7407
7569
|
static async create(props, options) {
|
|
7408
7570
|
const waitForReady = options?.waitForReady !== false;
|
|
7409
7571
|
const readyTimeout = options?.readyTimeout ?? DEFAULT_READY_TIMEOUT_MS;
|
|
7572
|
+
const hold = options?.hold !== false;
|
|
7410
7573
|
if (!props.modelName && props.type) {
|
|
7411
7574
|
// The model the seed's type names (its easName, at the model's nameMatch level): `blog_post`
|
|
7412
7575
|
// finds "Blog Post". No match leaves the type, which then fails as an unknown model.
|
|
7413
|
-
const _mod_21 = await import('./tabEvents-
|
|
7414
|
-
const _ns_21 = _mod_21.
|
|
7576
|
+
const _mod_21 = await import('./tabEvents-BHPY5I08.js');
|
|
7577
|
+
const _ns_21 = _mod_21.bh;
|
|
7415
7578
|
const { resolveModelRecordByNameOrType } = _ns_21;
|
|
7416
7579
|
const model = await resolveModelRecordByNameOrType(props.type, {
|
|
7417
7580
|
modelFileId: props.modelFileId,
|
|
@@ -7423,7 +7586,10 @@ class Item {
|
|
|
7423
7586
|
// Local id first, so list rows (local + uid) resolve the same instance as early draft loads
|
|
7424
7587
|
const cached = this.cache.peek(props.seedLocalId) ?? this.cache.peek(props.seedUid);
|
|
7425
7588
|
if (cached) {
|
|
7426
|
-
|
|
7589
|
+
if (hold)
|
|
7590
|
+
this.cache.holdInstance(cached);
|
|
7591
|
+
else
|
|
7592
|
+
this.cache.keepUnheld(cached);
|
|
7427
7593
|
const propertyInstances = cached.getService().getSnapshot().context.propertyInstances;
|
|
7428
7594
|
for (const [propertyName, propertyValue] of Object.entries(props)) {
|
|
7429
7595
|
propertyInstances?.get(propertyName)?.getService().send({ type: 'updateContext', propertyValue });
|
|
@@ -7434,7 +7600,8 @@ class Item {
|
|
|
7434
7600
|
await waitForEntityReady(cached, { timeout: readyTimeout });
|
|
7435
7601
|
}
|
|
7436
7602
|
catch (err) {
|
|
7437
|
-
|
|
7603
|
+
if (hold)
|
|
7604
|
+
cached.unload();
|
|
7438
7605
|
throw err;
|
|
7439
7606
|
}
|
|
7440
7607
|
return cached;
|
|
@@ -7443,14 +7610,15 @@ class Item {
|
|
|
7443
7610
|
// Exclude latestVersionUid from props as it has incompatible types (string vs VersionsType)
|
|
7444
7611
|
const { latestVersionUid: _latestVersionUid, ...propsWithoutVersionUid } = props;
|
|
7445
7612
|
const proxiedInstance = Item.wrapInProxy(new Item({ ...propsWithoutVersionUid }));
|
|
7446
|
-
this.cacheAndLoad(proxiedInstance);
|
|
7613
|
+
this.cacheAndLoad(proxiedInstance, hold);
|
|
7447
7614
|
if (!waitForReady)
|
|
7448
7615
|
return proxiedInstance;
|
|
7449
7616
|
try {
|
|
7450
7617
|
await waitForEntityReady(proxiedInstance, { timeout: readyTimeout });
|
|
7451
7618
|
}
|
|
7452
7619
|
catch (err) {
|
|
7453
|
-
|
|
7620
|
+
if (hold)
|
|
7621
|
+
proxiedInstance.unload();
|
|
7454
7622
|
throw err;
|
|
7455
7623
|
}
|
|
7456
7624
|
return proxiedInstance;
|
|
@@ -7469,8 +7637,8 @@ class Item {
|
|
|
7469
7637
|
const db = BaseDb.getAppDb();
|
|
7470
7638
|
if (db && props.modelName) {
|
|
7471
7639
|
// Model names are only unique per schema: resolve the exact models row from the most specific scope.
|
|
7472
|
-
const _mod_22 = await import('./tabEvents-
|
|
7473
|
-
const _ns_22 = _mod_22.
|
|
7640
|
+
const _mod_22 = await import('./tabEvents-BHPY5I08.js');
|
|
7641
|
+
const _ns_22 = _mod_22.bh;
|
|
7474
7642
|
const { resolveModelRecord } = _ns_22;
|
|
7475
7643
|
const modelRecord = await resolveModelRecord(props.modelName, {
|
|
7476
7644
|
modelFileId: props.modelFileId ?? modelInstance?.id,
|
|
@@ -7478,7 +7646,7 @@ class Item {
|
|
|
7478
7646
|
});
|
|
7479
7647
|
const modelRecords = modelRecord ? [modelRecord] : [];
|
|
7480
7648
|
if (!modelRecord) {
|
|
7481
|
-
const _mod_23 = await import('./errors-
|
|
7649
|
+
const _mod_23 = await import('./errors-DpC9W4i3.js');
|
|
7482
7650
|
const _ns_23 = _mod_23.a8;
|
|
7483
7651
|
const { UnknownModelError } = _ns_23;
|
|
7484
7652
|
throw new UnknownModelError(props.modelName, schemaName ?? modelInstance?.schemaName);
|
|
@@ -7489,8 +7657,8 @@ class Item {
|
|
|
7489
7657
|
// Scope the constructor's Model lookup to this model's schema (as getItemData does on reload),
|
|
7490
7658
|
// so a same-named model cached from another schema can't supply the property set.
|
|
7491
7659
|
if (modelRecord && !props.schemaName) {
|
|
7492
|
-
const _mod_24 = await import('./tabEvents-
|
|
7493
|
-
const _ns_24 = _mod_24.
|
|
7660
|
+
const _mod_24 = await import('./tabEvents-BHPY5I08.js');
|
|
7661
|
+
const _ns_24 = _mod_24.bh;
|
|
7494
7662
|
const { getModelSchemaName } = _ns_24;
|
|
7495
7663
|
const modelSchemaName = await getModelSchemaName(modelRecord.id, db);
|
|
7496
7664
|
if (modelSchemaName) {
|
|
@@ -7560,10 +7728,16 @@ class Item {
|
|
|
7560
7728
|
const propsWithModel = { ...propsWithoutVersionUid };
|
|
7561
7729
|
const newInstance = new Item(propsWithModel);
|
|
7562
7730
|
const proxiedInstance = Item.wrapInProxy(newInstance);
|
|
7731
|
+
// Held while create saves its values; `hold: false` gives the hold back as it returns
|
|
7563
7732
|
this.cacheAndLoad(proxiedInstance);
|
|
7733
|
+
const created = () => {
|
|
7734
|
+
if (!hold)
|
|
7735
|
+
this.cache.release(proxiedInstance);
|
|
7736
|
+
return proxiedInstance;
|
|
7737
|
+
};
|
|
7564
7738
|
// Storage values must be saved before returning, so wait for readiness even when not requested.
|
|
7565
7739
|
if (!waitForReady && pipelineValues.length === 0)
|
|
7566
|
-
return
|
|
7740
|
+
return created();
|
|
7567
7741
|
try {
|
|
7568
7742
|
await waitForEntityReady(proxiedInstance, { timeout: readyTimeout });
|
|
7569
7743
|
await this.savePipelineValues(proxiedInstance, pipelineValues, readyTimeout);
|
|
@@ -7573,7 +7747,7 @@ class Item {
|
|
|
7573
7747
|
await this.discardCreatedItem(proxiedInstance, seedLocalId);
|
|
7574
7748
|
throw err;
|
|
7575
7749
|
}
|
|
7576
|
-
return
|
|
7750
|
+
return created();
|
|
7577
7751
|
}
|
|
7578
7752
|
/**
|
|
7579
7753
|
* Stops a just-created item and deletes what create wrote: a `discard` outbox op (ADR 0019),
|
|
@@ -7588,7 +7762,7 @@ class Item {
|
|
|
7588
7762
|
/* best-effort cache cleanup */
|
|
7589
7763
|
}
|
|
7590
7764
|
try {
|
|
7591
|
-
const { appendOutboxOpAndWait, deleteFiles, startItemOutbox } = await import('./index-
|
|
7765
|
+
const { appendOutboxOpAndWait, deleteFiles, startItemOutbox } = await import('./index-BMHqJ4kN.js');
|
|
7592
7766
|
startItemOutbox();
|
|
7593
7767
|
const applied = await appendOutboxOpAndWait({
|
|
7594
7768
|
seedLocalId,
|
|
@@ -7611,7 +7785,7 @@ class Item {
|
|
|
7611
7785
|
for (const [propertyName, value] of pipelineValues) {
|
|
7612
7786
|
const property = await this.waitForPropertyInstance(item, propertyName, timeout);
|
|
7613
7787
|
if (!property) {
|
|
7614
|
-
const _mod_25 = await import('./errors-
|
|
7788
|
+
const _mod_25 = await import('./errors-DpC9W4i3.js');
|
|
7615
7789
|
const _ns_25 = _mod_25.a8;
|
|
7616
7790
|
const { ItemCreateError } = _ns_25;
|
|
7617
7791
|
throw new ItemCreateError(`Item.create: property ${item.modelName}.${propertyName} did not load for item ${item.seedLocalId}; value was not saved`, { code: 'property_not_loaded', modelName: item.modelName, property: propertyName, seedLocalId: item.seedLocalId });
|
|
@@ -7623,14 +7797,14 @@ class Item {
|
|
|
7623
7797
|
}
|
|
7624
7798
|
catch (error) {
|
|
7625
7799
|
if (error instanceof ItemPropertySaveValidationError) {
|
|
7626
|
-
const _mod_26 = await import('./errors-
|
|
7800
|
+
const _mod_26 = await import('./errors-DpC9W4i3.js');
|
|
7627
7801
|
const _ns_26 = _mod_26.a8;
|
|
7628
7802
|
const { ItemCreateValidationError } = _ns_26;
|
|
7629
7803
|
const created = new ItemCreateValidationError(item.modelName, error.validationErrors.map((e) => ({ property: propertyName, code: e.code, message: e.message })));
|
|
7630
7804
|
created.cause = error;
|
|
7631
7805
|
throw created;
|
|
7632
7806
|
}
|
|
7633
|
-
const _mod_27 = await import('./errors-
|
|
7807
|
+
const _mod_27 = await import('./errors-DpC9W4i3.js');
|
|
7634
7808
|
const _ns_27 = _mod_27.a8;
|
|
7635
7809
|
const { ItemCreateError } = _ns_27;
|
|
7636
7810
|
throw new ItemCreateError(`Item.create: failed to save ${item.modelName}.${propertyName} for item ${item.seedLocalId}: ` +
|
|
@@ -7715,7 +7889,15 @@ class Item {
|
|
|
7715
7889
|
modelName,
|
|
7716
7890
|
}));
|
|
7717
7891
|
}
|
|
7718
|
-
|
|
7892
|
+
/**
|
|
7893
|
+
* The Item for a seedLocalId or seedUid, loaded from its rows when it isn't cached. Takes no
|
|
7894
|
+
* cache hold: an item no one holds stays cached for the grace period
|
|
7895
|
+
* (`SeedConfig.entityCache.unloadGraceMs`) after this lookup, then unloads. A caller that keeps
|
|
7896
|
+
* the item longer passes `hold: true` and releases it with `unload()`, or holds it with
|
|
7897
|
+
* `Item.retain` (React hooks do). Returns undefined, keeping no hold, when there is no such item
|
|
7898
|
+
* or it isn't ready in `readyTimeout`.
|
|
7899
|
+
*/
|
|
7900
|
+
static async find({ modelName, seedLocalId, seedUid, waitForReady = true, readyTimeout = DEFAULT_READY_TIMEOUT_MS, hold = false, }) {
|
|
7719
7901
|
if (!seedLocalId && !seedUid) {
|
|
7720
7902
|
return undefined;
|
|
7721
7903
|
}
|
|
@@ -7725,11 +7907,22 @@ class Item {
|
|
|
7725
7907
|
return undefined;
|
|
7726
7908
|
}
|
|
7727
7909
|
let cached = false;
|
|
7910
|
+
let held;
|
|
7728
7911
|
try {
|
|
7729
7912
|
return await timedDb(`find ${modelName ?? '?'} ${id}`, async () => {
|
|
7730
|
-
const
|
|
7731
|
-
|
|
7732
|
-
|
|
7913
|
+
const fromCache = hold ? (Item.getById(id) ?? undefined) : Item.peek(id);
|
|
7914
|
+
if (fromCache && !hold)
|
|
7915
|
+
Item.cache.keepUnheld(fromCache);
|
|
7916
|
+
cached = fromCache !== undefined;
|
|
7917
|
+
let item = fromCache;
|
|
7918
|
+
if (!item) {
|
|
7919
|
+
item = await Item.createById(id, modelName, seedLocalId ? 'localId' : undefined);
|
|
7920
|
+
// createById holds what it returns; without one the item waits out the grace period
|
|
7921
|
+
if (item && !hold)
|
|
7922
|
+
Item.cache.release(item);
|
|
7923
|
+
}
|
|
7924
|
+
if (hold)
|
|
7925
|
+
held = item;
|
|
7733
7926
|
if (item && waitForReady)
|
|
7734
7927
|
await waitForEntityReady(item, { timeout: readyTimeout });
|
|
7735
7928
|
return item;
|
|
@@ -7737,26 +7930,46 @@ class Item {
|
|
|
7737
7930
|
}
|
|
7738
7931
|
catch (error) {
|
|
7739
7932
|
timingLogger(`find ${modelName ?? '?'} ${id} returned undefined: ${error}`);
|
|
7933
|
+
held?.unload();
|
|
7740
7934
|
return undefined;
|
|
7741
7935
|
}
|
|
7742
7936
|
}
|
|
7937
|
+
/**
|
|
7938
|
+
* Takes one more hold on a cached, running instance, released with `unload()`. False (and no
|
|
7939
|
+
* hold) when the instance isn't cached or was stopped.
|
|
7940
|
+
*/
|
|
7941
|
+
static retain(instance) {
|
|
7942
|
+
const item = instance;
|
|
7943
|
+
return item.getService().getSnapshot().status === 'active' && this.cache.holdInstance(item);
|
|
7944
|
+
}
|
|
7945
|
+
/**
|
|
7946
|
+
* The items of a model (every model when `modelName` is omitted), newest first. Takes no cache
|
|
7947
|
+
* holds, as `find`: an item no one holds unloads after the grace period. With `hold: true` each
|
|
7948
|
+
* item comes with a hold the caller releases with `unload()`; when the call then throws (aborted,
|
|
7949
|
+
* an item not ready in `readyTimeout`), it keeps none of the holds it took.
|
|
7950
|
+
*/
|
|
7743
7951
|
static async all(modelName, deleted, options) {
|
|
7744
|
-
const { waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, includeEas = false, addressFilter, modelFileId, schemaName, signal, } = options ?? {};
|
|
7952
|
+
const { hold = false, waitForReady = false, readyTimeout = DEFAULT_READY_TIMEOUT_MS, includeEas = false, addressFilter, modelFileId, schemaName, signal, } = options ?? {};
|
|
7745
7953
|
signal?.throwIfAborted();
|
|
7746
7954
|
const itemsData = await getItemsData({ modelName, modelFileId, schemaName, deleted, includeEas, addressFilter });
|
|
7747
7955
|
const itemInstances = [];
|
|
7748
|
-
|
|
7749
|
-
|
|
7956
|
+
try {
|
|
7957
|
+
// Built without waiting; with waitForReady the items are then awaited together, below.
|
|
7958
|
+
for (const itemData of itemsData) {
|
|
7959
|
+
signal?.throwIfAborted();
|
|
7960
|
+
itemInstances.push(await Item.create({ ...itemData, modelName }, { waitForReady: false, hold }));
|
|
7961
|
+
}
|
|
7962
|
+
if (waitForReady && itemInstances.length > 0) {
|
|
7963
|
+
await Promise.all(itemInstances.map((item) => waitForEntityReady(item, { timeout: readyTimeout })));
|
|
7964
|
+
}
|
|
7750
7965
|
signal?.throwIfAborted();
|
|
7751
|
-
itemInstances.push(await Item.create({
|
|
7752
|
-
...itemData,
|
|
7753
|
-
modelName,
|
|
7754
|
-
}, { waitForReady: false }));
|
|
7755
7966
|
}
|
|
7756
|
-
|
|
7757
|
-
|
|
7967
|
+
catch (error) {
|
|
7968
|
+
if (hold)
|
|
7969
|
+
for (const item of itemInstances)
|
|
7970
|
+
item.unload();
|
|
7971
|
+
throw error;
|
|
7758
7972
|
}
|
|
7759
|
-
signal?.throwIfAborted();
|
|
7760
7973
|
return orderBy(itemInstances, ['createdAt'], ['desc']);
|
|
7761
7974
|
}
|
|
7762
7975
|
/**
|
|
@@ -7769,7 +7982,7 @@ class Item {
|
|
|
7769
7982
|
if (!appDb || Item.cache.size === 0) {
|
|
7770
7983
|
return;
|
|
7771
7984
|
}
|
|
7772
|
-
const _mod_28 = await import('./index-
|
|
7985
|
+
const _mod_28 = await import('./index-BjWk0x4-.js');
|
|
7773
7986
|
const _ns_28 = _mod_28.s;
|
|
7774
7987
|
const { metadata } = _ns_28;
|
|
7775
7988
|
const { eq, and } = await import('drizzle-orm');
|
|
@@ -7881,11 +8094,11 @@ class Item {
|
|
|
7881
8094
|
}
|
|
7882
8095
|
/** Throws ItemCreateValidationError for unknown keys and values that break their property's rules. */
|
|
7883
8096
|
static async assertValidCreateValues(props, propertyNames, dataTypeByPropertyName, skipKeys) {
|
|
7884
|
-
const _mod_29 = await import('./errors-
|
|
8097
|
+
const _mod_29 = await import('./errors-DpC9W4i3.js');
|
|
7885
8098
|
const _ns_29 = _mod_29.a8;
|
|
7886
8099
|
const { ItemCreateValidationError } = _ns_29;
|
|
7887
|
-
const { getModelPropertyDefinitions, resolvePropertyKey } = await import('./property-
|
|
7888
|
-
const { SchemaValidationService } = await import('./SchemaValidationService-
|
|
8100
|
+
const { getModelPropertyDefinitions, resolvePropertyKey } = await import('./property-QjljUeb9.js');
|
|
8101
|
+
const { SchemaValidationService } = await import('./SchemaValidationService-C1xqJFxI.js');
|
|
7889
8102
|
const validationService = new SchemaValidationService();
|
|
7890
8103
|
const modelName = props.modelName;
|
|
7891
8104
|
const known = new Set(propertyNames);
|
|
@@ -8239,7 +8452,7 @@ class Item {
|
|
|
8239
8452
|
itemActor.send(event);
|
|
8240
8453
|
};
|
|
8241
8454
|
try {
|
|
8242
|
-
const _mod_30 = await import('./index-
|
|
8455
|
+
const _mod_30 = await import('./index-BjWk0x4-.js');
|
|
8243
8456
|
const _ns_30 = _mod_30.s;
|
|
8244
8457
|
const seedSchemaMod = _ns_30;
|
|
8245
8458
|
const { seeds, metadata } = seedSchemaMod;
|
|
@@ -8253,8 +8466,8 @@ class Item {
|
|
|
8253
8466
|
return;
|
|
8254
8467
|
}
|
|
8255
8468
|
// Query initial seed and version data
|
|
8256
|
-
const _mod_31 = await import('./tabEvents-
|
|
8257
|
-
const _ns_31 = _mod_31.
|
|
8469
|
+
const _mod_31 = await import('./tabEvents-BHPY5I08.js');
|
|
8470
|
+
const _ns_31 = _mod_31.bg;
|
|
8258
8471
|
const { findSeedRow } = _ns_31;
|
|
8259
8472
|
const seed = await findSeedRow({ localId: seedLocalId, uid: seedUid }, db);
|
|
8260
8473
|
if (!seed) {
|
|
@@ -8554,7 +8767,7 @@ class Item {
|
|
|
8554
8767
|
return;
|
|
8555
8768
|
}
|
|
8556
8769
|
// Through the outbox (ADR 0019): after the item's pending edits, not before them
|
|
8557
|
-
const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-
|
|
8770
|
+
const { appendOutboxOpAndWait, startItemOutbox, throwItemWriteError } = await import('./index-BMHqJ4kN.js');
|
|
8558
8771
|
startItemOutbox();
|
|
8559
8772
|
await appendOutboxOpAndWait({
|
|
8560
8773
|
seedLocalId: context.seedLocalId,
|
|
@@ -8581,5 +8794,5 @@ var Item$1 = /*#__PURE__*/Object.freeze({
|
|
|
8581
8794
|
Item: Item
|
|
8582
8795
|
});
|
|
8583
8796
|
|
|
8584
|
-
export { createReactiveProxy as $, getCorrectId as A, isItemOwned as B, ClearNotSupportedError as C, isPublishedSeedRef as D, propertyKeyFromStoredName as E, currentPropertyRows as F, metadataPropertyGroupKeys as G, compareMetadataRowsLatestFirst as H, Item as I, readMetadataPropertiesById as J, isPublishedMetadataRow as K, getLatestPublishedVersionRow as L, isVersionRevoked as M, readModelMetadataProperties as N, OUTBOX_DEFER_MS as O, metadataPropertyNameForms as P, currentPropertyRow as Q, getLatestVersionRow as R, parseListPropertyValueFromStorage as S, applyContextUpdate as T, isInternalUpdate as U, evictionLog as V, holdChild as W, isEntityTornDown as X, sameEntity as Y, DEFAULT_READY_TIMEOUT_MS as Z, waitForEntityReady as _, appendOutboxOpAndWait as a,
|
|
8585
|
-
//# sourceMappingURL=Item-
|
|
8797
|
+
export { createReactiveProxy as $, getCorrectId as A, isItemOwned as B, ClearNotSupportedError as C, isPublishedSeedRef as D, propertyKeyFromStoredName as E, currentPropertyRows as F, metadataPropertyGroupKeys as G, compareMetadataRowsLatestFirst as H, Item as I, readMetadataPropertiesById as J, isPublishedMetadataRow as K, getLatestPublishedVersionRow as L, isVersionRevoked as M, readModelMetadataProperties as N, OUTBOX_DEFER_MS as O, metadataPropertyNameForms as P, currentPropertyRow as Q, getLatestVersionRow as R, parseListPropertyValueFromStorage as S, applyContextUpdate as T, isInternalUpdate as U, evictionLog as V, holdChild as W, isEntityTornDown as X, sameEntity as Y, DEFAULT_READY_TIMEOUT_MS as Z, waitForEntityReady as _, appendOutboxOpAndWait as a, createSeed as a$, runEntityLoad as a0, evictEntities as a1, entityStatus as a2, releaseEntity as a3, destroyEntity as a4, EntityCache as a5, getGetAdditionalSyncAddresses as a6, modelPropertiesToObject as a7, listRelationEasPropertyName as a8, easPropertyNameForPublish as a9, getPublishExecutor as aA, getRevokeExecutor as aB, getUploadExecutor as aC, getVersionData as aD, isLocalUnsealedDraft as aE, isSeedRowOwned as aF, localUnsealedDraftSql as aG, ownedPublisherSql as aH, ownedSeedsSql as aI, pickLatestMetadataRowPerProperty as aJ, placeholderUidSql as aK, propertyMachine as aL, publisherInAddressListSql as aM, publisherIsInOwnedSet as aN, setAdditionalSyncAddresses as aO, setGetPublisherForNewSeeds as aP, setPublishExecutor as aQ, setRevokeExecutor as aR, setUploadExecutor as aS, getSeedPublisher as aT, deleteStagedFile as aU, storageFileName as aV, STORAGE_SUBDIR as aW, resolveNewSeedFields as aX, lookupPropertySchemaUid as aY, stageStorageContent as aZ, requireStagedFile as a_, metadataStorageName as aa, resolveMetadataPropertyId as ab, storageSeedTransactionId as ac, storageUploadPath as ad, matchMetadataProperty as ae, metadataRowsOfProperty as af, METADATA_LATEST_FIRST_ORDER_SQL as ag, getEasSchemaUidForModel as ah, isStorageSeedRef as ai, isActorStopped as aj, differsFromOriginals as ak, onEntityTeardown as al, getStorageTransactionIdForSeedUid as am, latestVersionOrder as an, otherVersionRowsWithUid as ao, mergeVersionRowInto as ap, findMetadataPropertyByName as aq, storedValueKind as ar, resolveStorageDisplay as as, resolvePublisherFromSeedRow as at, EntityUnloadedError as au, PUBLISH_NOT_CONFIGURED_MESSAGE as av, createNewItem as aw, getArweaveUrlForTransaction as ax, getGetPublisherForNewSeeds as ay, getMetadataLatest as az, waitForPendingOutboxOps as b, createMetadata as b0, storageValueRowOf as b1, findSetConflict as b2, recordPropertyEdit as b3, setEntityUnloadGraceMs as b4, stopOutbox as b5, evictAllEntities as b6, currentPropertyRow$1 as b7, resolve as b8, conflicts as b9, propertySchemaUid as ba, Item$1 as bb, OUTBOX_MAX_ATTEMPTS as c, OUTBOX_PRUNE_AFTER_MS as d, OUTBOX_PRUNE_FAILED_AFTER_MS as e, OUTBOX_RETRY_DELAYS_MS as f, getOutboxOps as g, OutboxOpDeferredError as h, OutboxOpFailedError as i, OutboxOpRejectedError as j, appendOutboxOp as k, drainOutbox as l, markPropertyConflictsResolved as m, getItemConflicts as n, outboxOpResult as o, getPendingSetValue as p, getPropertyConflict as q, outboxOpValue as r, pruneOutbox as s, registerOutboxApplier as t, startOutbox as u, ItemProperty as v, waitForOutboxOp as w, ItemPropertySaveValidationError as x, OwnershipError as y, assertItemOwned as z };
|
|
8798
|
+
//# sourceMappingURL=Item-CXLcIHsi.js.map
|