@party-stack/foundry-ontology 0.18.1 → 0.19.0
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 +19 -0
- package/lib/adapter/foundryCodec.d.ts +1 -0
- package/lib/adapter/objectCollectionOptions.d.ts +2 -0
- package/lib/adapter/objectCollectionOptions.d.ts.map +1 -1
- package/lib/adapter/objectCollectionOptions.js +62 -28
- package/lib/adapter/objectCollectionOptions.js.map +1 -1
- package/lib/installation/index.js +1 -2
- package/lib/meta/entityCollectionOptions.d.ts +1 -0
- package/lib/meta/loadActionTypeOmsMetadata.d.ts +1 -0
- package/lib/users/userCollectionOptions.d.ts +1 -0
- package/package.json +11 -11
package/README.md
CHANGED
|
@@ -44,3 +44,22 @@ are used when public metadata does not provide them. Open string one-of values
|
|
|
44
44
|
are preserved as suggestions. Object-query and struct-field prefills are omitted
|
|
45
45
|
until the expression model supports them, and failures from the private endpoint
|
|
46
46
|
do not prevent public action metadata from loading.
|
|
47
|
+
|
|
48
|
+
## Refreshing objects
|
|
49
|
+
|
|
50
|
+
Foundry object collections expose an awaitable full-source refresh:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
await ontology.objects.Employee.utils.refresh?.();
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`refresh` is an optional adapter utility on the generic ontology collection API.
|
|
57
|
+
Foundry fetches a fresh snapshot and replaces cached rows in one sync transaction,
|
|
58
|
+
while keeping live subscriptions active and applying updates received during the
|
|
59
|
+
fetch. The promise waits for the commit and rejects on failure. Ontology
|
|
60
|
+
collections start their sync before refreshing; when using
|
|
61
|
+
`objectCollectionOptions` directly, preload the collection first.
|
|
62
|
+
|
|
63
|
+
When edit history is unavailable, reconnection and action acknowledgement also
|
|
64
|
+
request a fresh snapshot. Acknowledgement waits for that snapshot's commit; it
|
|
65
|
+
cannot confirm a specific edit-history operation ID in this mode.
|
|
@@ -7,6 +7,7 @@ interface OntologyObject extends OntologyObjectV2 {
|
|
|
7
7
|
__primaryKey: string | number;
|
|
8
8
|
}
|
|
9
9
|
export interface ObjectCollectionUtils extends UtilsRecord {
|
|
10
|
+
refresh: () => Promise<void>;
|
|
10
11
|
awaitOperationId: (operationId: string, timeout?: number) => Promise<void>;
|
|
11
12
|
}
|
|
12
13
|
export interface ObjectCollectionOpts {
|
|
@@ -28,4 +29,5 @@ export declare function objectCollectionOptions(config: ObjectCollectionOpts): {
|
|
|
28
29
|
utils: ObjectCollectionUtils;
|
|
29
30
|
};
|
|
30
31
|
//#endregion
|
|
32
|
+
export {};
|
|
31
33
|
//# sourceMappingURL=objectCollectionOptions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectCollectionOptions.d.ts","names":[],"sources":["../../src/adapter/objectCollectionOptions.ts"],"mappings":";;;;KAgCK,aAAa,GAAG,gBAAgB,KAAK,OAAO,KAAK,MAAM,EAAE;UAEpD,uBAAuB;EAC7B;;iBAqBa,8BAA8B;EAC3C,mBAAmB,qBAAqB,qBAAqB;;
|
|
1
|
+
{"version":3,"file":"objectCollectionOptions.d.ts","names":[],"sources":["../../src/adapter/objectCollectionOptions.ts"],"mappings":";;;;KAgCK,aAAa,GAAG,gBAAgB,KAAK,OAAO,KAAK,MAAM,EAAE;UAEpD,uBAAuB;EAC7B;;iBAqBa,8BAA8B;EAC3C,eAAe;EACf,mBAAmB,qBAAqB,qBAAqB;;iBAutBhD;EACb,QAAQ;EACR;EACA;EACA;EACA;EACA,gBAAgB,QAAQ,4BAA4B;EACpD,oBAAoB,QAAQ,4BAA4B;;iBAG3C,uBAAuB,gBAAgB,eAAe,yBAE/D,sBACA,KACI,iBAAiB,kBAAkB,2BAA2B;EAGtE,QAAQ;;wBAOI,wBAAwB,gBAAgB,eAAe,iBACnE,QAAQ,uBAAuB,WAChC,aACC,iBAAiB,kBAAkB,2BAA2B,SAAS;wBAG3D,wBAAwB,QAAQ;EAC5C;EACA,MAAM,WAAW;EACjB,OAAO"}
|
|
@@ -124,22 +124,31 @@ async function fetchFoundryObjects(client, objectType, selectedProperties, opts,
|
|
|
124
124
|
function createSyncConfig(client, objectType, primaryKeyProperty, selectedProperties, decodeObject = (object) => object, decodeEditObject = decodeObject, live = true) {
|
|
125
125
|
const seenOperationIds = new Store(/* @__PURE__ */ new Set());
|
|
126
126
|
const syncDisposed = new Store(false);
|
|
127
|
-
const
|
|
127
|
+
const fullSourceRefreshVersion = new Store(0);
|
|
128
128
|
let editHistoryUnavailable = false;
|
|
129
129
|
let requestFullRefresh;
|
|
130
|
+
const refresh = async () => {
|
|
131
|
+
if (!requestFullRefresh || syncDisposed.state) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
132
|
+
await requestFullRefresh();
|
|
133
|
+
};
|
|
134
|
+
const refreshInBackground = () => {
|
|
135
|
+
refresh().catch((error) => {
|
|
136
|
+
console.warn(`Failed full Foundry refresh for ${objectType}.`, error);
|
|
137
|
+
});
|
|
138
|
+
};
|
|
130
139
|
let requestEditHistoryCatchUp;
|
|
131
140
|
const awaitOperationId = async (operationId, timeout = COLLECTION_SYNC_TIMEOUT_MS) => {
|
|
132
141
|
if (typeof operationId !== "string" || operationId.length === 0) throw new Error("Foundry operationId must be a non-empty string.");
|
|
133
142
|
if (seenOperationIds.state.has(operationId)) return;
|
|
134
143
|
if (syncDisposed.state) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
135
144
|
if (!requestEditHistoryCatchUp) return;
|
|
136
|
-
const
|
|
137
|
-
|
|
145
|
+
const refreshVersionAtStart = fullSourceRefreshVersion.state;
|
|
146
|
+
const historyUnavailableAtStart = editHistoryUnavailable;
|
|
138
147
|
return new Promise((resolve, reject) => {
|
|
139
148
|
const cleanup = () => {
|
|
140
149
|
clearTimeout(timeoutId);
|
|
141
150
|
seenOperationIdsSubscription.unsubscribe();
|
|
142
|
-
|
|
151
|
+
fullSourceRefreshVersionSubscription.unsubscribe();
|
|
143
152
|
disposedSubscription.unsubscribe();
|
|
144
153
|
};
|
|
145
154
|
const timeoutId = setTimeout(() => {
|
|
@@ -152,8 +161,8 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
152
161
|
resolve();
|
|
153
162
|
}
|
|
154
163
|
});
|
|
155
|
-
const
|
|
156
|
-
if (editHistoryUnavailable &&
|
|
164
|
+
const fullSourceRefreshVersionSubscription = fullSourceRefreshVersion.subscribe(() => {
|
|
165
|
+
if (!historyUnavailableAtStart && editHistoryUnavailable && fullSourceRefreshVersion.state > refreshVersionAtStart) {
|
|
157
166
|
cleanup();
|
|
158
167
|
resolve();
|
|
159
168
|
}
|
|
@@ -164,6 +173,14 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
164
173
|
reject(new ObjectCollectionSyncAbortedError(objectType));
|
|
165
174
|
}
|
|
166
175
|
});
|
|
176
|
+
if (editHistoryUnavailable) refresh().then(() => {
|
|
177
|
+
cleanup();
|
|
178
|
+
resolve();
|
|
179
|
+
}, (error) => {
|
|
180
|
+
cleanup();
|
|
181
|
+
reject(error);
|
|
182
|
+
});
|
|
183
|
+
else requestEditHistoryCatchUp?.();
|
|
167
184
|
});
|
|
168
185
|
};
|
|
169
186
|
return {
|
|
@@ -223,10 +240,8 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
223
240
|
});
|
|
224
241
|
const applyDirectWatcherUpdates = async (updates) => {
|
|
225
242
|
const pendingMutations = /* @__PURE__ */ new Map();
|
|
226
|
-
let observedObjectUpdate = false;
|
|
227
243
|
for (const update of updates) {
|
|
228
244
|
if (update.type !== "object") continue;
|
|
229
|
-
observedObjectUpdate = true;
|
|
230
245
|
const object = update.object;
|
|
231
246
|
const primaryKey = getWatcherObjectKey(object);
|
|
232
247
|
switch (update.state) {
|
|
@@ -249,7 +264,6 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
249
264
|
else upsertObject(mutation.object);
|
|
250
265
|
}
|
|
251
266
|
const receipt = transactionStarted ? commit() : true;
|
|
252
|
-
if (observedObjectUpdate) directWebsocketSyncVersion.setState((version) => version + 1);
|
|
253
267
|
if (receipt !== true) await receipt;
|
|
254
268
|
};
|
|
255
269
|
const switchToDirectWebsocketMode = (error) => {
|
|
@@ -265,7 +279,7 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
265
279
|
console.warn(`Failed to apply direct Foundry updates for ${objectType}.`, applyError);
|
|
266
280
|
});
|
|
267
281
|
}
|
|
268
|
-
|
|
282
|
+
refreshInBackground();
|
|
269
283
|
};
|
|
270
284
|
const catchUpFromEditHistory = async () => {
|
|
271
285
|
const nextEditHistoryCursor = cloneEditHistoryCursor(editHistoryCursor);
|
|
@@ -322,7 +336,7 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
322
336
|
};
|
|
323
337
|
const refreshAllFromSource = async () => {
|
|
324
338
|
const objects = await fetchFoundryObjects(client, objectType, selectedProperties, {}, decodeObject);
|
|
325
|
-
if (disposed)
|
|
339
|
+
if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
326
340
|
begin();
|
|
327
341
|
truncate();
|
|
328
342
|
for (const object of objects) write({
|
|
@@ -330,34 +344,52 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
330
344
|
value: object
|
|
331
345
|
});
|
|
332
346
|
const receipt = commit();
|
|
333
|
-
if (
|
|
347
|
+
if (receipt !== true) await receipt;
|
|
348
|
+
if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
349
|
+
while (pendingDirectWatcherUpdates.length > 0 && !disposed) {
|
|
334
350
|
const updates = pendingDirectWatcherUpdates;
|
|
335
351
|
pendingDirectWatcherUpdates = [];
|
|
336
352
|
await applyDirectWatcherUpdates(updates);
|
|
337
353
|
}
|
|
338
|
-
|
|
339
|
-
|
|
354
|
+
if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
355
|
+
fullSourceRefreshVersion.setState((version) => version + 1);
|
|
340
356
|
};
|
|
341
357
|
requestFullRefresh = () => {
|
|
342
358
|
fullRefreshRequested = true;
|
|
343
|
-
if (fullRefreshTask) return;
|
|
359
|
+
if (fullRefreshTask) return fullRefreshTask;
|
|
360
|
+
const priorCatchUp = catchUpTask;
|
|
344
361
|
fullRefreshTask = (async () => {
|
|
362
|
+
if (priorCatchUp) await priorCatchUp;
|
|
363
|
+
if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);
|
|
345
364
|
while (fullRefreshRequested && !disposed) {
|
|
346
365
|
fullRefreshRequested = false;
|
|
347
366
|
await refreshAllFromSource();
|
|
348
367
|
}
|
|
349
|
-
})().catch((error) => {
|
|
350
|
-
|
|
368
|
+
})().catch(async (error) => {
|
|
369
|
+
while (pendingDirectWatcherUpdates.length > 0 && !disposed) {
|
|
370
|
+
const updates = pendingDirectWatcherUpdates;
|
|
371
|
+
pendingDirectWatcherUpdates = [];
|
|
372
|
+
try {
|
|
373
|
+
await applyDirectWatcherUpdates(updates);
|
|
374
|
+
} catch (applyError) {
|
|
375
|
+
console.warn(`Failed to apply queued Foundry updates for ${objectType}.`, applyError);
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
throw error;
|
|
351
380
|
}).finally(() => {
|
|
352
381
|
fullRefreshTask = void 0;
|
|
353
|
-
if (fullRefreshRequested && !disposed)
|
|
382
|
+
if (fullRefreshRequested && !disposed) refreshInBackground();
|
|
354
383
|
});
|
|
384
|
+
return fullRefreshTask;
|
|
355
385
|
};
|
|
356
386
|
requestEditHistoryCatchUp = () => {
|
|
357
387
|
if (editHistoryUnavailable) return;
|
|
358
388
|
catchUpRequested = true;
|
|
359
389
|
if (catchUpTask) return;
|
|
390
|
+
const priorRefresh = fullRefreshTask;
|
|
360
391
|
catchUpTask = (async () => {
|
|
392
|
+
if (priorRefresh) await priorRefresh;
|
|
361
393
|
while (catchUpRequested && !disposed) {
|
|
362
394
|
catchUpRequested = false;
|
|
363
395
|
await catchUpFromEditHistory();
|
|
@@ -385,24 +417,23 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
385
417
|
}, (message) => {
|
|
386
418
|
switch (message.type) {
|
|
387
419
|
case "change":
|
|
388
|
-
if (
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
} else {
|
|
420
|
+
if (fullRefreshTask) pendingDirectWatcherUpdates.push(...message.updates);
|
|
421
|
+
else if (editHistoryUnavailable) applyDirectWatcherUpdates(message.updates).catch((error) => {
|
|
422
|
+
console.warn(`Failed to apply direct Foundry updates for ${objectType}.`, error);
|
|
423
|
+
refreshInBackground();
|
|
424
|
+
});
|
|
425
|
+
else {
|
|
395
426
|
pendingDirectWatcherUpdates.push(...message.updates);
|
|
396
427
|
requestEditHistoryCatchUp?.();
|
|
397
428
|
}
|
|
398
429
|
break;
|
|
399
430
|
case "refresh":
|
|
400
|
-
if (editHistoryUnavailable)
|
|
431
|
+
if (editHistoryUnavailable) refreshInBackground();
|
|
401
432
|
else requestEditHistoryCatchUp?.();
|
|
402
433
|
break;
|
|
403
434
|
case "state":
|
|
404
435
|
if (message.status !== "open") break;
|
|
405
|
-
if (editHistoryUnavailable)
|
|
436
|
+
if (editHistoryUnavailable) refreshInBackground();
|
|
406
437
|
else requestEditHistoryCatchUp?.();
|
|
407
438
|
}
|
|
408
439
|
}) : () => {};
|
|
@@ -420,7 +451,10 @@ function createSyncConfig(client, objectType, primaryKeyProperty, selectedProper
|
|
|
420
451
|
}
|
|
421
452
|
};
|
|
422
453
|
} },
|
|
423
|
-
utils: {
|
|
454
|
+
utils: {
|
|
455
|
+
awaitOperationId,
|
|
456
|
+
refresh
|
|
457
|
+
}
|
|
424
458
|
};
|
|
425
459
|
}
|
|
426
460
|
function objectCollectionOptions(config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objectCollectionOptions.js","names":["AsyncIterable.toArray","AsyncIterable.fromPagination"],"sources":["../../src/adapter/objectCollectionOptions.ts"],"sourcesContent":["import {\n OntologyObjectsV2,\n OntologyObjectV2,\n type ObjectEditHistoryEntry,\n type ObjectSetUpdate,\n ObjectTypesV2,\n type ObjectPrimaryKeyV2,\n} from \"@osdk/foundry.ontologies\";\nimport { getObjectSetWatcherManager } from \"@party-stack/foundry-object-set-watcher\";\nimport {\n BasicIndex,\n CollectionConfig,\n DeduplicatedLoadSubset,\n InferSchemaOutput,\n LoadSubsetOptions,\n StandardSchema,\n SyncConfig,\n UtilsRecord,\n} from \"@tanstack/db\";\nimport { Store } from \"@tanstack/store\";\nimport * as AsyncIterable from \"../utils/AsyncIterable.js\";\nimport {\n convertLoadSubsetFilter,\n convertLoadSubsetOrderBy,\n isAlwaysFalseFilter,\n} from \"./convertLoadSubsetOptions.js\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\ninterface OntologyObject extends OntologyObjectV2 {\n __primaryKey: string | number;\n}\n\ntype FoundryObject = Record<string, unknown>;\n\nconst COLLECTION_SYNC_TIMEOUT_MS = 5_000;\n\nclass TimeoutWaitingForOperationIdError extends Error {\n constructor(operationId: string, objectType: string) {\n super(`Timed out waiting for Foundry operation ${operationId} to sync for ${objectType}.`);\n this.name = \"TimeoutWaitingForOperationIdError\";\n }\n}\n\nclass ObjectCollectionSyncAbortedError extends Error {\n constructor(objectType: string) {\n super(`Foundry sync for ${objectType} stopped before the operation was observed.`);\n this.name = \"ObjectCollectionSyncAbortedError\";\n }\n}\n\nexport interface ObjectCollectionUtils extends UtilsRecord {\n awaitOperationId: (operationId: string, timeout?: number) => Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Edit history helpers\n// ---------------------------------------------------------------------------\n\nconst EDIT_HISTORY_PAGE_SIZE = 1_000;\nconst EDIT_HISTORY_CURSOR_METADATA_KEY = \"foundry.editHistoryCursor\";\nconst EDIT_HISTORY_CURSOR_VERSION = 1;\n\ninterface EditHistoryCursor {\n timestamp: string;\n seenEntryKeysAtTimestamp: Set<string>;\n}\n\ninterface PersistedEditHistoryCursor {\n version: typeof EDIT_HISTORY_CURSOR_VERSION;\n timestamp: string;\n seenEntryKeysAtTimestamp: string[];\n}\n\nfunction createEditHistoryCursor(timestamp: string = new Date().toISOString()): EditHistoryCursor {\n return { timestamp, seenEntryKeysAtTimestamp: new Set() };\n}\n\nfunction cloneEditHistoryCursor(cursor: EditHistoryCursor): EditHistoryCursor {\n return {\n timestamp: cursor.timestamp,\n seenEntryKeysAtTimestamp: new Set(cursor.seenEntryKeysAtTimestamp),\n };\n}\n\nfunction serializeEditHistoryCursor(cursor: EditHistoryCursor): PersistedEditHistoryCursor {\n return {\n version: EDIT_HISTORY_CURSOR_VERSION,\n timestamp: cursor.timestamp,\n seenEntryKeysAtTimestamp: [...cursor.seenEntryKeysAtTimestamp].sort(),\n };\n}\n\nfunction deserializeEditHistoryCursor(value: unknown): EditHistoryCursor | undefined {\n if (\n !isPlainObject(value) ||\n value.version !== EDIT_HISTORY_CURSOR_VERSION ||\n typeof value.timestamp !== \"string\" ||\n !Array.isArray(value.seenEntryKeysAtTimestamp) ||\n !value.seenEntryKeysAtTimestamp.every((key) => typeof key === \"string\")\n ) {\n return undefined;\n }\n return {\n timestamp: value.timestamp,\n seenEntryKeysAtTimestamp: new Set(value.seenEntryKeysAtTimestamp),\n };\n}\n\nfunction editHistoryCursorsEqual(left: EditHistoryCursor, right: EditHistoryCursor): boolean {\n return (\n left.timestamp === right.timestamp &&\n left.seenEntryKeysAtTimestamp.size === right.seenEntryKeysAtTimestamp.size &&\n [...left.seenEntryKeysAtTimestamp].every((key) => right.seenEntryKeysAtTimestamp.has(key))\n );\n}\n\nfunction canonicalizeJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalizeJsonValue);\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, canonicalizeJsonValue(value[key])])\n );\n }\n return value;\n}\n\nfunction getEditHistoryEntryKey(entry: ObjectEditHistoryEntry): string {\n return JSON.stringify(\n canonicalizeJsonValue({\n objectPrimaryKey: entry.objectPrimaryKey,\n operationId: entry.operationId,\n timestamp: entry.timestamp,\n edit: entry.edit,\n })\n );\n}\n\nfunction shouldProcessEditHistoryEntry(cursor: EditHistoryCursor, entry: ObjectEditHistoryEntry): boolean {\n if (entry.timestamp < cursor.timestamp) return false;\n if (entry.timestamp === cursor.timestamp) {\n return !cursor.seenEntryKeysAtTimestamp.has(getEditHistoryEntryKey(entry));\n }\n return true;\n}\n\nfunction advanceEditHistoryCursor(cursor: EditHistoryCursor, entry: ObjectEditHistoryEntry): void {\n const entryKey = getEditHistoryEntryKey(entry);\n if (entry.timestamp > cursor.timestamp) {\n cursor.timestamp = entry.timestamp;\n cursor.seenEntryKeysAtTimestamp.clear();\n }\n cursor.seenEntryKeysAtTimestamp.add(entryKey);\n}\n\nfunction getPrimaryKeyValue(\n primaryKey: ObjectPrimaryKeyV2,\n primaryKeyProperty: string,\n decodeEditObject: (object: FoundryObject) => FoundryObject\n): string | number {\n const values = Object.values(primaryKey);\n if (values.length !== 1) {\n throw new Error(\"Foundry object collections currently only support single-field primary keys.\");\n }\n const value = decodeEditObject({\n [primaryKeyProperty]: values[0],\n })[primaryKeyProperty];\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new Error(\"Foundry object collections currently only support string or number primary keys.\");\n }\n return value;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n// ---------------------------------------------------------------------------\n// Foundry object fetching\n// ---------------------------------------------------------------------------\n\nasync function fetchFoundryObjects(\n client: OntologyClient,\n objectType: string,\n selectedProperties: string[],\n opts: LoadSubsetOptions,\n decodeObject: (object: FoundryObject) => FoundryObject = (object) => object\n): Promise<FoundryObject[]> {\n opts.signal?.throwIfAborted();\n const offset = Math.max(0, Math.trunc(opts.offset ?? 0));\n const limit = opts.limit === undefined ? undefined : Math.max(0, Math.trunc(opts.limit));\n if (limit === 0) return [];\n\n let where = convertLoadSubsetFilter(opts.where);\n if (isAlwaysFalseFilter(where) || (where?.type === \"in\" && where.value.length === 0)) {\n return [];\n }\n\n if (opts.cursor?.whereFrom) {\n const cursorWhere = convertLoadSubsetFilter(opts.cursor.whereFrom);\n if (isAlwaysFalseFilter(cursorWhere)) {\n return [];\n }\n if (cursorWhere) {\n where = where ? { type: \"and\", value: [where, cursorWhere] } : cursorWhere;\n }\n }\n\n const requestClient = opts.signal\n ? {\n ...client,\n fetch: (input: RequestInfo | URL, init?: RequestInit) =>\n client.fetch(input, {\n ...init,\n signal: opts.signal,\n }),\n }\n : client;\n const results = await AsyncIterable.toArray(\n AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n OntologyObjectsV2.search(requestClient, client.ontologyRid, objectType, {\n snapshot: true,\n where,\n excludeRid: true,\n select: selectedProperties,\n selectV2: [],\n pageSize,\n pageToken,\n orderBy: convertLoadSubsetOrderBy(opts.orderBy),\n }),\n (page) => page.nextPageToken,\n (page) => page.data,\n 10_000,\n limit === undefined ? undefined : offset + limit\n )\n );\n opts.signal?.throwIfAborted();\n\n return (results as FoundryObject[])\n .slice(offset, limit === undefined ? undefined : offset + limit)\n .map(decodeObject);\n}\n\nfunction createSyncConfig(\n client: OntologyClient,\n objectType: string,\n primaryKeyProperty: string,\n selectedProperties: string[],\n decodeObject: (object: FoundryObject) => FoundryObject = (object) => object,\n decodeEditObject: (object: FoundryObject) => FoundryObject = decodeObject,\n live: boolean = true\n): { sync: SyncConfig<Record<string, unknown>, string | number>; utils: ObjectCollectionUtils } {\n const seenOperationIds = new Store<Set<string>>(new Set<string>());\n const syncDisposed = new Store(false);\n const directWebsocketSyncVersion = new Store(0);\n let editHistoryUnavailable = false;\n let requestFullRefresh: (() => void) | undefined;\n let requestEditHistoryCatchUp: (() => void) | undefined;\n\n const awaitOperationId = async (\n operationId: string,\n timeout: number = COLLECTION_SYNC_TIMEOUT_MS\n ): Promise<void> => {\n if (typeof operationId !== \"string\" || operationId.length === 0) {\n throw new Error(\"Foundry operationId must be a non-empty string.\");\n }\n\n if (seenOperationIds.state.has(operationId)) {\n return;\n }\n\n if (syncDisposed.state) {\n throw new ObjectCollectionSyncAbortedError(objectType);\n }\n\n if (!requestEditHistoryCatchUp) {\n // An on-demand collection has no local state to confirm until its sync starts.\n // TODO: Track sync activity and edit-history availability separately. If sync is\n // active but edit-history catch-up is unavailable, request and await a full refresh.\n return;\n }\n\n const directSyncVersionAtStart = directWebsocketSyncVersion.state;\n requestEditHistoryCatchUp();\n\n return new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n clearTimeout(timeoutId);\n seenOperationIdsSubscription.unsubscribe();\n directWebsocketSyncVersionSubscription.unsubscribe();\n disposedSubscription.unsubscribe();\n };\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(new TimeoutWaitingForOperationIdError(operationId, objectType));\n }, timeout);\n const seenOperationIdsSubscription = seenOperationIds.subscribe(() => {\n if (seenOperationIds.state.has(operationId)) {\n cleanup();\n resolve();\n }\n });\n const directWebsocketSyncVersionSubscription = directWebsocketSyncVersion.subscribe(() => {\n if (editHistoryUnavailable && directWebsocketSyncVersion.state > directSyncVersionAtStart) {\n cleanup();\n resolve();\n }\n });\n const disposedSubscription = syncDisposed.subscribe(() => {\n if (syncDisposed.state) {\n cleanup();\n reject(new ObjectCollectionSyncAbortedError(objectType));\n }\n });\n });\n };\n\n const utils: ObjectCollectionUtils = { awaitOperationId };\n\n const sync: SyncConfig<Record<string, unknown>, string | number> = {\n sync: (params) => {\n const { begin, write, commit, markError, markReady, truncate } = params;\n const collectionMetadata = params.metadata?.collection;\n\n syncDisposed.setState(() => false);\n\n let disposed = false;\n const restoredEditHistoryCursor = deserializeEditHistoryCursor(\n collectionMetadata?.get(EDIT_HISTORY_CURSOR_METADATA_KEY)\n );\n let editHistoryCursor = restoredEditHistoryCursor ?? createEditHistoryCursor();\n let initialCommit: ReturnType<typeof commit> = true;\n if (!restoredEditHistoryCursor) {\n if (collectionMetadata) {\n begin();\n collectionMetadata.set(\n EDIT_HISTORY_CURSOR_METADATA_KEY,\n serializeEditHistoryCursor(editHistoryCursor)\n );\n initialCommit = commit();\n }\n }\n let catchUpRequested = false;\n let catchUpTask: Promise<void> | undefined;\n let pendingDirectWatcherUpdates: ObjectSetUpdate[] = [];\n let fullRefreshRequested = false;\n let fullRefreshTask: Promise<void> | undefined;\n\n const getObjectKey = (object: FoundryObject): string | number =>\n object[primaryKeyProperty] as string | number;\n\n const getWatcherObjectKey = (object: FoundryObject): string | number => {\n const key = object[primaryKeyProperty] ?? object.__primaryKey;\n if (typeof key !== \"string\" && typeof key !== \"number\") {\n throw new Error(\n `Foundry websocket update for ${objectType} did not include a supported primary key.`\n );\n }\n return key;\n };\n\n const upsertObject = (object: FoundryObject) => {\n const key = getObjectKey(object);\n const exists = params.collection.has(key);\n const existing = exists ? params.collection.get(key) : undefined;\n write({\n type: exists ? \"update\" : \"insert\",\n value: existing\n ? {\n ...existing,\n ...object,\n }\n : object,\n });\n };\n\n const deleteObjectByKey = (key: string | number): boolean => {\n write({ type: \"delete\", key });\n return true;\n };\n\n const fetchEditHistoryPage = (body: Parameters<typeof ObjectTypesV2.getEditsHistory>[3]) =>\n ObjectTypesV2.getEditsHistory(\n client,\n client.ontologyRid,\n objectType,\n body,\n // oxlint-disable-next-line typescript/no-unsafe-argument\n {\n preview: true,\n // oxlint-disable-next-line typescript/no-explicit-any\n } as unknown as any\n );\n\n const decodeEditProperties = (\n properties: Record<string, unknown>,\n primaryKey: string | number\n ): FoundryObject =>\n decodeEditObject({\n ...properties,\n [primaryKeyProperty]: primaryKey,\n });\n\n const decodeWatcherObject = (object: FoundryObject, primaryKey: string | number): FoundryObject =>\n decodeObject({\n ...object,\n [primaryKeyProperty]: primaryKey,\n });\n\n const applyDirectWatcherUpdates = async (updates: ObjectSetUpdate[]): Promise<void> => {\n const pendingMutations = new Map<\n string | number,\n { type: \"upsert\"; object: FoundryObject } | { type: \"delete\" }\n >();\n let observedObjectUpdate = false;\n\n for (const update of updates) {\n if (update.type !== \"object\") continue;\n\n observedObjectUpdate = true;\n const object = update.object;\n const primaryKey = getWatcherObjectKey(object);\n\n switch (update.state) {\n case \"ADDED_OR_UPDATED\":\n pendingMutations.set(primaryKey, {\n type: \"upsert\",\n object: decodeWatcherObject(object, primaryKey),\n });\n break;\n case \"REMOVED\":\n pendingMutations.set(primaryKey, { type: \"delete\" });\n break;\n }\n }\n\n let transactionStarted = false;\n for (const [primaryKey, mutation] of pendingMutations) {\n if (!transactionStarted) {\n begin();\n transactionStarted = true;\n }\n\n if (mutation.type === \"delete\") {\n deleteObjectByKey(primaryKey);\n } else {\n upsertObject(mutation.object);\n }\n }\n\n const receipt = transactionStarted ? commit() : true;\n\n if (observedObjectUpdate) {\n directWebsocketSyncVersion.setState((version) => version + 1);\n }\n\n if (receipt !== true) await receipt;\n };\n\n const switchToDirectWebsocketMode = (error: unknown): void => {\n if (!editHistoryUnavailable) {\n const errorMessage = error instanceof Error ? error.message : error;\n console.warn(\n `Edit history catch-up failed for ${objectType}; falling back to direct websocket updates.`,\n errorMessage\n );\n editHistoryUnavailable = true;\n }\n\n if (pendingDirectWatcherUpdates.length > 0) {\n const updates = pendingDirectWatcherUpdates;\n pendingDirectWatcherUpdates = [];\n void applyDirectWatcherUpdates(updates).catch((applyError: unknown) => {\n console.warn(`Failed to apply direct Foundry updates for ${objectType}.`, applyError);\n });\n }\n requestFullRefresh?.();\n };\n\n const catchUpFromEditHistory = async (): Promise<void> => {\n const nextEditHistoryCursor = cloneEditHistoryCursor(editHistoryCursor);\n const pendingMutations = new Map<\n string | number,\n { type: \"upsert\"; object: FoundryObject } | { type: \"delete\" }\n >();\n const newOperationIds = new Set<string>();\n\n for await (const entry of AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n fetchEditHistoryPage({\n filters: {\n type: \"timestampFilter\",\n startTime: nextEditHistoryCursor.timestamp,\n },\n includeAllPreviousProperties: true,\n pageSize,\n pageToken,\n sortOrder: \"oldest_first\",\n }),\n (page) => page.nextPageToken,\n (page) => page.data,\n EDIT_HISTORY_PAGE_SIZE\n )) {\n if (disposed) break;\n if (!shouldProcessEditHistoryEntry(nextEditHistoryCursor, entry)) continue;\n advanceEditHistoryCursor(nextEditHistoryCursor, entry);\n newOperationIds.add(entry.operationId);\n\n const primaryKey = getPrimaryKeyValue(\n entry.objectPrimaryKey,\n primaryKeyProperty,\n decodeEditObject\n );\n\n switch (entry.edit.type) {\n case \"createEdit\":\n case \"modifyEdit\":\n pendingMutations.set(primaryKey, {\n type: \"upsert\",\n object: decodeEditProperties(entry.edit.properties, primaryKey),\n });\n break;\n case \"deleteEdit\":\n pendingMutations.set(primaryKey, { type: \"delete\" });\n break;\n }\n }\n\n if (disposed) return;\n\n const checkpointChanged = !editHistoryCursorsEqual(editHistoryCursor, nextEditHistoryCursor);\n let transactionStarted = false;\n const ensureTransaction = () => {\n if (transactionStarted) return;\n begin();\n transactionStarted = true;\n };\n for (const [primaryKey, mutation] of pendingMutations) {\n ensureTransaction();\n\n if (mutation.type === \"delete\") {\n deleteObjectByKey(primaryKey);\n } else {\n upsertObject(mutation.object);\n }\n }\n\n if (checkpointChanged && collectionMetadata) {\n ensureTransaction();\n collectionMetadata.set(\n EDIT_HISTORY_CURSOR_METADATA_KEY,\n serializeEditHistoryCursor(nextEditHistoryCursor)\n );\n }\n\n const receipt = transactionStarted ? commit() : true;\n\n if (checkpointChanged) {\n editHistoryCursor = nextEditHistoryCursor;\n }\n\n if (newOperationIds.size > 0) {\n seenOperationIds.setState((current) => new Set([...current, ...newOperationIds]));\n }\n\n pendingDirectWatcherUpdates = [];\n\n if (receipt !== true) await receipt;\n };\n\n const refreshAllFromSource = async (): Promise<void> => {\n const objects = await fetchFoundryObjects(\n client,\n objectType,\n selectedProperties,\n {},\n decodeObject\n );\n if (disposed) return;\n\n begin();\n truncate();\n for (const object of objects) {\n write({\n type: \"insert\",\n value: object,\n });\n }\n const receipt = commit();\n\n if (pendingDirectWatcherUpdates.length > 0) {\n const updates = pendingDirectWatcherUpdates;\n pendingDirectWatcherUpdates = [];\n await applyDirectWatcherUpdates(updates);\n }\n directWebsocketSyncVersion.setState((version) => version + 1);\n\n if (receipt !== true) await receipt;\n };\n\n requestFullRefresh = () => {\n fullRefreshRequested = true;\n if (fullRefreshTask) return;\n\n fullRefreshTask = (async () => {\n while (fullRefreshRequested && !disposed) {\n fullRefreshRequested = false;\n await refreshAllFromSource();\n }\n })()\n .catch((error: unknown) => {\n console.warn(`Failed full Foundry refresh for ${objectType}.`, error);\n })\n .finally(() => {\n fullRefreshTask = undefined;\n if (fullRefreshRequested && !disposed) {\n requestFullRefresh?.();\n }\n });\n };\n\n requestEditHistoryCatchUp = () => {\n if (editHistoryUnavailable) {\n return;\n }\n\n catchUpRequested = true;\n if (catchUpTask) return;\n\n catchUpTask = (async () => {\n while (catchUpRequested && !disposed) {\n catchUpRequested = false;\n await catchUpFromEditHistory();\n }\n })()\n .catch((error: unknown) => {\n switchToDirectWebsocketMode(error);\n })\n .finally(() => {\n catchUpTask = undefined;\n if (catchUpRequested && !disposed) {\n requestEditHistoryCatchUp?.();\n }\n });\n };\n\n const loadSubset = async (opts: LoadSubsetOptions): Promise<void> => {\n const objects = await fetchFoundryObjects(\n client,\n objectType,\n selectedProperties,\n opts,\n decodeObject\n );\n if (objects.length > 0) {\n begin();\n for (const object of objects) {\n upsertObject(object);\n }\n const receipt = commit(opts.signal);\n if (receipt !== true) await receipt;\n }\n };\n\n const loadSubsetDedupe = new DeduplicatedLoadSubset({ loadSubset });\n const unsubscribe = live\n ? getObjectSetWatcherManager(client).subscribe({ type: \"base\", objectType }, (message) => {\n switch (message.type) {\n case \"change\": {\n if (editHistoryUnavailable) {\n if (fullRefreshTask) {\n pendingDirectWatcherUpdates.push(...message.updates);\n } else {\n void applyDirectWatcherUpdates(message.updates).catch(\n (error: unknown) => {\n console.warn(\n `Failed to apply direct Foundry updates for ${objectType}.`,\n error\n );\n requestFullRefresh?.();\n }\n );\n }\n } else {\n pendingDirectWatcherUpdates.push(...message.updates);\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n case \"refresh\": {\n if (editHistoryUnavailable) {\n requestFullRefresh?.();\n } else {\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n case \"state\": {\n if (message.status !== \"open\") break;\n if (editHistoryUnavailable) {\n requestFullRefresh?.();\n } else {\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n }\n })\n : () => {};\n\n // start task here, cleanup can stop it\n // in that task:\n // - spawn object set subscription, which sends messages to catch up\n // - actions sends messages to catch up\n\n if (initialCommit === true) {\n markReady();\n } else {\n void initialCommit.then(markReady, markError);\n }\n\n return {\n loadSubset: loadSubsetDedupe.loadSubset,\n cleanup: () => {\n disposed = true;\n requestEditHistoryCatchUp = undefined;\n requestFullRefresh = undefined;\n syncDisposed.setState(() => true);\n unsubscribe();\n loadSubsetDedupe.reset();\n },\n };\n },\n };\n\n return { sync, utils };\n}\n\n// ---------------------------------------------------------------------------\n// Collection option types\n// ---------------------------------------------------------------------------\n\nexport interface ObjectCollectionOpts {\n client: OntologyClient;\n objectType: string;\n primaryKeyProperty: string;\n selectedProperties: string[];\n live?: boolean;\n decodeObject?: (object: Record<string, unknown>) => Record<string, unknown>;\n decodeEditObject?: (object: Record<string, unknown>) => Record<string, unknown>;\n}\n\nexport interface ObjectCollectionConfig<TSchema extends StandardSchema<OntologyObject>>\n extends\n ObjectCollectionOpts,\n Omit<\n CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema>,\n \"sync\" | \"syncMode\" | \"getKey\" | \"onInsert\" | \"onUpdate\" | \"onDelete\"\n > {\n schema: TSchema;\n}\n\n// ---------------------------------------------------------------------------\n// Public collection options\n// ---------------------------------------------------------------------------\n\nexport function objectCollectionOptions<TSchema extends StandardSchema<OntologyObject>>(\n config: ObjectCollectionConfig<TSchema>\n): WithRequired<\n CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema, ObjectCollectionUtils>,\n \"schema\"\n>;\nexport function objectCollectionOptions(config: ObjectCollectionOpts): {\n syncMode: \"on-demand\";\n sync: SyncConfig<Record<string, unknown>, string | number>;\n utils: ObjectCollectionUtils;\n};\n// oxlint-disable-next-line typescript/no-explicit-any\nexport function objectCollectionOptions(config: any): any {\n const {\n client,\n objectType,\n primaryKeyProperty,\n selectedProperties,\n live,\n decodeObject,\n decodeEditObject,\n schema,\n ...rest\n } = config as ObjectCollectionOpts & { schema?: StandardSchema<OntologyObject> } & Record<\n string,\n unknown\n >;\n const { sync, utils } = createSyncConfig(\n client,\n objectType,\n primaryKeyProperty,\n selectedProperties,\n decodeObject,\n decodeEditObject,\n live\n );\n\n if (schema === undefined) {\n return { syncMode: \"on-demand\" as const, sync, utils };\n }\n\n return {\n ...rest,\n schema,\n defaultIndexType: BasicIndex,\n autoIndex: \"eager\",\n syncMode: \"on-demand\" as const,\n getKey: (object: Record<string, unknown>) =>\n (object as Record<string, string | number>)[primaryKeyProperty] as string | number,\n sync,\n utils,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"objectCollectionOptions.js","names":["AsyncIterable.toArray","AsyncIterable.fromPagination"],"sources":["../../src/adapter/objectCollectionOptions.ts"],"sourcesContent":["import {\n OntologyObjectsV2,\n OntologyObjectV2,\n type ObjectEditHistoryEntry,\n type ObjectSetUpdate,\n ObjectTypesV2,\n type ObjectPrimaryKeyV2,\n} from \"@osdk/foundry.ontologies\";\nimport { getObjectSetWatcherManager } from \"@party-stack/foundry-object-set-watcher\";\nimport {\n BasicIndex,\n CollectionConfig,\n DeduplicatedLoadSubset,\n InferSchemaOutput,\n LoadSubsetOptions,\n StandardSchema,\n SyncConfig,\n UtilsRecord,\n} from \"@tanstack/db\";\nimport { Store } from \"@tanstack/store\";\nimport * as AsyncIterable from \"../utils/AsyncIterable.js\";\nimport {\n convertLoadSubsetFilter,\n convertLoadSubsetOrderBy,\n isAlwaysFalseFilter,\n} from \"./convertLoadSubsetOptions.js\";\nimport type { OntologyClient } from \"@party-stack/foundry-client\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\ninterface OntologyObject extends OntologyObjectV2 {\n __primaryKey: string | number;\n}\n\ntype FoundryObject = Record<string, unknown>;\n\nconst COLLECTION_SYNC_TIMEOUT_MS = 5_000;\n\nclass TimeoutWaitingForOperationIdError extends Error {\n constructor(operationId: string, objectType: string) {\n super(`Timed out waiting for Foundry operation ${operationId} to sync for ${objectType}.`);\n this.name = \"TimeoutWaitingForOperationIdError\";\n }\n}\n\nclass ObjectCollectionSyncAbortedError extends Error {\n constructor(objectType: string) {\n super(`Foundry sync for ${objectType} stopped before the operation was observed.`);\n this.name = \"ObjectCollectionSyncAbortedError\";\n }\n}\n\nexport interface ObjectCollectionUtils extends UtilsRecord {\n refresh: () => Promise<void>;\n awaitOperationId: (operationId: string, timeout?: number) => Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Edit history helpers\n// ---------------------------------------------------------------------------\n\nconst EDIT_HISTORY_PAGE_SIZE = 1_000;\nconst EDIT_HISTORY_CURSOR_METADATA_KEY = \"foundry.editHistoryCursor\";\nconst EDIT_HISTORY_CURSOR_VERSION = 1;\n\ninterface EditHistoryCursor {\n timestamp: string;\n seenEntryKeysAtTimestamp: Set<string>;\n}\n\ninterface PersistedEditHistoryCursor {\n version: typeof EDIT_HISTORY_CURSOR_VERSION;\n timestamp: string;\n seenEntryKeysAtTimestamp: string[];\n}\n\nfunction createEditHistoryCursor(timestamp: string = new Date().toISOString()): EditHistoryCursor {\n return { timestamp, seenEntryKeysAtTimestamp: new Set() };\n}\n\nfunction cloneEditHistoryCursor(cursor: EditHistoryCursor): EditHistoryCursor {\n return {\n timestamp: cursor.timestamp,\n seenEntryKeysAtTimestamp: new Set(cursor.seenEntryKeysAtTimestamp),\n };\n}\n\nfunction serializeEditHistoryCursor(cursor: EditHistoryCursor): PersistedEditHistoryCursor {\n return {\n version: EDIT_HISTORY_CURSOR_VERSION,\n timestamp: cursor.timestamp,\n seenEntryKeysAtTimestamp: [...cursor.seenEntryKeysAtTimestamp].sort(),\n };\n}\n\nfunction deserializeEditHistoryCursor(value: unknown): EditHistoryCursor | undefined {\n if (\n !isPlainObject(value) ||\n value.version !== EDIT_HISTORY_CURSOR_VERSION ||\n typeof value.timestamp !== \"string\" ||\n !Array.isArray(value.seenEntryKeysAtTimestamp) ||\n !value.seenEntryKeysAtTimestamp.every((key) => typeof key === \"string\")\n ) {\n return undefined;\n }\n return {\n timestamp: value.timestamp,\n seenEntryKeysAtTimestamp: new Set(value.seenEntryKeysAtTimestamp),\n };\n}\n\nfunction editHistoryCursorsEqual(left: EditHistoryCursor, right: EditHistoryCursor): boolean {\n return (\n left.timestamp === right.timestamp &&\n left.seenEntryKeysAtTimestamp.size === right.seenEntryKeysAtTimestamp.size &&\n [...left.seenEntryKeysAtTimestamp].every((key) => right.seenEntryKeysAtTimestamp.has(key))\n );\n}\n\nfunction canonicalizeJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(canonicalizeJsonValue);\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, canonicalizeJsonValue(value[key])])\n );\n }\n return value;\n}\n\nfunction getEditHistoryEntryKey(entry: ObjectEditHistoryEntry): string {\n return JSON.stringify(\n canonicalizeJsonValue({\n objectPrimaryKey: entry.objectPrimaryKey,\n operationId: entry.operationId,\n timestamp: entry.timestamp,\n edit: entry.edit,\n })\n );\n}\n\nfunction shouldProcessEditHistoryEntry(cursor: EditHistoryCursor, entry: ObjectEditHistoryEntry): boolean {\n if (entry.timestamp < cursor.timestamp) return false;\n if (entry.timestamp === cursor.timestamp) {\n return !cursor.seenEntryKeysAtTimestamp.has(getEditHistoryEntryKey(entry));\n }\n return true;\n}\n\nfunction advanceEditHistoryCursor(cursor: EditHistoryCursor, entry: ObjectEditHistoryEntry): void {\n const entryKey = getEditHistoryEntryKey(entry);\n if (entry.timestamp > cursor.timestamp) {\n cursor.timestamp = entry.timestamp;\n cursor.seenEntryKeysAtTimestamp.clear();\n }\n cursor.seenEntryKeysAtTimestamp.add(entryKey);\n}\n\nfunction getPrimaryKeyValue(\n primaryKey: ObjectPrimaryKeyV2,\n primaryKeyProperty: string,\n decodeEditObject: (object: FoundryObject) => FoundryObject\n): string | number {\n const values = Object.values(primaryKey);\n if (values.length !== 1) {\n throw new Error(\"Foundry object collections currently only support single-field primary keys.\");\n }\n const value = decodeEditObject({\n [primaryKeyProperty]: values[0],\n })[primaryKeyProperty];\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new Error(\"Foundry object collections currently only support string or number primary keys.\");\n }\n return value;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n// ---------------------------------------------------------------------------\n// Foundry object fetching\n// ---------------------------------------------------------------------------\n\nasync function fetchFoundryObjects(\n client: OntologyClient,\n objectType: string,\n selectedProperties: string[],\n opts: LoadSubsetOptions,\n decodeObject: (object: FoundryObject) => FoundryObject = (object) => object\n): Promise<FoundryObject[]> {\n opts.signal?.throwIfAborted();\n const offset = Math.max(0, Math.trunc(opts.offset ?? 0));\n const limit = opts.limit === undefined ? undefined : Math.max(0, Math.trunc(opts.limit));\n if (limit === 0) return [];\n\n let where = convertLoadSubsetFilter(opts.where);\n if (isAlwaysFalseFilter(where) || (where?.type === \"in\" && where.value.length === 0)) {\n return [];\n }\n\n if (opts.cursor?.whereFrom) {\n const cursorWhere = convertLoadSubsetFilter(opts.cursor.whereFrom);\n if (isAlwaysFalseFilter(cursorWhere)) {\n return [];\n }\n if (cursorWhere) {\n where = where ? { type: \"and\", value: [where, cursorWhere] } : cursorWhere;\n }\n }\n\n const requestClient = opts.signal\n ? {\n ...client,\n fetch: (input: RequestInfo | URL, init?: RequestInit) =>\n client.fetch(input, {\n ...init,\n signal: opts.signal,\n }),\n }\n : client;\n const results = await AsyncIterable.toArray(\n AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n OntologyObjectsV2.search(requestClient, client.ontologyRid, objectType, {\n snapshot: true,\n where,\n excludeRid: true,\n select: selectedProperties,\n selectV2: [],\n pageSize,\n pageToken,\n orderBy: convertLoadSubsetOrderBy(opts.orderBy),\n }),\n (page) => page.nextPageToken,\n (page) => page.data,\n 10_000,\n limit === undefined ? undefined : offset + limit\n )\n );\n opts.signal?.throwIfAborted();\n\n return (results as FoundryObject[])\n .slice(offset, limit === undefined ? undefined : offset + limit)\n .map(decodeObject);\n}\n\nfunction createSyncConfig(\n client: OntologyClient,\n objectType: string,\n primaryKeyProperty: string,\n selectedProperties: string[],\n decodeObject: (object: FoundryObject) => FoundryObject = (object) => object,\n decodeEditObject: (object: FoundryObject) => FoundryObject = decodeObject,\n live: boolean = true\n): { sync: SyncConfig<Record<string, unknown>, string | number>; utils: ObjectCollectionUtils } {\n const seenOperationIds = new Store<Set<string>>(new Set<string>());\n const syncDisposed = new Store(false);\n const fullSourceRefreshVersion = new Store(0);\n let editHistoryUnavailable = false;\n let requestFullRefresh: (() => Promise<void>) | undefined;\n const refresh = async (): Promise<void> => {\n if (!requestFullRefresh || syncDisposed.state) throw new ObjectCollectionSyncAbortedError(objectType);\n await requestFullRefresh();\n };\n const refreshInBackground = () => {\n void refresh().catch((error: unknown) => {\n console.warn(`Failed full Foundry refresh for ${objectType}.`, error);\n });\n };\n let requestEditHistoryCatchUp: (() => void) | undefined;\n\n const awaitOperationId = async (\n operationId: string,\n timeout: number = COLLECTION_SYNC_TIMEOUT_MS\n ): Promise<void> => {\n if (typeof operationId !== \"string\" || operationId.length === 0) {\n throw new Error(\"Foundry operationId must be a non-empty string.\");\n }\n\n if (seenOperationIds.state.has(operationId)) {\n return;\n }\n\n if (syncDisposed.state) {\n throw new ObjectCollectionSyncAbortedError(objectType);\n }\n\n if (!requestEditHistoryCatchUp) {\n // An on-demand collection has no local state to confirm until its sync starts.\n return;\n }\n\n const refreshVersionAtStart = fullSourceRefreshVersion.state;\n const historyUnavailableAtStart = editHistoryUnavailable;\n return new Promise<void>((resolve, reject) => {\n const cleanup = () => {\n clearTimeout(timeoutId);\n seenOperationIdsSubscription.unsubscribe();\n fullSourceRefreshVersionSubscription.unsubscribe();\n disposedSubscription.unsubscribe();\n };\n\n const timeoutId = setTimeout(() => {\n cleanup();\n reject(new TimeoutWaitingForOperationIdError(operationId, objectType));\n }, timeout);\n const seenOperationIdsSubscription = seenOperationIds.subscribe(() => {\n if (seenOperationIds.state.has(operationId)) {\n cleanup();\n resolve();\n }\n });\n const fullSourceRefreshVersionSubscription = fullSourceRefreshVersion.subscribe(() => {\n if (\n !historyUnavailableAtStart &&\n editHistoryUnavailable &&\n fullSourceRefreshVersion.state > refreshVersionAtStart\n ) {\n cleanup();\n resolve();\n }\n });\n const disposedSubscription = syncDisposed.subscribe(() => {\n if (syncDisposed.state) {\n cleanup();\n reject(new ObjectCollectionSyncAbortedError(objectType));\n }\n });\n if (editHistoryUnavailable) {\n void refresh().then(\n () => {\n cleanup();\n resolve();\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n }\n );\n } else requestEditHistoryCatchUp?.();\n });\n };\n\n const utils: ObjectCollectionUtils = { awaitOperationId, refresh };\n\n const sync: SyncConfig<Record<string, unknown>, string | number> = {\n sync: (params) => {\n const { begin, write, commit, markError, markReady, truncate } = params;\n const collectionMetadata = params.metadata?.collection;\n\n syncDisposed.setState(() => false);\n\n let disposed = false;\n const restoredEditHistoryCursor = deserializeEditHistoryCursor(\n collectionMetadata?.get(EDIT_HISTORY_CURSOR_METADATA_KEY)\n );\n let editHistoryCursor = restoredEditHistoryCursor ?? createEditHistoryCursor();\n let initialCommit: ReturnType<typeof commit> = true;\n if (!restoredEditHistoryCursor) {\n if (collectionMetadata) {\n begin();\n collectionMetadata.set(\n EDIT_HISTORY_CURSOR_METADATA_KEY,\n serializeEditHistoryCursor(editHistoryCursor)\n );\n initialCommit = commit();\n }\n }\n let catchUpRequested = false;\n let catchUpTask: Promise<void> | undefined;\n let pendingDirectWatcherUpdates: ObjectSetUpdate[] = [];\n let fullRefreshRequested = false;\n let fullRefreshTask: Promise<void> | undefined;\n\n const getObjectKey = (object: FoundryObject): string | number =>\n object[primaryKeyProperty] as string | number;\n\n const getWatcherObjectKey = (object: FoundryObject): string | number => {\n const key = object[primaryKeyProperty] ?? object.__primaryKey;\n if (typeof key !== \"string\" && typeof key !== \"number\") {\n throw new Error(\n `Foundry websocket update for ${objectType} did not include a supported primary key.`\n );\n }\n return key;\n };\n\n const upsertObject = (object: FoundryObject) => {\n const key = getObjectKey(object);\n const exists = params.collection.has(key);\n const existing = exists ? params.collection.get(key) : undefined;\n write({\n type: exists ? \"update\" : \"insert\",\n value: existing\n ? {\n ...existing,\n ...object,\n }\n : object,\n });\n };\n\n const deleteObjectByKey = (key: string | number): boolean => {\n write({ type: \"delete\", key });\n return true;\n };\n\n const fetchEditHistoryPage = (body: Parameters<typeof ObjectTypesV2.getEditsHistory>[3]) =>\n ObjectTypesV2.getEditsHistory(\n client,\n client.ontologyRid,\n objectType,\n body,\n // oxlint-disable-next-line typescript/no-unsafe-argument\n {\n preview: true,\n // oxlint-disable-next-line typescript/no-explicit-any\n } as unknown as any\n );\n\n const decodeEditProperties = (\n properties: Record<string, unknown>,\n primaryKey: string | number\n ): FoundryObject =>\n decodeEditObject({\n ...properties,\n [primaryKeyProperty]: primaryKey,\n });\n\n const decodeWatcherObject = (object: FoundryObject, primaryKey: string | number): FoundryObject =>\n decodeObject({\n ...object,\n [primaryKeyProperty]: primaryKey,\n });\n\n const applyDirectWatcherUpdates = async (updates: ObjectSetUpdate[]): Promise<void> => {\n const pendingMutations = new Map<\n string | number,\n { type: \"upsert\"; object: FoundryObject } | { type: \"delete\" }\n >();\n\n for (const update of updates) {\n if (update.type !== \"object\") continue;\n\n const object = update.object;\n const primaryKey = getWatcherObjectKey(object);\n\n switch (update.state) {\n case \"ADDED_OR_UPDATED\":\n pendingMutations.set(primaryKey, {\n type: \"upsert\",\n object: decodeWatcherObject(object, primaryKey),\n });\n break;\n case \"REMOVED\":\n pendingMutations.set(primaryKey, { type: \"delete\" });\n break;\n }\n }\n\n let transactionStarted = false;\n for (const [primaryKey, mutation] of pendingMutations) {\n if (!transactionStarted) {\n begin();\n transactionStarted = true;\n }\n\n if (mutation.type === \"delete\") {\n deleteObjectByKey(primaryKey);\n } else {\n upsertObject(mutation.object);\n }\n }\n\n const receipt = transactionStarted ? commit() : true;\n\n if (receipt !== true) await receipt;\n };\n\n const switchToDirectWebsocketMode = (error: unknown): void => {\n if (!editHistoryUnavailable) {\n const errorMessage = error instanceof Error ? error.message : error;\n console.warn(\n `Edit history catch-up failed for ${objectType}; falling back to direct websocket updates.`,\n errorMessage\n );\n editHistoryUnavailable = true;\n }\n\n if (pendingDirectWatcherUpdates.length > 0) {\n const updates = pendingDirectWatcherUpdates;\n pendingDirectWatcherUpdates = [];\n void applyDirectWatcherUpdates(updates).catch((applyError: unknown) => {\n console.warn(`Failed to apply direct Foundry updates for ${objectType}.`, applyError);\n });\n }\n refreshInBackground();\n };\n\n const catchUpFromEditHistory = async (): Promise<void> => {\n const nextEditHistoryCursor = cloneEditHistoryCursor(editHistoryCursor);\n const pendingMutations = new Map<\n string | number,\n { type: \"upsert\"; object: FoundryObject } | { type: \"delete\" }\n >();\n const newOperationIds = new Set<string>();\n\n for await (const entry of AsyncIterable.fromPagination(\n (pageSize, pageToken: string | undefined) =>\n fetchEditHistoryPage({\n filters: {\n type: \"timestampFilter\",\n startTime: nextEditHistoryCursor.timestamp,\n },\n includeAllPreviousProperties: true,\n pageSize,\n pageToken,\n sortOrder: \"oldest_first\",\n }),\n (page) => page.nextPageToken,\n (page) => page.data,\n EDIT_HISTORY_PAGE_SIZE\n )) {\n if (disposed) break;\n if (!shouldProcessEditHistoryEntry(nextEditHistoryCursor, entry)) continue;\n advanceEditHistoryCursor(nextEditHistoryCursor, entry);\n newOperationIds.add(entry.operationId);\n\n const primaryKey = getPrimaryKeyValue(\n entry.objectPrimaryKey,\n primaryKeyProperty,\n decodeEditObject\n );\n\n switch (entry.edit.type) {\n case \"createEdit\":\n case \"modifyEdit\":\n pendingMutations.set(primaryKey, {\n type: \"upsert\",\n object: decodeEditProperties(entry.edit.properties, primaryKey),\n });\n break;\n case \"deleteEdit\":\n pendingMutations.set(primaryKey, { type: \"delete\" });\n break;\n }\n }\n\n if (disposed) return;\n\n const checkpointChanged = !editHistoryCursorsEqual(editHistoryCursor, nextEditHistoryCursor);\n let transactionStarted = false;\n const ensureTransaction = () => {\n if (transactionStarted) return;\n begin();\n transactionStarted = true;\n };\n for (const [primaryKey, mutation] of pendingMutations) {\n ensureTransaction();\n\n if (mutation.type === \"delete\") {\n deleteObjectByKey(primaryKey);\n } else {\n upsertObject(mutation.object);\n }\n }\n\n if (checkpointChanged && collectionMetadata) {\n ensureTransaction();\n collectionMetadata.set(\n EDIT_HISTORY_CURSOR_METADATA_KEY,\n serializeEditHistoryCursor(nextEditHistoryCursor)\n );\n }\n\n const receipt = transactionStarted ? commit() : true;\n\n if (checkpointChanged) {\n editHistoryCursor = nextEditHistoryCursor;\n }\n\n if (newOperationIds.size > 0) {\n seenOperationIds.setState((current) => new Set([...current, ...newOperationIds]));\n }\n\n pendingDirectWatcherUpdates = [];\n\n if (receipt !== true) await receipt;\n };\n\n const refreshAllFromSource = async (): Promise<void> => {\n const objects = await fetchFoundryObjects(\n client,\n objectType,\n selectedProperties,\n {},\n decodeObject\n );\n if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);\n\n begin();\n truncate();\n for (const object of objects) {\n write({\n type: \"insert\",\n value: object,\n });\n }\n const receipt = commit();\n\n if (receipt !== true) await receipt;\n if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);\n while (pendingDirectWatcherUpdates.length > 0 && !disposed) {\n const updates = pendingDirectWatcherUpdates;\n pendingDirectWatcherUpdates = [];\n await applyDirectWatcherUpdates(updates);\n }\n if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);\n fullSourceRefreshVersion.setState((version) => version + 1);\n };\n\n requestFullRefresh = () => {\n fullRefreshRequested = true;\n if (fullRefreshTask) return fullRefreshTask;\n\n const priorCatchUp = catchUpTask;\n fullRefreshTask = (async () => {\n if (priorCatchUp) await priorCatchUp;\n if (disposed) throw new ObjectCollectionSyncAbortedError(objectType);\n while (fullRefreshRequested && !disposed) {\n fullRefreshRequested = false;\n await refreshAllFromSource();\n }\n })()\n .catch(async (error: unknown) => {\n // A failed snapshot must not strand updates queued by the live watcher.\n while (pendingDirectWatcherUpdates.length > 0 && !disposed) {\n const updates = pendingDirectWatcherUpdates;\n pendingDirectWatcherUpdates = [];\n try {\n await applyDirectWatcherUpdates(updates);\n } catch (applyError: unknown) {\n console.warn(\n `Failed to apply queued Foundry updates for ${objectType}.`,\n applyError\n );\n break;\n }\n }\n throw error;\n })\n .finally(() => {\n fullRefreshTask = undefined;\n if (fullRefreshRequested && !disposed) {\n refreshInBackground();\n }\n });\n return fullRefreshTask;\n };\n\n requestEditHistoryCatchUp = () => {\n if (editHistoryUnavailable) {\n return;\n }\n\n catchUpRequested = true;\n if (catchUpTask) return;\n\n const priorRefresh = fullRefreshTask;\n catchUpTask = (async () => {\n if (priorRefresh) await priorRefresh;\n while (catchUpRequested && !disposed) {\n catchUpRequested = false;\n await catchUpFromEditHistory();\n }\n })()\n .catch((error: unknown) => {\n switchToDirectWebsocketMode(error);\n })\n .finally(() => {\n catchUpTask = undefined;\n if (catchUpRequested && !disposed) {\n requestEditHistoryCatchUp?.();\n }\n });\n };\n\n const loadSubset = async (opts: LoadSubsetOptions): Promise<void> => {\n const objects = await fetchFoundryObjects(\n client,\n objectType,\n selectedProperties,\n opts,\n decodeObject\n );\n if (objects.length > 0) {\n begin();\n for (const object of objects) {\n upsertObject(object);\n }\n const receipt = commit(opts.signal);\n if (receipt !== true) await receipt;\n }\n };\n\n const loadSubsetDedupe = new DeduplicatedLoadSubset({ loadSubset });\n const unsubscribe = live\n ? getObjectSetWatcherManager(client).subscribe({ type: \"base\", objectType }, (message) => {\n switch (message.type) {\n case \"change\": {\n if (fullRefreshTask) {\n pendingDirectWatcherUpdates.push(...message.updates);\n } else if (editHistoryUnavailable) {\n void applyDirectWatcherUpdates(message.updates).catch((error: unknown) => {\n console.warn(\n `Failed to apply direct Foundry updates for ${objectType}.`,\n error\n );\n refreshInBackground();\n });\n } else {\n pendingDirectWatcherUpdates.push(...message.updates);\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n case \"refresh\": {\n if (editHistoryUnavailable) {\n refreshInBackground();\n } else {\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n case \"state\": {\n if (message.status !== \"open\") break;\n if (editHistoryUnavailable) {\n refreshInBackground();\n } else {\n requestEditHistoryCatchUp?.();\n }\n break;\n }\n }\n })\n : () => {};\n\n // start task here, cleanup can stop it\n // in that task:\n // - spawn object set subscription, which sends messages to catch up\n // - actions sends messages to catch up\n\n if (initialCommit === true) {\n markReady();\n } else {\n void initialCommit.then(markReady, markError);\n }\n\n return {\n loadSubset: loadSubsetDedupe.loadSubset,\n cleanup: () => {\n disposed = true;\n requestEditHistoryCatchUp = undefined;\n requestFullRefresh = undefined;\n syncDisposed.setState(() => true);\n unsubscribe();\n loadSubsetDedupe.reset();\n },\n };\n },\n };\n\n return { sync, utils };\n}\n\n// ---------------------------------------------------------------------------\n// Collection option types\n// ---------------------------------------------------------------------------\n\nexport interface ObjectCollectionOpts {\n client: OntologyClient;\n objectType: string;\n primaryKeyProperty: string;\n selectedProperties: string[];\n live?: boolean;\n decodeObject?: (object: Record<string, unknown>) => Record<string, unknown>;\n decodeEditObject?: (object: Record<string, unknown>) => Record<string, unknown>;\n}\n\nexport interface ObjectCollectionConfig<TSchema extends StandardSchema<OntologyObject>>\n extends\n ObjectCollectionOpts,\n Omit<\n CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema>,\n \"sync\" | \"syncMode\" | \"getKey\" | \"onInsert\" | \"onUpdate\" | \"onDelete\"\n > {\n schema: TSchema;\n}\n\n// ---------------------------------------------------------------------------\n// Public collection options\n// ---------------------------------------------------------------------------\n\nexport function objectCollectionOptions<TSchema extends StandardSchema<OntologyObject>>(\n config: ObjectCollectionConfig<TSchema>\n): WithRequired<\n CollectionConfig<InferSchemaOutput<TSchema>, string | number, TSchema, ObjectCollectionUtils>,\n \"schema\"\n>;\nexport function objectCollectionOptions(config: ObjectCollectionOpts): {\n syncMode: \"on-demand\";\n sync: SyncConfig<Record<string, unknown>, string | number>;\n utils: ObjectCollectionUtils;\n};\n// oxlint-disable-next-line typescript/no-explicit-any\nexport function objectCollectionOptions(config: any): any {\n const {\n client,\n objectType,\n primaryKeyProperty,\n selectedProperties,\n live,\n decodeObject,\n decodeEditObject,\n schema,\n ...rest\n } = config as ObjectCollectionOpts & { schema?: StandardSchema<OntologyObject> } & Record<\n string,\n unknown\n >;\n const { sync, utils } = createSyncConfig(\n client,\n objectType,\n primaryKeyProperty,\n selectedProperties,\n decodeObject,\n decodeEditObject,\n live\n );\n\n if (schema === undefined) {\n return { syncMode: \"on-demand\" as const, sync, utils };\n }\n\n return {\n ...rest,\n schema,\n defaultIndexType: BasicIndex,\n autoIndex: \"eager\",\n syncMode: \"on-demand\" as const,\n getKey: (object: Record<string, unknown>) =>\n (object as Record<string, string | number>)[primaryKeyProperty] as string | number,\n sync,\n utils,\n };\n}\n"],"mappings":";;;;;;;AAwCA,MAAM,6BAA6B;AAEnC,IAAM,oCAAN,cAAgD,MAAM;CAClD,YAAY,aAAqB,YAAoB;EACjD,MAAM,2CAA2C,YAAY,eAAe,WAAW,EAAE;EACzF,KAAK,OAAO;CAChB;AACJ;AAEA,IAAM,mCAAN,cAA+C,MAAM;CACjD,YAAY,YAAoB;EAC5B,MAAM,oBAAoB,WAAW,4CAA4C;EACjF,KAAK,OAAO;CAChB;AACJ;AAWA,MAAM,yBAAyB;AAC/B,MAAM,mCAAmC;AACzC,MAAM,8BAA8B;AAapC,SAAS,wBAAwB,6BAAoB,IAAI,KAAK,EAAA,CAAE,YAAY,GAAsB;CAC9F,OAAO;EAAE;EAAW,0CAA0B,IAAI,IAAI;CAAE;AAC5D;AAEA,SAAS,uBAAuB,QAA8C;CAC1E,OAAO;EACH,WAAW,OAAO;EAClB,0BAA0B,IAAI,IAAI,OAAO,wBAAwB;CACrE;AACJ;AAEA,SAAS,2BAA2B,QAAuD;CACvF,OAAO;EACH,SAAS;EACT,WAAW,OAAO;EAClB,0BAA0B,CAAC,GAAG,OAAO,wBAAwB,CAAC,CAAC,KAAK;CACxE;AACJ;AAEA,SAAS,6BAA6B,OAA+C;CACjF,IACI,CAAC,cAAc,KAAK,KACpB,MAAM,YAAY,+BAClB,OAAO,MAAM,cAAc,YAC3B,CAAC,MAAM,QAAQ,MAAM,wBAAwB,KAC7C,CAAC,MAAM,yBAAyB,OAAO,QAAQ,OAAO,QAAQ,QAAQ,GAEtE;CAEJ,OAAO;EACH,WAAW,MAAM;EACjB,0BAA0B,IAAI,IAAI,MAAM,wBAAwB;CACpE;AACJ;AAEA,SAAS,wBAAwB,MAAyB,OAAmC;CACzF,OACI,KAAK,cAAc,MAAM,aACzB,KAAK,yBAAyB,SAAS,MAAM,yBAAyB,QACtE,CAAC,GAAG,KAAK,wBAAwB,CAAC,CAAC,OAAO,QAAQ,MAAM,yBAAyB,IAAI,GAAG,CAAC;AAEjG;AAEA,SAAS,sBAAsB,OAAyB;CACpD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,qBAAqB;CAChE,IAAI,cAAc,KAAK,GACnB,OAAO,OAAO,YACV,OAAO,KAAK,KAAK,CAAC,CACb,KAAK,CAAC,CACN,KAAK,QAAQ,CAAC,KAAK,sBAAsB,MAAM,IAAI,CAAC,CAAC,CAC9D;CAEJ,OAAO;AACX;AAEA,SAAS,uBAAuB,OAAuC;CACnE,OAAO,KAAK,UACR,sBAAsB;EAClB,kBAAkB,MAAM;EACxB,aAAa,MAAM;EACnB,WAAW,MAAM;EACjB,MAAM,MAAM;CAChB,CAAC,CACL;AACJ;AAEA,SAAS,8BAA8B,QAA2B,OAAwC;CACtG,IAAI,MAAM,YAAY,OAAO,WAAW,OAAO;CAC/C,IAAI,MAAM,cAAc,OAAO,WAC3B,OAAO,CAAC,OAAO,yBAAyB,IAAI,uBAAuB,KAAK,CAAC;CAE7E,OAAO;AACX;AAEA,SAAS,yBAAyB,QAA2B,OAAqC;CAC9F,MAAM,WAAW,uBAAuB,KAAK;CAC7C,IAAI,MAAM,YAAY,OAAO,WAAW;EACpC,OAAO,YAAY,MAAM;EACzB,OAAO,yBAAyB,MAAM;CAC1C;CACA,OAAO,yBAAyB,IAAI,QAAQ;AAChD;AAEA,SAAS,mBACL,YACA,oBACA,kBACe;CACf,MAAM,SAAS,OAAO,OAAO,UAAU;CACvC,IAAI,OAAO,WAAW,GAClB,MAAM,IAAI,MAAM,8EAA8E;CAElG,MAAM,QAAQ,iBAAiB,GAC1B,qBAAqB,OAAO,GACjC,CAAC,CAAC,CAAC;CACH,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAC9C,MAAM,IAAI,MAAM,kFAAkF;CAEtG,OAAO;AACX;AAEA,SAAS,cAAc,OAAkD;CACrE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC9E;AAMA,eAAe,oBACX,QACA,YACA,oBACA,MACA,gBAA0D,WAAW,QAC7C;CACxB,KAAK,QAAQ,eAAe;CAC5B,MAAM,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC;CACvD,MAAM,QAAQ,KAAK,UAAU,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,KAAK,CAAC;CACvF,IAAI,UAAU,GAAG,OAAO,CAAC;CAEzB,IAAI,QAAQ,wBAAwB,KAAK,KAAK;CAC9C,IAAI,oBAAoB,KAAK,KAAM,OAAO,SAAS,QAAQ,MAAM,MAAM,WAAW,GAC9E,OAAO,CAAC;CAGZ,IAAI,KAAK,QAAQ,WAAW;EACxB,MAAM,cAAc,wBAAwB,KAAK,OAAO,SAAS;EACjE,IAAI,oBAAoB,WAAW,GAC/B,OAAO,CAAC;EAEZ,IAAI,aACA,QAAQ,QAAQ;GAAE,MAAM;GAAO,OAAO,CAAC,OAAO,WAAW;EAAE,IAAI;CAEvE;CAEA,MAAM,gBAAgB,KAAK,SACrB;EACI,GAAG;EACH,QAAQ,OAA0B,SAC9B,OAAO,MAAM,OAAO;GAChB,GAAG;GACH,QAAQ,KAAK;EACjB,CAAC;CACT,IACA;CACN,MAAM,UAAU,MAAMA,QAClBC,gBACK,UAAU,cACP,kBAAkB,OAAO,eAAe,OAAO,aAAa,YAAY;EACpE,UAAU;EACV;EACA,YAAY;EACZ,QAAQ;EACR,UAAU,CAAC;EACX;EACA;EACA,SAAS,yBAAyB,KAAK,OAAO;CAClD,CAAC,IACJ,SAAS,KAAK,gBACd,SAAS,KAAK,MACf,KACA,UAAU,KAAA,IAAY,KAAA,IAAY,SAAS,KAC/C,CACJ;CACA,KAAK,QAAQ,eAAe;CAE5B,OAAQ,QACH,MAAM,QAAQ,UAAU,KAAA,IAAY,KAAA,IAAY,SAAS,KAAK,CAAC,CAC/D,IAAI,YAAY;AACzB;AAEA,SAAS,iBACL,QACA,YACA,oBACA,oBACA,gBAA0D,WAAW,QACrE,mBAA6D,cAC7D,OAAgB,MAC4E;CAC5F,MAAM,mBAAmB,IAAI,sBAAmB,IAAI,IAAY,CAAC;CACjE,MAAM,eAAe,IAAI,MAAM,KAAK;CACpC,MAAM,2BAA2B,IAAI,MAAM,CAAC;CAC5C,IAAI,yBAAyB;CAC7B,IAAI;CACJ,MAAM,UAAU,YAA2B;EACvC,IAAI,CAAC,sBAAsB,aAAa,OAAO,MAAM,IAAI,iCAAiC,UAAU;EACpG,MAAM,mBAAmB;CAC7B;CACA,MAAM,4BAA4B;EAC9B,QAAa,CAAC,CAAC,OAAO,UAAmB;GACrC,QAAQ,KAAK,mCAAmC,WAAW,IAAI,KAAK;EACxE,CAAC;CACL;CACA,IAAI;CAEJ,MAAM,mBAAmB,OACrB,aACA,UAAkB,+BACF;EAChB,IAAI,OAAO,gBAAgB,YAAY,YAAY,WAAW,GAC1D,MAAM,IAAI,MAAM,iDAAiD;EAGrE,IAAI,iBAAiB,MAAM,IAAI,WAAW,GACtC;EAGJ,IAAI,aAAa,OACb,MAAM,IAAI,iCAAiC,UAAU;EAGzD,IAAI,CAAC,2BAED;EAGJ,MAAM,wBAAwB,yBAAyB;EACvD,MAAM,4BAA4B;EAClC,OAAO,IAAI,SAAe,SAAS,WAAW;GAC1C,MAAM,gBAAgB;IAClB,aAAa,SAAS;IACtB,6BAA6B,YAAY;IACzC,qCAAqC,YAAY;IACjD,qBAAqB,YAAY;GACrC;GAEA,MAAM,YAAY,iBAAiB;IAC/B,QAAQ;IACR,OAAO,IAAI,kCAAkC,aAAa,UAAU,CAAC;GACzE,GAAG,OAAO;GACV,MAAM,+BAA+B,iBAAiB,gBAAgB;IAClE,IAAI,iBAAiB,MAAM,IAAI,WAAW,GAAG;KACzC,QAAQ;KACR,QAAQ;IACZ;GACJ,CAAC;GACD,MAAM,uCAAuC,yBAAyB,gBAAgB;IAClF,IACI,CAAC,6BACD,0BACA,yBAAyB,QAAQ,uBACnC;KACE,QAAQ;KACR,QAAQ;IACZ;GACJ,CAAC;GACD,MAAM,uBAAuB,aAAa,gBAAgB;IACtD,IAAI,aAAa,OAAO;KACpB,QAAQ;KACR,OAAO,IAAI,iCAAiC,UAAU,CAAC;IAC3D;GACJ,CAAC;GACD,IAAI,wBACA,QAAa,CAAC,CAAC,WACL;IACF,QAAQ;IACR,QAAQ;GACZ,IACC,UAAmB;IAChB,QAAQ;IACR,OAAO,KAAK;GAChB,CACJ;QACG,4BAA4B;EACvC,CAAC;CACL;CA+aA,OAAO;EAAE,MAAA,EA1aL,OAAO,WAAW;GACd,MAAM,EAAE,OAAO,OAAO,QAAQ,WAAW,WAAW,aAAa;GACjE,MAAM,qBAAqB,OAAO,UAAU;GAE5C,aAAa,eAAe,KAAK;GAEjC,IAAI,WAAW;GACf,MAAM,4BAA4B,6BAC9B,oBAAoB,IAAI,gCAAgC,CAC5D;GACA,IAAI,oBAAoB,6BAA6B,wBAAwB;GAC7E,IAAI,gBAA2C;GAC/C,IAAI,CAAC,2BACG;QAAA,oBAAoB;KACpB,MAAM;KACN,mBAAmB,IACf,kCACA,2BAA2B,iBAAiB,CAChD;KACA,gBAAgB,OAAO;IAC3B;;GAEJ,IAAI,mBAAmB;GACvB,IAAI;GACJ,IAAI,8BAAiD,CAAC;GACtD,IAAI,uBAAuB;GAC3B,IAAI;GAEJ,MAAM,gBAAgB,WAClB,OAAO;GAEX,MAAM,uBAAuB,WAA2C;IACpE,MAAM,MAAM,OAAO,uBAAuB,OAAO;IACjD,IAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,UAC1C,MAAM,IAAI,MACN,gCAAgC,WAAW,0CAC/C;IAEJ,OAAO;GACX;GAEA,MAAM,gBAAgB,WAA0B;IAC5C,MAAM,MAAM,aAAa,MAAM;IAC/B,MAAM,SAAS,OAAO,WAAW,IAAI,GAAG;IACxC,MAAM,WAAW,SAAS,OAAO,WAAW,IAAI,GAAG,IAAI,KAAA;IACvD,MAAM;KACF,MAAM,SAAS,WAAW;KAC1B,OAAO,WACD;MACI,GAAG;MACH,GAAG;KACP,IACA;IACV,CAAC;GACL;GAEA,MAAM,qBAAqB,QAAkC;IACzD,MAAM;KAAE,MAAM;KAAU;IAAI,CAAC;IAC7B,OAAO;GACX;GAEA,MAAM,wBAAwB,SAC1B,cAAc,gBACV,QACA,OAAO,aACP,YACA,MAEA,EACI,SAAS,KAEb,CACJ;GAEJ,MAAM,wBACF,YACA,eAEA,iBAAiB;IACb,GAAG;KACF,qBAAqB;GAC1B,CAAC;GAEL,MAAM,uBAAuB,QAAuB,eAChD,aAAa;IACT,GAAG;KACF,qBAAqB;GAC1B,CAAC;GAEL,MAAM,4BAA4B,OAAO,YAA8C;IACnF,MAAM,mCAAmB,IAAI,IAG3B;IAEF,KAAK,MAAM,UAAU,SAAS;KAC1B,IAAI,OAAO,SAAS,UAAU;KAE9B,MAAM,SAAS,OAAO;KACtB,MAAM,aAAa,oBAAoB,MAAM;KAE7C,QAAQ,OAAO,OAAf;MACI,KAAK;OACD,iBAAiB,IAAI,YAAY;QAC7B,MAAM;QACN,QAAQ,oBAAoB,QAAQ,UAAU;OAClD,CAAC;OACD;MACJ,KAAK,WACD,iBAAiB,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;KAE3D;IACJ;IAEA,IAAI,qBAAqB;IACzB,KAAK,MAAM,CAAC,YAAY,aAAa,kBAAkB;KACnD,IAAI,CAAC,oBAAoB;MACrB,MAAM;MACN,qBAAqB;KACzB;KAEA,IAAI,SAAS,SAAS,UAClB,kBAAkB,UAAU;UAE5B,aAAa,SAAS,MAAM;IAEpC;IAEA,MAAM,UAAU,qBAAqB,OAAO,IAAI;IAEhD,IAAI,YAAY,MAAM,MAAM;GAChC;GAEA,MAAM,+BAA+B,UAAyB;IAC1D,IAAI,CAAC,wBAAwB;KACzB,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;KAC9D,QAAQ,KACJ,oCAAoC,WAAW,8CAC/C,YACJ;KACA,yBAAyB;IAC7B;IAEA,IAAI,4BAA4B,SAAS,GAAG;KACxC,MAAM,UAAU;KAChB,8BAA8B,CAAC;KAC/B,0BAA+B,OAAO,CAAC,CAAC,OAAO,eAAwB;MACnE,QAAQ,KAAK,8CAA8C,WAAW,IAAI,UAAU;KACxF,CAAC;IACL;IACA,oBAAoB;GACxB;GAEA,MAAM,yBAAyB,YAA2B;IACtD,MAAM,wBAAwB,uBAAuB,iBAAiB;IACtE,MAAM,mCAAmB,IAAI,IAG3B;IACF,MAAM,kCAAkB,IAAI,IAAY;IAExC,WAAW,MAAM,SAASA,gBACrB,UAAU,cACP,qBAAqB;KACjB,SAAS;MACL,MAAM;MACN,WAAW,sBAAsB;KACrC;KACA,8BAA8B;KAC9B;KACA;KACA,WAAW;IACf,CAAC,IACJ,SAAS,KAAK,gBACd,SAAS,KAAK,MACf,sBACJ,GAAG;KACC,IAAI,UAAU;KACd,IAAI,CAAC,8BAA8B,uBAAuB,KAAK,GAAG;KAClE,yBAAyB,uBAAuB,KAAK;KACrD,gBAAgB,IAAI,MAAM,WAAW;KAErC,MAAM,aAAa,mBACf,MAAM,kBACN,oBACA,gBACJ;KAEA,QAAQ,MAAM,KAAK,MAAnB;MACI,KAAK;MACL,KAAK;OACD,iBAAiB,IAAI,YAAY;QAC7B,MAAM;QACN,QAAQ,qBAAqB,MAAM,KAAK,YAAY,UAAU;OAClE,CAAC;OACD;MACJ,KAAK,cACD,iBAAiB,IAAI,YAAY,EAAE,MAAM,SAAS,CAAC;KAE3D;IACJ;IAEA,IAAI,UAAU;IAEd,MAAM,oBAAoB,CAAC,wBAAwB,mBAAmB,qBAAqB;IAC3F,IAAI,qBAAqB;IACzB,MAAM,0BAA0B;KAC5B,IAAI,oBAAoB;KACxB,MAAM;KACN,qBAAqB;IACzB;IACA,KAAK,MAAM,CAAC,YAAY,aAAa,kBAAkB;KACnD,kBAAkB;KAElB,IAAI,SAAS,SAAS,UAClB,kBAAkB,UAAU;UAE5B,aAAa,SAAS,MAAM;IAEpC;IAEA,IAAI,qBAAqB,oBAAoB;KACzC,kBAAkB;KAClB,mBAAmB,IACf,kCACA,2BAA2B,qBAAqB,CACpD;IACJ;IAEA,MAAM,UAAU,qBAAqB,OAAO,IAAI;IAEhD,IAAI,mBACA,oBAAoB;IAGxB,IAAI,gBAAgB,OAAO,GACvB,iBAAiB,UAAU,4BAAY,IAAI,IAAI,CAAC,GAAG,SAAS,GAAG,eAAe,CAAC,CAAC;IAGpF,8BAA8B,CAAC;IAE/B,IAAI,YAAY,MAAM,MAAM;GAChC;GAEA,MAAM,uBAAuB,YAA2B;IACpD,MAAM,UAAU,MAAM,oBAClB,QACA,YACA,oBACA,CAAC,GACD,YACJ;IACA,IAAI,UAAU,MAAM,IAAI,iCAAiC,UAAU;IAEnE,MAAM;IACN,SAAS;IACT,KAAK,MAAM,UAAU,SACjB,MAAM;KACF,MAAM;KACN,OAAO;IACX,CAAC;IAEL,MAAM,UAAU,OAAO;IAEvB,IAAI,YAAY,MAAM,MAAM;IAC5B,IAAI,UAAU,MAAM,IAAI,iCAAiC,UAAU;IACnE,OAAO,4BAA4B,SAAS,KAAK,CAAC,UAAU;KACxD,MAAM,UAAU;KAChB,8BAA8B,CAAC;KAC/B,MAAM,0BAA0B,OAAO;IAC3C;IACA,IAAI,UAAU,MAAM,IAAI,iCAAiC,UAAU;IACnE,yBAAyB,UAAU,YAAY,UAAU,CAAC;GAC9D;GAEA,2BAA2B;IACvB,uBAAuB;IACvB,IAAI,iBAAiB,OAAO;IAE5B,MAAM,eAAe;IACrB,mBAAmB,YAAY;KAC3B,IAAI,cAAc,MAAM;KACxB,IAAI,UAAU,MAAM,IAAI,iCAAiC,UAAU;KACnE,OAAO,wBAAwB,CAAC,UAAU;MACtC,uBAAuB;MACvB,MAAM,qBAAqB;KAC/B;IACJ,EAAA,CAAG,CAAC,CACC,MAAM,OAAO,UAAmB;KAE7B,OAAO,4BAA4B,SAAS,KAAK,CAAC,UAAU;MACxD,MAAM,UAAU;MAChB,8BAA8B,CAAC;MAC/B,IAAI;OACA,MAAM,0BAA0B,OAAO;MAC3C,SAAS,YAAqB;OAC1B,QAAQ,KACJ,8CAA8C,WAAW,IACzD,UACJ;OACA;MACJ;KACJ;KACA,MAAM;IACV,CAAC,CAAC,CACD,cAAc;KACX,kBAAkB,KAAA;KAClB,IAAI,wBAAwB,CAAC,UACzB,oBAAoB;IAE5B,CAAC;IACL,OAAO;GACX;GAEA,kCAAkC;IAC9B,IAAI,wBACA;IAGJ,mBAAmB;IACnB,IAAI,aAAa;IAEjB,MAAM,eAAe;IACrB,eAAe,YAAY;KACvB,IAAI,cAAc,MAAM;KACxB,OAAO,oBAAoB,CAAC,UAAU;MAClC,mBAAmB;MACnB,MAAM,uBAAuB;KACjC;IACJ,EAAA,CAAG,CAAC,CACC,OAAO,UAAmB;KACvB,4BAA4B,KAAK;IACrC,CAAC,CAAC,CACD,cAAc;KACX,cAAc,KAAA;KACd,IAAI,oBAAoB,CAAC,UACrB,4BAA4B;IAEpC,CAAC;GACT;GAEA,MAAM,aAAa,OAAO,SAA2C;IACjE,MAAM,UAAU,MAAM,oBAClB,QACA,YACA,oBACA,MACA,YACJ;IACA,IAAI,QAAQ,SAAS,GAAG;KACpB,MAAM;KACN,KAAK,MAAM,UAAU,SACjB,aAAa,MAAM;KAEvB,MAAM,UAAU,OAAO,KAAK,MAAM;KAClC,IAAI,YAAY,MAAM,MAAM;IAChC;GACJ;GAEA,MAAM,mBAAmB,IAAI,uBAAuB,EAAE,WAAW,CAAC;GAClE,MAAM,cAAc,OACd,2BAA2B,MAAM,CAAC,CAAC,UAAU;IAAE,MAAM;IAAQ;GAAW,IAAI,YAAY;IACpF,QAAQ,QAAQ,MAAhB;KACI,KAAK;MACD,IAAI,iBACA,4BAA4B,KAAK,GAAG,QAAQ,OAAO;WAChD,IAAI,wBACP,0BAA+B,QAAQ,OAAO,CAAC,CAAC,OAAO,UAAmB;OACtE,QAAQ,KACJ,8CAA8C,WAAW,IACzD,KACJ;OACA,oBAAoB;MACxB,CAAC;WACE;OACH,4BAA4B,KAAK,GAAG,QAAQ,OAAO;OACnD,4BAA4B;MAChC;MACA;KAEJ,KAAK;MACD,IAAI,wBACA,oBAAoB;WAEpB,4BAA4B;MAEhC;KAEJ,KAAK;MACD,IAAI,QAAQ,WAAW,QAAQ;MAC/B,IAAI,wBACA,oBAAoB;WAEpB,4BAA4B;IAIxC;GACJ,CAAC,UACK,CAAC;GAOb,IAAI,kBAAkB,MAClB,UAAU;QAEV,cAAmB,KAAK,WAAW,SAAS;GAGhD,OAAO;IACH,YAAY,iBAAiB;IAC7B,eAAe;KACX,WAAW;KACX,4BAA4B,KAAA;KAC5B,qBAAqB,KAAA;KACrB,aAAa,eAAe,IAAI;KAChC,YAAY;KACZ,iBAAiB,MAAM;IAC3B;GACJ;EACJ,EAGQ;EAAG,OAAA;GA7awB;GAAkB;EA6atC;CAAE;AACzB;AA0CA,SAAgB,wBAAwB,QAAkB;CACtD,MAAM,EACF,QACA,YACA,oBACA,oBACA,MACA,cACA,kBACA,QACA,GAAG,SACH;CAIJ,MAAM,EAAE,MAAM,UAAU,iBACpB,QACA,YACA,oBACA,oBACA,cACA,kBACA,IACJ;CAEA,IAAI,WAAW,KAAA,GACX,OAAO;EAAE,UAAU;EAAsB;EAAM;CAAM;CAGzD,OAAO;EACH,GAAG;EACH;EACA,kBAAkB;EAClB,WAAW;EACX,UAAU;EACV,SAAS,WACJ,OAA2C;EAChD;EACA;CACJ;AACJ"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { createFoundryBackendInstallation, createFoundryOntologyRoute };
|
|
1
|
+
export { createFoundryBackendInstallation, createFoundryOntologyRoute } from "./createFoundryBackendInstallation.js";
|
|
@@ -21,4 +21,5 @@ export declare function objectTypeCollectionOptions(metadata: MetaEntityCollecti
|
|
|
21
21
|
export declare function valueTypeCollectionOptions(metadata: MetaEntityCollection): OntologyCollectionOptions;
|
|
22
22
|
export declare function linkTypeCollectionOptions(metadata: MetaEntityCollection): OntologyCollectionOptions;
|
|
23
23
|
//#endregion
|
|
24
|
+
export {};
|
|
24
25
|
//# sourceMappingURL=entityCollectionOptions.d.ts.map
|
|
@@ -10,4 +10,5 @@ export interface ActionTypeOmsMetadata {
|
|
|
10
10
|
}
|
|
11
11
|
export declare function loadActionTypeOmsMetadata(client: OntologyClient, actionTypeRids: string[]): Promise<Map<string, ActionTypeOmsMetadata>>;
|
|
12
12
|
//#endregion
|
|
13
|
+
export {};
|
|
13
14
|
//# sourceMappingURL=loadActionTypeOmsMetadata.d.ts.map
|
|
@@ -21,4 +21,5 @@ export declare function userCollectionOptions({ client, lens }: UserCollectionOp
|
|
|
21
21
|
};
|
|
22
22
|
export declare function convertQuery(options: LoadSubsetOptions | undefined, lens: Lens): UsersQuery;
|
|
23
23
|
//#endregion
|
|
24
|
+
export {};
|
|
24
25
|
//# sourceMappingURL=userCollectionOptions.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@party-stack/foundry-ontology",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"lib"
|
|
6
6
|
],
|
|
@@ -36,31 +36,31 @@
|
|
|
36
36
|
"effection": "^4.0.2",
|
|
37
37
|
"temporal-polyfill": "^0.3.0",
|
|
38
38
|
"zod": "^4.4.3",
|
|
39
|
+
"@party-stack/connections": "0.3.2",
|
|
39
40
|
"@party-stack/errors": "0.2.1",
|
|
40
|
-
"@party-stack/connections": "0.3.1",
|
|
41
41
|
"@party-stack/foundry-client": "0.3.1",
|
|
42
42
|
"@party-stack/foundry-object-set-watcher": "0.5.2",
|
|
43
43
|
"@party-stack/icons-blueprint": "0.2.1",
|
|
44
|
-
"@party-stack/oauth": "0.3.
|
|
45
|
-
"@party-stack/ontology": "0.
|
|
46
|
-
"@party-stack/runtime": "0.4.
|
|
44
|
+
"@party-stack/oauth": "0.3.2",
|
|
45
|
+
"@party-stack/ontology": "0.20.0",
|
|
46
|
+
"@party-stack/runtime": "0.4.2"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@tanstack/db": "0.
|
|
50
|
-
"@tanstack/query-db-collection": "1.4.
|
|
49
|
+
"@tanstack/db": "0.14.0",
|
|
50
|
+
"@tanstack/query-db-collection": "1.4.4",
|
|
51
51
|
"@types/node": "^24.10.1",
|
|
52
52
|
"@types/react": "^19.3.0",
|
|
53
53
|
"react": "^19.3.0",
|
|
54
54
|
"ts-node": "^10.9.2",
|
|
55
55
|
"tsx": "^4.20.6",
|
|
56
56
|
"typescript": "~7.0.2",
|
|
57
|
-
"vite-plus": "1.
|
|
58
|
-
"@party-stack/build-config": "0.1.
|
|
57
|
+
"vite-plus": "1.2.0",
|
|
58
|
+
"@party-stack/build-config": "0.1.3"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@tanstack/db": "0.
|
|
61
|
+
"@tanstack/db": "0.14.0",
|
|
62
62
|
"@tanstack/query-core": "^5.102.8",
|
|
63
|
-
"@tanstack/query-db-collection": "1.4.
|
|
63
|
+
"@tanstack/query-db-collection": "1.4.4",
|
|
64
64
|
"react": "^18.0.0 || ^19.0.0"
|
|
65
65
|
}
|
|
66
66
|
}
|