@foretag/tanstack-db-surrealdb 0.6.3 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -192,6 +192,44 @@ var toNativeRecordIdLikeValue = (value) => {
192
192
  }
193
193
  return getNativeRecordId(canonical);
194
194
  };
195
+ var preferRecordIdLikeIdentity = (value) => {
196
+ const canonical = asCanonicalRecordIdString(value);
197
+ if (!canonical) return normalizeRecordIdLikeValue(value);
198
+ if (value instanceof surrealdb.RecordId) {
199
+ recordIdIdentityPool.set(canonical, value);
200
+ return value;
201
+ }
202
+ if (isCrossRuntimeRecordIdObject(value)) {
203
+ recordIdIdentityPool.set(canonical, value);
204
+ return value;
205
+ }
206
+ const wrappedId = unwrapIdWrapper(value);
207
+ if (wrappedId instanceof surrealdb.RecordId) {
208
+ recordIdIdentityPool.set(canonical, wrappedId);
209
+ return wrappedId;
210
+ }
211
+ if (isCrossRuntimeRecordIdObject(wrappedId)) {
212
+ recordIdIdentityPool.set(canonical, wrappedId);
213
+ return wrappedId;
214
+ }
215
+ return internRecordIdIdentity(canonical);
216
+ };
217
+ var preferRecordIdLikeIdentityDeep = (value) => {
218
+ const preferred = preferRecordIdLikeIdentity(value);
219
+ if (Array.isArray(preferred)) {
220
+ return preferred.map(
221
+ (item) => preferRecordIdLikeIdentityDeep(item)
222
+ );
223
+ }
224
+ if (isPlainObject(preferred)) {
225
+ const out = {};
226
+ for (const [k, v] of Object.entries(preferred)) {
227
+ out[k] = preferRecordIdLikeIdentityDeep(v);
228
+ }
229
+ return out;
230
+ }
231
+ return preferred;
232
+ };
195
233
  var normalizeRecordIdLikeValue = (value) => {
196
234
  if (value instanceof surrealdb.RecordId) {
197
235
  const canonical2 = asCanonicalRecordIdString(value);
@@ -718,6 +756,100 @@ var subsetCacheKey = (subset) => {
718
756
  return value;
719
757
  }) ?? "";
720
758
  };
