@arcote.tech/arc-adapter-db-sqlite 0.7.15 → 0.7.16

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.
Files changed (2) hide show
  1. package/dist/index.js +196 -290
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1487,7 +1487,8 @@ class EventWire {
1487
1487
  onSyncedCallback;
1488
1488
  reconnectTimeout;
1489
1489
  syncRequested = false;
1490
- viewSubscriptions = new Map;
1490
+ querySubscriptions = new Map;
1491
+ querySubCounter = 0;
1491
1492
  enableEventSync;
1492
1493
  constructor(baseUrl, options) {
1493
1494
  this.baseUrl = baseUrl;
@@ -1542,7 +1543,7 @@ class EventWire {
1542
1543
  this.requestSync();
1543
1544
  }
1544
1545
  this.flushPendingEvents();
1545
- this.sendAllViewSubscriptions();
1546
+ this.sendAllQuerySubscriptions();
1546
1547
  } else {
1547
1548
  console.log(`[EventWire] onopen called but ws is not OPEN, readyState:`, this.ws?.readyState);
1548
1549
  }
@@ -1618,24 +1619,29 @@ class EventWire {
1618
1619
  onSynced(callback) {
1619
1620
  this.onSyncedCallback = callback;
1620
1621
  }
1621
- subscribeView(element, scope, callbacks) {
1622
- const key = `${scope}:${element}`;
1623
- this.viewSubscriptions.set(key, callbacks);
1622
+ subscribeQuery(descriptor, scope, callbacks) {
1623
+ const subscriptionId = `qs_${this.instanceId}_${++this.querySubCounter}`;
1624
+ this.querySubscriptions.set(subscriptionId, {
1625
+ descriptor,
1626
+ scope,
1627
+ callbacks
1628
+ });
1624
1629
  if (this.state === "connected" && this.ws) {
1625
1630
  this.ws.send(JSON.stringify({
1626
- type: "subscribe-view",
1627
- element,
1631
+ type: "subscribe-query",
1632
+ subscriptionId,
1633
+ descriptor,
1628
1634
  scope
1629
1635
  }));
1630
1636
  }
1637
+ return subscriptionId;
1631
1638
  }
1632
- unsubscribeView(element, scope) {
1633
- this.viewSubscriptions.delete(`${scope}:${element}`);
1639
+ unsubscribeQuery(subscriptionId) {
1640
+ this.querySubscriptions.delete(subscriptionId);
1634
1641
  if (this.state === "connected" && this.ws) {
1635
1642
  this.ws.send(JSON.stringify({
1636
- type: "unsubscribe-view",
1637
- element,
1638
- scope
1643
+ type: "unsubscribe-query",
1644
+ subscriptionId
1639
1645
  }));
1640
1646
  }
1641
1647
  }
@@ -1670,17 +1676,17 @@ class EventWire {
1670
1676
  this.lastHostEventId = message.lastHostEventId;
1671
1677
  }
1672
1678
  break;
1673
- case "view-snapshot": {
1674
- const sub = this.viewSubscriptions.get(`${message.scope}:${message.element}`);
1679
+ case "query-snapshot": {
1680
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1675
1681
  if (sub) {
1676
- sub.onSnapshot(message.items ?? []);
1682
+ sub.callbacks.onSnapshot(message.result ?? null);
1677
1683
  }
1678
1684
  break;
1679
1685
  }
1680
- case "view-changes": {
1681
- const sub = this.viewSubscriptions.get(`${message.scope}:${message.element}`);
1686
+ case "query-changes": {
1687
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1682
1688
  if (sub && Array.isArray(message.changes)) {
1683
- sub.onChanges(message.changes);
1689
+ sub.callbacks.onChanges(message.changes);
1684
1690
  }
1685
1691
  break;
1686
1692
  }
@@ -1708,17 +1714,15 @@ class EventWire {
1708
1714
  this.pendingEvents = [];
1709
1715
  }
1710
1716
  }
1711
- sendAllViewSubscriptions() {
1717
+ sendAllQuerySubscriptions() {
1712
1718
  if (!this.ws || this.state !== "connected")
1713
1719
  return;
1714
- for (const key of this.viewSubscriptions.keys()) {
1715
- const sepIdx = key.indexOf(":");
1716
- const scope = key.slice(0, sepIdx);
1717
- const element = key.slice(sepIdx + 1);
1720
+ for (const [subscriptionId, sub] of this.querySubscriptions) {
1718
1721
  this.ws.send(JSON.stringify({
1719
- type: "subscribe-view",
1720
- element,
1721
- scope
1722
+ type: "subscribe-query",
1723
+ subscriptionId,
1724
+ descriptor: sub.descriptor,
1725
+ scope: sub.scope
1722
1726
  }));
1723
1727
  }
1724
1728
  }
@@ -1742,19 +1746,12 @@ class LocalEventPublisher {
1742
1746
  views = [];
1743
1747
  syncCallback;
1744
1748
  subscribers = new Map;
1745
- viewChangesCallbacks = new Set;
1746
1749
  constructor(dataStorage) {
1747
1750
  this.dataStorage = dataStorage;
1748
1751
  }
1749
1752
  onPublish(callback) {
1750
1753
  this.syncCallback = callback;
1751
1754
  }
1752
- onViewChanges(callback) {
1753
- this.viewChangesCallbacks.add(callback);
1754
- return () => {
1755
- this.viewChangesCallbacks.delete(callback);
1756
- };
1757
- }
1758
1755
  registerViews(views) {
1759
1756
  this.views = views;
1760
1757
  }
@@ -1822,19 +1819,7 @@ class LocalEventPublisher {
1822
1819
  });
1823
1820
  const viewChanges = await this.collectViewChanges(event);
1824
1821
  allChanges.push(...viewChanges);
1825
- const viewStoreNames = new Set(viewChanges.map((c) => c.store));
1826
- const committed = await this.dataStorage.commitChanges(allChanges, {
1827
- captureRowsFor: viewStoreNames
1828
- });
1829
- if (committed.length > 0 && this.viewChangesCallbacks.size > 0) {
1830
- for (const callback of this.viewChangesCallbacks) {
1831
- try {
1832
- callback(committed);
1833
- } catch (error) {
1834
- console.error(`[EventPublisher] onViewChanges callback error:`, error);
1835
- }
1836
- }
1837
- }
1822
+ await this.dataStorage.commitChanges(allChanges);
1838
1823
  await this.notifySubscribers(event);
1839
1824
  if (this.syncCallback) {
1840
1825
  this.syncCallback(event);
@@ -2474,9 +2459,8 @@ class ArcObject extends ArcAbstract {
2474
2459
  }
2475
2460
  }
2476
2461
  class DataStorage {
2477
- async commitChanges(changes, _options) {
2462
+ async commitChanges(changes) {
2478
2463
  await Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applyChanges(changes2)));
2479
- return [];
2480
2464
  }
2481
2465
  }
2482
2466
 
@@ -3567,6 +3551,48 @@ function deepMerge(target, source) {
3567
3551
  function isPlainObject(item) {
3568
3552
  return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
3569
3553
  }
3554
+ function murmurHash(key, seed = 0) {
3555
+ let remainder, bytes, h1, h1b, c1, c2, k1, i;
3556
+ remainder = key.length & 3;
3557
+ bytes = key.length - remainder;
3558
+ h1 = seed;
3559
+ c1 = 3432918353;
3560
+ c2 = 461845907;
3561
+ i = 0;
3562
+ while (i < bytes) {
3563
+ k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
3564
+ ++i;
3565
+ k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
3566
+ k1 = k1 << 15 | k1 >>> 17;
3567
+ k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
3568
+ h1 ^= k1;
3569
+ h1 = h1 << 13 | h1 >>> 19;
3570
+ h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
3571
+ h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
3572
+ }
3573
+ k1 = 0;
3574
+ if (remainder >= 3) {
3575
+ k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
3576
+ }
3577
+ if (remainder >= 2) {
3578
+ k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
3579
+ }
3580
+ if (remainder >= 1) {
3581
+ k1 ^= key.charCodeAt(i) & 255;
3582
+ k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
3583
+ k1 = k1 << 15 | k1 >>> 17;
3584
+ k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
3585
+ h1 ^= k1;
3586
+ }
3587
+ h1 ^= key.length;
3588
+ h1 ^= h1 >>> 16;
3589
+ h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
3590
+ h1 ^= h1 >>> 13;
3591
+ h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
3592
+ h1 ^= h1 >>> 16;
3593
+ return h1 >>> 0;
3594
+ }
3595
+
3570
3596
  class ForkedStoreState extends StoreState {
3571
3597
  master;
3572
3598
  changedItems = new Map;
@@ -3722,12 +3748,8 @@ class MasterStoreState extends StoreState {
3722
3748
  }
3723
3749
  return transaction.find(this.storeName, { where: { _id: id2 } }).then((results) => results[0]);
3724
3750
  }
3725
- async applyChangeAndReturnEvent(transaction, change, transactionCache, options) {
3751
+ async applyChangeAndReturnEvent(transaction, change, transactionCache) {
3726
3752
  if (change.type === "set") {
3727
- let existing;
3728
- if (options?.captureRows) {
3729
- existing = await this.readExisting(transaction, change.data._id, transactionCache);
3730
- }
3731
3753
  await transaction.set(this.storeName, change.data);
3732
3754
  const item = this.deserialize ? this.deserialize(change.data) : change.data;
3733
3755
  if (transactionCache) {
@@ -3740,16 +3762,10 @@ class MasterStoreState extends StoreState {
3740
3762
  type: "set",
3741
3763
  item: change.data,
3742
3764
  id: change.data._id
3743
- },
3744
- oldRow: existing ?? null,
3745
- newRow: change.data
3765
+ }
3746
3766
  };
3747
3767
  }
3748
3768
  if (change.type === "delete") {
3749
- let existing;
3750
- if (options?.captureRows) {
3751
- existing = await this.readExisting(transaction, change.id, transactionCache);
3752
- }
3753
3769
  await transaction.remove(this.storeName, change.id);
3754
3770
  if (transactionCache) {
3755
3771
  transactionCache.delete(`${this.storeName}:${change.id}`);
@@ -3761,9 +3777,7 @@ class MasterStoreState extends StoreState {
3761
3777
  type: "delete",
3762
3778
  item: null,
3763
3779
  id: change.id
3764
- },
3765
- oldRow: existing ?? null,
3766
- newRow: null
3780
+ }
3767
3781
  };
3768
3782
  }
3769
3783
  if (change.type === "modify") {
@@ -3781,9 +3795,7 @@ class MasterStoreState extends StoreState {
3781
3795
  type: "set",
3782
3796
  item,
3783
3797
  id: change.id
3784
- },
3785
- oldRow: existing ?? null,
3786
- newRow: updated
3798
+ }
3787
3799
  };
3788
3800
  }
3789
3801
  if (change.type === "mutate") {
@@ -3801,9 +3813,7 @@ class MasterStoreState extends StoreState {
3801
3813
  type: "set",
3802
3814
  item,
3803
3815
  id: change.id
3804
- },
3805
- oldRow: existing ?? null,
3806
- newRow: updated
3816
+ }
3807
3817
  };
3808
3818
  }
3809
3819
  throw new Error("Unknown change type");
@@ -3881,22 +3891,17 @@ class MasterDataStorage extends DataStorage {
3881
3891
  applySerializedChanges(changes) {
3882
3892
  return Promise.all(changes.map(({ store, changes: changes2 }) => this.getStore(store).applySerializedChanges(changes2)));
3883
3893
  }
3884
- async commitChanges(changes, options) {
3894
+ async commitChanges(changes) {
3885
3895
  const transaction = await this.getReadWriteTransaction();
3886
3896
  const transactionCache = new Map;
3887
3897
  const eventsByStore = new Map;
3888
- const committed = [];
3889
3898
  for (const { store, changes: storeChanges } of changes) {
3890
3899
  const storeState = this.getStore(store);
3891
3900
  const storeEvents = [];
3892
- const capture = options?.captureRowsFor?.has(store) ?? false;
3893
3901
  for (const change of storeChanges) {
3894
- const { event: event3, oldRow, newRow } = await storeState.applyChangeAndReturnEvent(transaction, change, transactionCache, { captureRows: capture });
3902
+ const { event: event3 } = await storeState.applyChangeAndReturnEvent(transaction, change, transactionCache);
3895
3903
  if (event3)
3896
3904
  storeEvents.push(event3);
3897
- if (capture) {
3898
- committed.push({ store, id: event3.id, oldRow, newRow });
3899
- }
3900
3905
  }
3901
3906
  if (storeEvents.length > 0) {
3902
3907
  eventsByStore.set(store, storeEvents);
@@ -3907,7 +3912,6 @@ class MasterDataStorage extends DataStorage {
3907
3912
  const storeState = this.getStore(store);
3908
3913
  storeState.notifyListenersPublic(events);
3909
3914
  }
3910
- return committed;
3911
3915
  }
3912
3916
  fork() {
3913
3917
  return new ForkedDataStorage(this);
@@ -4022,8 +4026,8 @@ class ObservableDataStorage {
4022
4026
  getReadWriteTransaction() {
4023
4027
  return this.source.getReadWriteTransaction();
4024
4028
  }
4025
- commitChanges(changes, options) {
4026
- return this.source.commitChanges(changes, options);
4029
+ commitChanges(changes) {
4030
+ return this.source.commitChanges(changes);
4027
4031
  }
4028
4032
  trackQuery(storeName, options, result, listener4) {
4029
4033
  const key = this.getQueryKey(storeName, options);
@@ -4036,7 +4040,8 @@ class ObservableDataStorage {
4036
4040
  }
4037
4041
  handleStoreChange(storeName, events) {
4038
4042
  let hasChanges = false;
4039
- for (const query of this.trackedQueries.values()) {
4043
+ const staleKeys = [];
4044
+ for (const [key, query] of this.trackedQueries) {
4040
4045
  if (query.storeName !== storeName)
4041
4046
  continue;
4042
4047
  let currentResult = query.result;
@@ -4048,10 +4053,20 @@ class ObservableDataStorage {
4048
4053
  queryChanged = true;
4049
4054
  }
4050
4055
  }
4051
- if (queryChanged) {
4052
- query.result = currentResult;
4056
+ if (!queryChanged)
4057
+ continue;
4058
+ if (query.options.limit !== undefined && query.result.length === query.options.limit && currentResult.length < query.options.limit) {
4059
+ staleKeys.push(key);
4053
4060
  hasChanges = true;
4061
+ continue;
4054
4062
  }
4063
+ query.result = currentResult;
4064
+ hasChanges = true;
4065
+ }
4066
+ for (const key of staleKeys) {
4067
+ const query = this.trackedQueries.get(key);
4068
+ this.source.getStore(query.storeName).unsubscribe(query.listener);
4069
+ this.trackedQueries.delete(key);
4055
4070
  }
4056
4071
  if (hasChanges) {
4057
4072
  this.onChange();
@@ -4322,244 +4337,135 @@ class Model {
4322
4337
  return s;
4323
4338
  }
4324
4339
  }
4325
- var DEFAULT_SCOPE = "default";
4326
-
4327
- class StreamingQueryCache {
4328
- stores = new Map;
4329
- views = [];
4330
- activeStreams = new Map;
4331
- pendingUnsubscribes = new Map;
4332
- static UNSUBSCRIBE_DELAY_MS = 5000;
4333
- storeKey(viewName, scope) {
4334
- return `${scope ?? DEFAULT_SCOPE}:${viewName}`;
4335
- }
4336
- registerViews(views) {
4337
- this.views = views;
4338
- }
4339
- getStore(viewName, scope) {
4340
- const key = this.storeKey(viewName, scope);
4341
- if (!this.stores.has(key)) {
4342
- this.stores.set(key, new StreamingStore);
4340
+ function applyQueryChanges(result, changes) {
4341
+ const next = [...result];
4342
+ for (const change of changes) {
4343
+ if (change.type === "delete") {
4344
+ const idx = next.findIndex((it) => it._id === change.id);
4345
+ if (idx !== -1)
4346
+ next.splice(idx, 1);
4343
4347
  }
4344
- return this.stores.get(key);
4345
4348
  }
4346
- hasData(viewName, scope) {
4347
- const store = this.stores.get(this.storeKey(viewName, scope));
4348
- return store ? store.hasData() : false;
4349
- }
4350
- registerStream(key, createStream) {
4351
- const pending = this.pendingUnsubscribes.get(key);
4352
- if (pending) {
4353
- clearTimeout(pending);
4354
- this.pendingUnsubscribes.delete(key);
4349
+ for (const change of changes) {
4350
+ if (change.type === "set") {
4351
+ const idx = next.findIndex((it) => it._id === change.id);
4352
+ if (idx !== -1)
4353
+ next.splice(idx, 1);
4354
+ next.splice(change.index, 0, change.item);
4355
4355
  }
4356
- const existing = this.activeStreams.get(key);
4357
- if (existing) {
4358
- existing.refCount++;
4359
- return {
4360
- unsubscribe: () => this.unregisterStream(key),
4361
- wasReused: true
4356
+ }
4357
+ return next;
4358
+ }
4359
+ class StreamingQueryCache {
4360
+ entries = new Map;
4361
+ static UNSUBSCRIBE_DELAY_MS = 5000;
4362
+ entryKey(descriptor, scope) {
4363
+ return `${scope ?? "default"}:${murmurHash(JSON.stringify(descriptor))}`;
4364
+ }
4365
+ subscribe(descriptor, scope, eventWire, onChange) {
4366
+ const key = this.entryKey(descriptor, scope);
4367
+ let entry = this.entries.get(key);
4368
+ if (entry) {
4369
+ if (entry.pendingUnsub) {
4370
+ clearTimeout(entry.pendingUnsub);
4371
+ entry.pendingUnsub = undefined;
4372
+ }
4373
+ entry.refCount++;
4374
+ } else {
4375
+ const newEntry = {
4376
+ result: undefined,
4377
+ hasResult: false,
4378
+ listeners: new Set,
4379
+ refCount: 1,
4380
+ subscriptionId: ""
4362
4381
  };
4382
+ newEntry.subscriptionId = eventWire.subscribeQuery(descriptor, scope, {
4383
+ onSnapshot: (result) => {
4384
+ newEntry.result = result;
4385
+ newEntry.hasResult = true;
4386
+ this.notify(newEntry);
4387
+ },
4388
+ onChanges: (changes) => {
4389
+ if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
4390
+ return;
4391
+ }
4392
+ newEntry.result = applyQueryChanges(newEntry.result, changes);
4393
+ this.notify(newEntry);
4394
+ }
4395
+ });
4396
+ this.entries.set(key, newEntry);
4397
+ entry = newEntry;
4363
4398
  }
4364
- const streamConn = createStream();
4365
- this.activeStreams.set(key, {
4366
- unsubscribe: streamConn.unsubscribe,
4367
- refCount: 1
4368
- });
4399
+ const subscribed = entry;
4400
+ subscribed.listeners.add(onChange);
4401
+ let active = true;
4369
4402
  return {
4370
- unsubscribe: () => this.unregisterStream(key),
4371
- wasReused: false
4403
+ read: () => ({
4404
+ result: subscribed.result,
4405
+ loading: !subscribed.hasResult
4406
+ }),
4407
+ unsubscribe: () => {
4408
+ if (!active)
4409
+ return;
4410
+ active = false;
4411
+ subscribed.listeners.delete(onChange);
4412
+ subscribed.refCount--;
4413
+ if (subscribed.refCount > 0)
4414
+ return;
4415
+ subscribed.pendingUnsub = setTimeout(() => {
4416
+ subscribed.pendingUnsub = undefined;
4417
+ if (subscribed.refCount > 0)
4418
+ return;
4419
+ eventWire.unsubscribeQuery(subscribed.subscriptionId);
4420
+ this.entries.delete(key);
4421
+ }, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
4422
+ }
4372
4423
  };
4373
4424
  }
4374
- unregisterStream(key) {
4375
- const stream = this.activeStreams.get(key);
4376
- if (!stream)
4377
- return;
4378
- stream.refCount--;
4379
- if (stream.refCount <= 0) {
4380
- const timeout = setTimeout(() => {
4381
- this.pendingUnsubscribes.delete(key);
4382
- const current2 = this.activeStreams.get(key);
4383
- if (current2 && current2.refCount <= 0) {
4384
- current2.unsubscribe();
4385
- this.activeStreams.delete(key);
4386
- }
4387
- }, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
4388
- this.pendingUnsubscribes.set(key, timeout);
4389
- }
4390
- }
4391
- subscribeView(viewName, eventWire, scope) {
4392
- const key = this.storeKey(viewName, scope);
4393
- const { unsubscribe } = this.registerStream(key, () => {
4394
- const store = this.stores.get(key) ?? new StreamingStore;
4395
- this.stores.set(key, store);
4396
- eventWire.subscribeView(viewName, scope ?? DEFAULT_SCOPE, {
4397
- onSnapshot: (items) => store.setAll(items),
4398
- onChanges: (changes) => store.applyChanges(changes)
4399
- });
4400
- return {
4401
- unsubscribe: () => eventWire.unsubscribeView(viewName, scope ?? DEFAULT_SCOPE)
4402
- };
4403
- });
4404
- return unsubscribe;
4405
- }
4406
- invalidateScope(scope) {
4425
+ invalidateScope(scope, eventWire) {
4407
4426
  const prefix = `${scope}:`;
4408
- for (const [key, timeout] of this.pendingUnsubscribes) {
4409
- if (!key.startsWith(prefix))
4410
- continue;
4411
- clearTimeout(timeout);
4412
- this.pendingUnsubscribes.delete(key);
4413
- }
4414
- for (const [key, stream] of this.activeStreams) {
4415
- if (!key.startsWith(prefix))
4416
- continue;
4417
- try {
4418
- stream.unsubscribe();
4419
- } catch {}
4420
- this.activeStreams.delete(key);
4421
- }
4422
- for (const [key, store] of this.stores) {
4427
+ for (const [key, entry] of this.entries) {
4423
4428
  if (!key.startsWith(prefix))
4424
4429
  continue;
4425
- store.clear();
4426
- }
4427
- }
4428
- async applyEvent(event3) {
4429
- for (const view3 of this.views) {
4430
- const handlers = view3.getHandlers();
4431
- const handler = handlers[event3.type];
4432
- if (!handler)
4433
- continue;
4434
- const suffix = `:${view3.name}`;
4435
- for (const [key, store] of this.stores) {
4436
- if (!key.endsWith(suffix))
4437
- continue;
4438
- const ctx = {
4439
- set: async (id3, data) => {
4440
- store.set(String(id3), { _id: String(id3), ...data });
4441
- },
4442
- modify: async (id3, data) => {
4443
- store.modify(String(id3), data);
4444
- },
4445
- remove: async (id3) => {
4446
- store.remove(String(id3));
4447
- },
4448
- find: async (options) => {
4449
- return store.find(options);
4450
- },
4451
- findOne: async (where) => {
4452
- return store.findOne(where);
4453
- },
4454
- $auth: {}
4455
- };
4456
- await handler(ctx, event3);
4457
- }
4458
- }
4459
- }
4460
- clear() {
4461
- for (const stream of this.activeStreams.values()) {
4462
- stream.unsubscribe();
4463
- }
4464
- this.activeStreams.clear();
4465
- for (const timeout of this.pendingUnsubscribes.values()) {
4466
- clearTimeout(timeout);
4467
- }
4468
- this.pendingUnsubscribes.clear();
4469
- for (const store of this.stores.values()) {
4470
- store.clear();
4430
+ if (entry.pendingUnsub)
4431
+ clearTimeout(entry.pendingUnsub);
4432
+ eventWire?.unsubscribeQuery(entry.subscriptionId);
4433
+ this.entries.delete(key);
4434
+ entry.result = undefined;
4435
+ entry.hasResult = false;
4436
+ this.notify(entry);
4471
4437
  }
4472
4438
  }
4473
- }
4474
-
4475
- class StreamingStore {
4476
- data = new Map;
4477
- listeners = new Set;
4478
- initialized = false;
4479
- hasData() {
4480
- return this.initialized;
4481
- }
4482
- setAll(items) {
4483
- this.initialized = true;
4484
- this.data.clear();
4485
- for (const item of items) {
4486
- this.data.set(item._id, item);
4439
+ clear(eventWire) {
4440
+ for (const entry of this.entries.values()) {
4441
+ if (entry.pendingUnsub)
4442
+ clearTimeout(entry.pendingUnsub);
4443
+ eventWire?.unsubscribeQuery(entry.subscriptionId);
4487
4444
  }
4488
- this.notifyListeners(null);
4445
+ this.entries.clear();
4489
4446
  }
4490
- applyChanges(events) {
4491
- if (events.length === 0)
4492
- return;
4493
- for (const event3 of events) {
4494
- if (event3.type === "set" && event3.item) {
4495
- this.data.set(event3.id, event3.item);
4496
- } else if (event3.type === "delete") {
4497
- this.data.delete(event3.id);
4447
+ notify(entry) {
4448
+ for (const listener4 of entry.listeners) {
4449
+ try {
4450
+ listener4();
4451
+ } catch (err) {
4452
+ console.error(`[Arc] Query cache listener error:`, err);
4498
4453
  }
4499
4454
  }
4500
- this.notifyListeners(events);
4501
- }
4502
- set(id3, item) {
4503
- this.data.set(id3, item);
4504
- this.notifyListeners([{ type: "set", id: id3, item }]);
4505
- }
4506
- modify(id3, updates) {
4507
- const existing = this.data.get(id3);
4508
- if (existing) {
4509
- const updated = { ...existing, ...updates };
4510
- this.data.set(id3, updated);
4511
- this.notifyListeners([{ type: "set", id: id3, item: updated }]);
4512
- }
4513
- }
4514
- remove(id3) {
4515
- if (this.data.delete(id3)) {
4516
- this.notifyListeners([{ type: "delete", id: id3, item: null }]);
4517
- }
4518
- }
4519
- clear() {
4520
- this.initialized = false;
4521
- this.data.clear();
4522
- this.notifyListeners(null);
4523
- }
4524
- find(options = {}) {
4525
- let results = Array.from(this.data.values());
4526
- if (options.where) {
4527
- results = results.filter((item) => checkItemMatchesWhere(item, options.where));
4528
- }
4529
- return applyOrderByAndLimit(results, options);
4530
- }
4531
- findOne(where) {
4532
- const results = this.find({ where });
4533
- return results[0];
4534
- }
4535
- subscribe(listener4) {
4536
- this.listeners.add(listener4);
4537
- return () => {
4538
- this.listeners.delete(listener4);
4539
- };
4540
- }
4541
- notifyListeners(events) {
4542
- for (const listener4 of this.listeners) {
4543
- listener4(events);
4544
- }
4545
4455
  }
4546
4456
  }
4547
4457
 
4548
4458
  class StreamingEventPublisher {
4549
- cache;
4550
4459
  eventWire;
4551
4460
  views = [];
4552
4461
  subscribers = new Map;
4553
- constructor(cache, eventWire) {
4554
- this.cache = cache;
4462
+ constructor(eventWire) {
4555
4463
  this.eventWire = eventWire;
4556
4464
  }
4557
4465
  registerViews(views) {
4558
4466
  this.views = views;
4559
- this.cache.registerViews(views);
4560
4467
  }
4561
4468
  async publish(event3) {
4562
- await this.cache.applyEvent(event3);
4563
4469
  await this.notifySubscribers(event3);
4564
4470
  this.eventWire.syncEvents([
4565
4471
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcote.tech/arc-adapter-db-sqlite",
3
- "version": "0.7.15",
3
+ "version": "0.7.16",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  "test": "bun test"
21
21
  },
22
22
  "peerDependencies": {
23
- "@arcote.tech/arc": "^0.7.15"
23
+ "@arcote.tech/arc": "^0.7.16"
24
24
  },
25
25
  "devDependencies": {
26
26
  "typescript": "^5.0.0"