korajs 1.0.0-beta.10 → 1.0.0-beta.11

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.cjs CHANGED
@@ -1317,6 +1317,7 @@ function createSyncQuerySubscriptionHook(getSyncEngine) {
1317
1317
  // src/initialize-app.ts
1318
1318
  async function initializeApp(config, emitter, mergeEngine) {
1319
1319
  const adapterType = config.store?.adapter ?? detectAdapterType();
1320
+ let effectiveAdapterType = adapterType;
1320
1321
  const baseDbName = config.store?.name ?? "kora-db";
1321
1322
  const authBinding = config.sync?.authClient ?? null;
1322
1323
  const authUserId = config.store?.namespaceByAuthUser && authBinding?.resolveUserId ? await authBinding.resolveUserId() : void 0;
@@ -1357,6 +1358,7 @@ async function initializeApp(config, emitter, mergeEngine) {
1357
1358
  emitter,
1358
1359
  config.store?.workerResponseTimeoutMs
1359
1360
  );
1361
+ effectiveAdapterType = "indexeddb";
1360
1362
  store = buildStore(adapter);
1361
1363
  await store.open();
1362
1364
  emitter.emit({
@@ -1368,6 +1370,7 @@ async function initializeApp(config, emitter, mergeEngine) {
1368
1370
  message: `OPFS persistence is unavailable (${fallbackReason}) for database "${dbName}"; Kora is using durable IndexedDB instead.`
1369
1371
  });
1370
1372
  } catch {
1373
+ effectiveAdapterType = "sqlite-wasm";
1371
1374
  adapter = await createAdapter(
1372
1375
  "sqlite-wasm",
1373
1376
  dbName,
@@ -1413,6 +1416,8 @@ async function initializeApp(config, emitter, mergeEngine) {
1413
1416
  url: config.sync.url,
1414
1417
  transport: config.sync.transport,
1415
1418
  auth: syncAuth,
1419
+ authState: authBinding?.resolveSyncState,
1420
+ querySubsets: config.sync.querySubsets,
1416
1421
  batchSize: config.sync.batchSize,
1417
1422
  schemaVersion: config.sync.schemaVersion ?? config.schema.version,
1418
1423
  scopeMap,
@@ -1449,7 +1454,15 @@ async function initializeApp(config, emitter, mergeEngine) {
1449
1454
  unsubscribeLocalOperations,
1450
1455
  authBinding,
1451
1456
  blobStore,
1452
- blobChunkProvider
1457
+ blobChunkProvider,
1458
+ storeInfo: {
1459
+ baseName: baseDbName,
1460
+ databaseName: dbName,
1461
+ authUserId: authUserId ?? null,
1462
+ persistence: effectiveAdapterType,
1463
+ durable: adapter.getStorageOpenState?.()?.persistent ?? adapterType !== "sqlite-wasm",
1464
+ isolationState: "ready"
1465
+ }
1453
1466
  };
1454
1467
  }
1455
1468
  function emitOpfsUnavailable(emitter, dbName, reason) {
@@ -1573,6 +1586,66 @@ function createSyncControl(options) {
1573
1586
  state.syncStatusBridge?.refresh();
1574
1587
  }
1575
1588
  },
1589
+ async setQuerySubsets(subsets) {
1590
+ await ready;
1591
+ state.syncEngine?.setQuerySubsets(subsets);
1592
+ },
1593
+ async waitForSettled(options2 = {}) {
1594
+ await ready;
1595
+ const upload = options2.upload ?? true;
1596
+ const download = options2.download ?? "active-view";
1597
+ const classify = () => {
1598
+ const status = state.syncEngine?.getStatus() ?? offlineSyncStatus();
1599
+ if (status.phase === "suspended")
1600
+ return { outcome: "suspended", reason: status.reason ?? "suspended", status };
1601
+ if (status.blockedFailure)
1602
+ return { outcome: "blocked", failure: status.blockedFailure, status };
1603
+ if (status.phase === "offline") return { outcome: "offline", status };
1604
+ const uploadDone = !upload || status.pendingOperations === 0 && (status.inFlightUploadOperations ?? 0) === 0;
1605
+ const downloadDone = download === false || status.activeViewComplete;
1606
+ return uploadDone && downloadDone ? { outcome: "settled", status } : null;
1607
+ };
1608
+ return await new Promise((resolve) => {
1609
+ let done = false;
1610
+ let unsubscribeReady = false;
1611
+ let cleanupPending = false;
1612
+ let timer = null;
1613
+ let unsubscribe = () => {
1614
+ };
1615
+ const finish = (result) => {
1616
+ if (done) return;
1617
+ done = true;
1618
+ if (unsubscribeReady) unsubscribe();
1619
+ else cleanupPending = true;
1620
+ if (timer) clearTimeout(timer);
1621
+ options2.signal?.removeEventListener("abort", onAbort);
1622
+ resolve(result);
1623
+ };
1624
+ const check = () => {
1625
+ const result = classify();
1626
+ if (result) finish(result);
1627
+ };
1628
+ const onAbort = () => finish({
1629
+ outcome: "aborted",
1630
+ status: state.syncEngine?.getStatus() ?? offlineSyncStatus()
1631
+ });
1632
+ unsubscribe = state.syncStatusBridge?.subscribe(check) ?? (() => {
1633
+ });
1634
+ unsubscribeReady = true;
1635
+ if (cleanupPending) unsubscribe();
1636
+ options2.signal?.addEventListener("abort", onAbort, { once: true });
1637
+ if (options2.timeoutMs !== void 0)
1638
+ timer = setTimeout(
1639
+ () => finish({
1640
+ outcome: "timeout",
1641
+ status: state.syncEngine?.getStatus() ?? offlineSyncStatus()
1642
+ }),
1643
+ options2.timeoutMs
1644
+ );
1645
+ if (options2.signal?.aborted) onAbort();
1646
+ else check();
1647
+ });
1648
+ },
1576
1649
  getStatus() {
1577
1650
  if (state.syncEngine) {
1578
1651
  return state.syncEngine.getStatus();
@@ -1609,13 +1682,22 @@ function createSyncControl(options) {
1609
1682
  state: "disconnected",
1610
1683
  status: {
1611
1684
  status: "offline",
1685
+ phase: "offline",
1612
1686
  reconnecting: false,
1613
1687
  pendingOperations: 0,
1614
1688
  lastSyncedAt: null,
1615
1689
  lastSuccessfulPush: null,
1616
1690
  lastSuccessfulPull: null,
1617
1691
  conflicts: 0,
1618
- clockSkewMs: null
1692
+ clockSkewMs: null,
1693
+ inFlightUploadOperations: 0,
1694
+ hasInFlightDeliveryBatch: false,
1695
+ activeViewId: "",
1696
+ activeViewComplete: false,
1697
+ initialSync: { complete: false, receivedBatches: 0, totalBatches: null, progress: null },
1698
+ deliveryWatermark: 0,
1699
+ serverFrontier: null,
1700
+ blockedFailure: null
1619
1701
  },
1620
1702
  nodeId: "",
1621
1703
  url: config.sync?.url ?? "",
@@ -1675,8 +1757,15 @@ var AuthSyncCoordinator = class {
1675
1757
  if (!engine) {
1676
1758
  return;
1677
1759
  }
1760
+ engine.notifyAuthChanged?.();
1761
+ const authState = await this.authBinding.resolveSyncState?.();
1762
+ if (authState?.state === "loading" || authState?.state === "signed-out") {
1763
+ await engine.stop();
1764
+ await engine.start();
1765
+ return;
1766
+ }
1678
1767
  const headers = await this.authBinding.auth();
1679
- if (!headers.token) {
1768
+ if (!headers.token && authState?.state !== "anonymous") {
1680
1769
  await engine.stop();
1681
1770
  return;
1682
1771
  }
@@ -1952,6 +2041,14 @@ function createApp(config) {
1952
2041
  let unsubscribeSync = null;
1953
2042
  let unsubscribeAudit = null;
1954
2043
  let unsubscribeLocalOperations = null;
2044
+ let currentStoreInfo = {
2045
+ baseName: config.store?.name ?? "kora-db",
2046
+ databaseName: "",
2047
+ authUserId: null,
2048
+ persistence: config.store?.adapter ?? "sqlite-wasm",
2049
+ durable: false,
2050
+ isolationState: "closed"
2051
+ };
1955
2052
  const syncState = {
1956
2053
  syncEngine: null,
1957
2054
  syncStatusBridge: null,
@@ -1975,6 +2072,7 @@ function createApp(config) {
1975
2072
  config.blob?.chunkSize,
1976
2073
  () => enumerateLiveBlobRefs(init.store, config.schema)
1977
2074
  );
2075
+ currentStoreInfo = init.storeInfo;
1978
2076
  wireSyncLifecycleAfterReady(config, emitter, syncState, init);
1979
2077
  });
1980
2078
  const getStore = () => store;
@@ -2031,6 +2129,9 @@ function createApp(config) {
2031
2129
  getQueryStoreCache() {
2032
2130
  return queryStoreCache;
2033
2131
  },
2132
+ storeInfo() {
2133
+ return { ...currentStoreInfo };
2134
+ },
2034
2135
  transaction(fn) {
2035
2136
  return executeTransaction(fn);
2036
2137
  },
@@ -2064,6 +2165,7 @@ function createApp(config) {
2064
2165
  await store.close();
2065
2166
  store = null;
2066
2167
  }
2168
+ currentStoreInfo = { ...currentStoreInfo, isolationState: "closed" };
2067
2169
  emitter.clear();
2068
2170
  },
2069
2171
  async exportBackup(options) {