759
+ var isPlainObject2 = (value) => typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
760
+ var normalizeSubsetValuesInPlace = (value, seen = /* @__PURE__ */ new WeakSet(), preferredByCanonical = /* @__PURE__ */ new Map()) => {
761
+ if (Array.isArray(value)) {
762
+ for (const entry of value) {
763
+ normalizeSubsetValuesInPlace(entry, seen, preferredByCanonical);
764
+ }
765
+ return preferredByCanonical;
766
+ }
767
+ if (!value || typeof value !== "object") return preferredByCanonical;
768
+ if (seen.has(value)) return preferredByCanonical;
769
+ seen.add(value);
770
+ const obj = value;
771
+ if (obj.type === "val" && "value" in obj) {
772
+ const canonical = asCanonicalRecordIdString(obj.value);
773
+ if (canonical) {
774
+ const preferred = preferRecordIdLikeIdentity(obj.value);
775
+ obj.value = preferred;
776
+ preferredByCanonical.set(canonical, preferred);
777
+ } else {
778
+ obj.value = preferRecordIdLikeIdentityDeep(obj.value);
779
+ }
780
+ }
781
+ for (const child of Object.values(obj)) {
782
+ normalizeSubsetValuesInPlace(child, seen, preferredByCanonical);
783
+ }
784
+ return preferredByCanonical;
785
+ };
786
+ var primeRecordIdIdentityFromSubset = (subset) => {
787
+ if (!subset) return /* @__PURE__ */ new Map();
788
+ return normalizeSubsetValuesInPlace(subset);
789
+ };
790
+ var rebindRecordIdIdentityDeep = (value, preferredByCanonical) => {
791
+ const canonical = asCanonicalRecordIdString(value);
792
+ if (canonical && preferredByCanonical.has(canonical)) {
793
+ const preferred = preferredByCanonical.get(canonical);
794
+ return {
795
+ value: preferred,
796
+ changed: value !== preferred
797
+ };
798
+ }
799
+ if (Array.isArray(value)) {
800
+ let changed2 = false;
801
+ const out2 = value.map((entry) => {
802
+ const rebound = rebindRecordIdIdentityDeep(
803
+ entry,
804
+ preferredByCanonical
805
+ );
806
+ changed2 = changed2 || rebound.changed;
807
+ return rebound.value;
808
+ });
809
+ return changed2 ? { value: out2, changed: true } : { value, changed: false };
810
+ }
811
+ if (!isPlainObject2(value)) return { value, changed: false };
812
+ let changed = false;
813
+ const out = {};
814
+ for (const [key, entry] of Object.entries(value)) {
815
+ const rebound = rebindRecordIdIdentityDeep(entry, preferredByCanonical);
816
+ if (rebound.changed) changed = true;
817
+ out[key] = rebound.value;
818
+ }
819
+ return changed ? { value: out, changed: true } : { value, changed: false };
820
+ };
821
+ var applyPreferredRecordIdIdentityToCollection = (ctx, preferredByCanonical) => {
822
+ if (!preferredByCanonical.size) return;
823
+ const collection = ctx.collection;
824
+ if (!collection || typeof collection.entries !== "function") return;
825
+ const rebound = [];
826
+ for (const [, row] of collection.entries()) {
827
+ const updated = rebindRecordIdIdentityDeep(row, preferredByCanonical);
828
+ if (!updated.changed) continue;
829
+ rebound.push(updated.value);
830
+ }
831
+ if (!rebound.length) return;
832
+ ctx.begin();
833
+ try {
834
+ for (const row of rebound) {
835
+ ctx.write({
836
+ type: "delete",
837
+ value: { id: row.id }
838
+ });
839
+ ctx.write({ type: "insert", value: row });
840
+ }
841
+ } finally {
842
+ ctx.commit();
843
+ }
844
+ const collectionWithInternals = collection;
845
+ const entries = collectionWithInternals._state?.entries?.();
846
+ const indexes = collectionWithInternals._indexes?.indexes;
847
+ if (entries && indexes) {
848
+ for (const index of indexes.values()) {
849
+ index.build?.(entries);
850
+ }
851
+ }
852
+ };
721
853
  function modernSurrealCollectionOptions(config) {
722
854
  const {
723
855
  db,
@@ -735,7 +867,8 @@ function modernSurrealCollectionOptions(config) {
735
867
  const syncMode = syncModeFrom(inputSyncMode);
736
868
  const isOnDemandLike = syncMode === "on-demand" || syncMode === "progressive";
737
869
  const isStrictOnDemand = syncMode === "on-demand";
738
- const queryDrivenSyncMode = isOnDemandLike ? "on-demand" : "eager";
870
+ const queryDrivenSyncMode = "on-demand";
871
+ const queryDrivenUsesSubsets = queryDrivenSyncMode === "on-demand";
739
872
  const tableOptions = toTableOptions(table);
740
873
  const tableName = tableOptions.name;
741
874
  const tableResource = toTableResource(table);
@@ -1028,7 +1161,8 @@ function modernSurrealCollectionOptions(config) {
1028
1161
  };
1029
1162
  };
1030
1163
  const loadSubset = async (subset) => {
1031
- if (!isOnDemandLike) return;
1164
+ const preferredFromSubset = primeRecordIdIdentityFromSubset(subset);
1165
+ applyPreferredRecordIdIdentityToCollection(ctx, preferredFromSubset);
1032
1166
  const key = subsetCacheKey(subset);
1033
1167
  const rows = await tableAccess.loadSubset(subset);
1034
1168
  const ids = new Set(
@@ -1061,7 +1195,7 @@ function modernSurrealCollectionOptions(config) {
1061
1195
  await ensureUpdateLive();
1062
1196
  };
1063
1197
  const unloadSubset = (subset) => {
1064
- if (!isOnDemandLike) return;
1198
+ primeRecordIdIdentityFromSubset(subset);
1065
1199
  const key = subsetCacheKey(subset);
1066
1200
  subsetIds.delete(key);
1067
1201
  updateActiveOnDemandIds();
@@ -1099,21 +1233,12 @@ function modernSurrealCollectionOptions(config) {
1099
1233
  syncMode: queryDrivenSyncMode,
1100
1234
  queryFn: async ({ meta }) => {
1101
1235
  try {
1102
- if (isOnDemandLike && !meta?.loadSubsetOptions) {
1236
+ primeRecordIdIdentityFromSubset(meta?.loadSubsetOptions);
1237
+ if (queryDrivenUsesSubsets && !meta?.loadSubsetOptions) {
1103
1238
  return [];
1104
1239
  }
1105
1240
  if (!crdtEnabled) {
1106
- if (!isOnDemandLike) {
1107
- const rows2 = await toRecordArray(
1108
- await db.select(tableResource)
1109
- );
1110
- const decoded2 = await Promise.all(
1111
- rows2.map(
1112
- (row) => decodeBaseRow(row)
1113
- )
1114
- );
1115
- return decoded2;
1116
- }
1241
+ if (!queryDrivenUsesSubsets) ;
1117
1242
  const rows = await tableAccess.loadSubset(
1118
1243
  meta?.loadSubsetOptions
1119
1244
  );
@@ -1124,7 +1249,7 @@ function modernSurrealCollectionOptions(config) {
1124
1249
  );
1125
1250
  return decoded;
1126
1251
  }
1127
- if (isOnDemandLike) return [];
1252
+ if (queryDrivenUsesSubsets) return [];
1128
1253
  if (!updatesTableName) return [];
1129
1254
  const updates = await queryRows(
1130
1255
  db,