@anfenn/dync 1.0.32 → 1.1.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/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as DyncOptions, S as SyncStatus, a as SyncApi, T as TableMap } from './types-BszcepJK.cjs';
2
- export { A as AfterRemoteAddCallback, c as ApiFunctions, f as BatchFirstLoadResult, d as BatchPushPayload, e as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, F as FirstLoadProgress, g as FirstLoadProgressCallback, h as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, i as MutationEvent, b as SyncAction, j as SyncOptions, k as SyncState, l as SyncedRecord } from './types-BszcepJK.cjs';
1
+ import { D as DyncOptions, S as SyncStatus, a as SyncApi, T as TableMap } from './types-DhCTdAep.cjs';
2
+ export { A as AfterRemoteAddCallback, e as BatchFirstLoadResult, c as BatchPushPayload, d as BatchPushResult, B as BatchSync, f as ConflictResolutionStrategy, C as CrudSyncApi, F as FirstLoadProgress, g as FirstLoadProgressCallback, h as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, i as MutationEvent, b as SyncAction, j as SyncOptions, k as SyncState, l as SyncedRecord } from './types-DhCTdAep.cjs';
3
3
  import { T as TableSchemaDefinition, D as DexieQueryContext, S as SQLiteQueryContext, M as MemoryQueryContext, a as StorageTable } from './dexie-3VOQSn1s.cjs';
4
4
  export { b as MemoryAdapter, c as SQLiteAdapter, d as StorageAdapter } from './dexie-3VOQSn1s.cjs';
5
5
  import { c as SQLiteVersionMigration } from './types-6-NyRQ0D.cjs';
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { D as DyncOptions, S as SyncStatus, a as SyncApi, T as TableMap } from './types-Dhx9MuUp.js';
2
- export { A as AfterRemoteAddCallback, c as ApiFunctions, f as BatchFirstLoadResult, d as BatchPushPayload, e as BatchPushResult, B as BatchSync, C as ConflictResolutionStrategy, F as FirstLoadProgress, g as FirstLoadProgressCallback, h as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, i as MutationEvent, b as SyncAction, j as SyncOptions, k as SyncState, l as SyncedRecord } from './types-Dhx9MuUp.js';
1
+ import { D as DyncOptions, S as SyncStatus, a as SyncApi, T as TableMap } from './types-BIJhsSOf.js';
2
+ export { A as AfterRemoteAddCallback, e as BatchFirstLoadResult, c as BatchPushPayload, d as BatchPushResult, B as BatchSync, f as ConflictResolutionStrategy, C as CrudSyncApi, F as FirstLoadProgress, g as FirstLoadProgressCallback, h as MissingRemoteRecordDuringUpdateCallback, M as MissingRemoteRecordStrategy, i as MutationEvent, b as SyncAction, j as SyncOptions, k as SyncState, l as SyncedRecord } from './types-BIJhsSOf.js';
3
3
  import { T as TableSchemaDefinition, D as DexieQueryContext, S as SQLiteQueryContext, M as MemoryQueryContext, a as StorageTable } from './dexie-D85rTx4g.js';
4
4
  export { b as MemoryAdapter, c as SQLiteAdapter, d as StorageAdapter } from './dexie-D85rTx4g.js';
5
5
  import { c as SQLiteVersionMigration } from './types-6-NyRQ0D.js';
package/dist/index.js CHANGED
@@ -139,7 +139,7 @@ var SYNC_STATE_KEY = "sync_state";
139
139
  var DEFAULT_STATE = {
140
140
  firstLoadDone: false,
141
141
  pendingChanges: [],
142
- lastPulled: {}
142
+ newestServerUpdatedAt: {}
143
143
  };
144
144
  var StateManager = class {
145
145
  persistedState;
@@ -309,7 +309,8 @@ function clonePersistedState(state) {
309
309
  before: cloneRecord(change.before),
310
310
  after: cloneRecord(change.after)
311
311
  })),
312
- lastPulled: { ...state.lastPulled },
312
+ newestServerUpdatedAt: { ...state.newestServerUpdatedAt },
313
+ lastPulledAt: state.lastPulledAt ? { ...state.lastPulledAt } : void 0,
313
314
  conflicts: cloneConflicts(state.conflicts)
314
315
  };
315
316
  }
@@ -708,12 +709,25 @@ async function pullAll(ctx) {
708
709
  const changedTables = [];
709
710
  for (const [tableName, api] of Object.entries(ctx.syncApis)) {
710
711
  try {
711
- const lastPulled = ctx.state.getState().lastPulled[tableName];
712
- const since = lastPulled ? new Date(lastPulled) : /* @__PURE__ */ new Date(0);
712
+ const now = Date.now();
713
+ if (beforeListExtraInterval(api, tableName, ctx, now)) {
714
+ continue;
715
+ }
716
+ const newestServerUpdatedAt = ctx.state.getState().newestServerUpdatedAt[tableName];
717
+ const since = newestServerUpdatedAt ? new Date(newestServerUpdatedAt) : /* @__PURE__ */ new Date(0);
713
718
  ctx.logger.debug(`[dync] pull:start tableName=${tableName} since=${since.toISOString()}`);
714
719
  const serverData = await api.list(since);
715
720
  const changed = await processPullData(tableName, serverData, since, ctx);
716
721
  if (changed) changedTables.push(tableName);
722
+ if (hasListExtraInterval(api)) {
723
+ await ctx.state.setState((syncState) => ({
724
+ ...syncState,
725
+ lastPulledAt: {
726
+ ...syncState.lastPulledAt,
727
+ [tableName]: now
728
+ }
729
+ }));
730
+ }
717
731
  } catch (err) {
718
732
  firstSyncError = firstSyncError ?? err;
719
733
  ctx.logger.error(`[dync] pull:error tableName=${tableName}`, err);
@@ -721,6 +735,22 @@ async function pullAll(ctx) {
721
735
  }
722
736
  return { error: firstSyncError, changedTables };
723
737
  }
738
+ function hasListExtraInterval(api) {
739
+ return Number.isFinite(api.listExtraIntervalMs) && api.listExtraIntervalMs > 0;
740
+ }
741
+ function beforeListExtraInterval(api, tableName, ctx, now) {
742
+ if (!hasListExtraInterval(api)) {
743
+ return false;
744
+ }
745
+ const lastPulledAt = ctx.state.getState().lastPulledAt?.[tableName] ?? 0;
746
+ if (now - lastPulledAt < api.listExtraIntervalMs) {
747
+ ctx.logger.debug(
748
+ `[dync] pull:skip-interval tableName=${tableName} lastPulledAt=${new Date(lastPulledAt).toISOString()} nextAllowed=${new Date(lastPulledAt + api.listExtraIntervalMs).toISOString()}`
749
+ );
750
+ return true;
751
+ }
752
+ return false;
753
+ }
724
754
  async function handleRemoteItemUpdate(table, tableName, localItem, remote, ctx) {
725
755
  const pendingChange = ctx.state.getState().pendingChanges.find((p) => p.tableName === tableName && p.localId === localItem._localId);
726
756
  const conflictStrategy = ctx.conflictResolutionStrategy;
@@ -777,8 +807,8 @@ async function pullAllBatch(ctx) {
777
807
  try {
778
808
  const sinceMap = {};
779
809
  for (const tableName of ctx.batchSync.syncTables) {
780
- const lastPulled = ctx.state.getState().lastPulled[tableName];
781
- sinceMap[tableName] = lastPulled ? new Date(lastPulled) : /* @__PURE__ */ new Date(0);
810
+ const newestServerUpdatedAt = ctx.state.getState().newestServerUpdatedAt[tableName];
811
+ sinceMap[tableName] = newestServerUpdatedAt ? new Date(newestServerUpdatedAt) : /* @__PURE__ */ new Date(0);
782
812
  }
783
813
  ctx.logger.debug(`[dync] pull:batch:start tables=${[...ctx.batchSync.syncTables].join(",")}`, sinceMap);
784
814
  const serverDataByTable = await ctx.batchSync.pull(sinceMap);
@@ -840,8 +870,8 @@ async function processPullData(tableName, serverData, since, ctx) {
840
870
  }
841
871
  await ctx.state.setState((syncState) => ({
842
872
  ...syncState,
843
- lastPulled: {
844
- ...syncState.lastPulled,
873
+ newestServerUpdatedAt: {
874
+ ...syncState.newestServerUpdatedAt,
845
875
  [tableName]: newest.toISOString()
846
876
  }
847
877
  }));
@@ -1123,7 +1153,7 @@ async function startFirstLoad(ctx) {
1123
1153
  ctx.logger.debug("[dync] First load completed");
1124
1154
  }
1125
1155
  async function processBatchInChunks(ctx, tableName, batch, isEmptyTable, isFirstBatch) {
1126
- let newest = new Date(ctx.state.getState().lastPulled[tableName] || 0);
1156
+ let newest = new Date(ctx.state.getState().newestServerUpdatedAt[tableName] || 0);
1127
1157
  return ctx.withTransaction("rw", [tableName, DYNC_STATE_TABLE], async (tables) => {
1128
1158
  const txTable = tables[tableName];
1129
1159
  let tableIsEmpty = isEmptyTable;
@@ -1158,8 +1188,8 @@ async function processBatchInChunks(ctx, tableName, batch, isEmptyTable, isFirst
1158
1188
  }
1159
1189
  await ctx.state.setState((syncState) => ({
1160
1190
  ...syncState,
1161
- lastPulled: {
1162
- ...syncState.lastPulled,
1191
+ newestServerUpdatedAt: {
1192
+ ...syncState.newestServerUpdatedAt,
1163
1193
  [tableName]: newest.toISOString()
1164
1194
  }
1165
1195
  }));
@@ -1333,7 +1363,7 @@ var DyncBase = class {
1333
1363
  this.adapter = storageAdapter;
1334
1364
  this.name = databaseName;
1335
1365
  this.syncOptions = {
1336
- syncInterval: DEFAULT_SYNC_INTERVAL_MILLIS,
1366
+ syncIntervalMs: DEFAULT_SYNC_INTERVAL_MILLIS,
1337
1367
  logger: DEFAULT_LOGGER,
1338
1368
  minLogLevel: DEFAULT_MIN_LOG_LEVEL,
1339
1369
  missingRemoteRecordDuringUpdateStrategy: DEFAULT_MISSING_REMOTE_RECORD_STRATEGY,
@@ -1584,7 +1614,8 @@ var DyncBase = class {
1584
1614
  }
1585
1615
  return pullAll({
1586
1616
  ...baseContext,
1587
- syncApis: this.syncApis
1617
+ syncApis: this.syncApis,
1618
+ syncIntervalMs: this.syncOptions.syncIntervalMs
1588
1619
  });
1589
1620
  }
1590
1621
  async pushAll() {
@@ -1619,7 +1650,7 @@ var DyncBase = class {
1619
1650
  while (this.syncTimerStarted) {
1620
1651
  this.sleepAbortController = new AbortController();
1621
1652
  await this.syncOnce();
1622
- await sleep(this.syncOptions.syncInterval, this.sleepAbortController.signal);
1653
+ await sleep(this.syncOptions.syncIntervalMs, this.sleepAbortController.signal);
1623
1654
  }
1624
1655
  this.syncStatus = "disabled";
1625
1656
  this.disableSyncPromiseResolver?.();