@arcote.tech/arc-adapter-db-sqlite 0.7.14 → 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 +203 -256
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1487,12 +1487,13 @@ class EventWire {
1487
1487
  onSyncedCallback;
1488
1488
  reconnectTimeout;
1489
1489
  syncRequested = false;
1490
- viewSubscriptions = new Map;
1491
- viewSubCounter = 0;
1492
- pendingViewSubs = [];
1493
- constructor(baseUrl) {
1490
+ querySubscriptions = new Map;
1491
+ querySubCounter = 0;
1492
+ enableEventSync;
1493
+ constructor(baseUrl, options) {
1494
1494
  this.baseUrl = baseUrl;
1495
1495
  this.instanceId = ++eventWireInstanceCounter;
1496
+ this.enableEventSync = options?.enableEventSync ?? true;
1496
1497
  }
1497
1498
  setScopeToken(scope, token) {
1498
1499
  if (token === null) {
@@ -1538,9 +1539,11 @@ class EventWire {
1538
1539
  if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1539
1540
  this.state = "connected";
1540
1541
  this.sendAllScopeTokens();
1541
- this.requestSync();
1542
+ if (this.enableEventSync) {
1543
+ this.requestSync();
1544
+ }
1542
1545
  this.flushPendingEvents();
1543
- this.flushPendingViewSubs();
1546
+ this.sendAllQuerySubscriptions();
1544
1547
  } else {
1545
1548
  console.log(`[EventWire] onopen called but ws is not OPEN, readyState:`, this.ws?.readyState);
1546
1549
  }
@@ -1616,9 +1619,13 @@ class EventWire {
1616
1619
  onSynced(callback) {
1617
1620
  this.onSyncedCallback = callback;
1618
1621
  }
1619
- subscribeQuery(descriptor, callback, scope) {
1620
- const subscriptionId = `qs_${++this.viewSubCounter}_${Date.now()}`;
1621
- this.viewSubscriptions.set(subscriptionId, callback);
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
+ });
1622
1629
  if (this.state === "connected" && this.ws) {
1623
1630
  this.ws.send(JSON.stringify({
1624
1631
  type: "subscribe-query",
@@ -1626,20 +1633,17 @@ class EventWire {
1626
1633
  descriptor,
1627
1634
  scope
1628
1635
  }));
1629
- } else {
1630
- this.pendingViewSubs.push({ subscriptionId, descriptor, scope });
1631
1636
  }
1632
1637
  return subscriptionId;
1633
1638
  }
1634
1639
  unsubscribeQuery(subscriptionId) {
1635
- this.viewSubscriptions.delete(subscriptionId);
1640
+ this.querySubscriptions.delete(subscriptionId);
1636
1641
  if (this.state === "connected" && this.ws) {
1637
1642
  this.ws.send(JSON.stringify({
1638
1643
  type: "unsubscribe-query",
1639
1644
  subscriptionId
1640
1645
  }));
1641
1646
  }
1642
- this.pendingViewSubs = this.pendingViewSubs.filter((s) => s.subscriptionId !== subscriptionId);
1643
1647
  }
1644
1648
  getState() {
1645
1649
  return this.state;
@@ -1672,10 +1676,17 @@ class EventWire {
1672
1676
  this.lastHostEventId = message.lastHostEventId;
1673
1677
  }
1674
1678
  break;
1675
- case "query-data": {
1676
- const cb = this.viewSubscriptions.get(message.subscriptionId);
1677
- if (cb) {
1678
- cb(message.data);
1679
+ case "query-snapshot": {
1680
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1681
+ if (sub) {
1682
+ sub.callbacks.onSnapshot(message.result ?? null);
1683
+ }
1684
+ break;
1685
+ }
1686
+ case "query-changes": {
1687
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1688
+ if (sub && Array.isArray(message.changes)) {
1689
+ sub.callbacks.onChanges(message.changes);
1679
1690
  }
1680
1691
  break;
1681
1692
  }
@@ -1703,18 +1714,17 @@ class EventWire {
1703
1714
  this.pendingEvents = [];
1704
1715
  }
1705
1716
  }
1706
- flushPendingViewSubs() {
1717
+ sendAllQuerySubscriptions() {
1707
1718
  if (!this.ws || this.state !== "connected")
1708
1719
  return;
1709
- for (const sub of this.pendingViewSubs) {
1720
+ for (const [subscriptionId, sub] of this.querySubscriptions) {
1710
1721
  this.ws.send(JSON.stringify({
1711
1722
  type: "subscribe-query",
1712
- subscriptionId: sub.subscriptionId,
1723
+ subscriptionId,
1713
1724
  descriptor: sub.descriptor,
1714
1725
  scope: sub.scope
1715
1726
  }));
1716
1727
  }
1717
- this.pendingViewSubs = [];
1718
1728
  }
1719
1729
  scheduleReconnect() {
1720
1730
  if (this.reconnectTimeout)
@@ -3541,6 +3551,48 @@ function deepMerge(target, source) {
3541
3551
  function isPlainObject(item) {
3542
3552
  return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
3543
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
+
3544
3596
  class ForkedStoreState extends StoreState {
3545
3597
  master;
3546
3598
  changedItems = new Map;
@@ -3689,12 +3741,19 @@ class MasterStoreState extends StoreState {
3689
3741
  constructor(storeName, dataStorage, deserialize) {
3690
3742
  super(storeName, dataStorage, deserialize);
3691
3743
  }
3744
+ async readExisting(transaction, id2, transactionCache) {
3745
+ const cacheKey = `${this.storeName}:${id2}`;
3746
+ if (transactionCache && transactionCache.has(cacheKey)) {
3747
+ return transactionCache.get(cacheKey);
3748
+ }
3749
+ return transaction.find(this.storeName, { where: { _id: id2 } }).then((results) => results[0]);
3750
+ }
3692
3751
  async applyChangeAndReturnEvent(transaction, change, transactionCache) {
3693
3752
  if (change.type === "set") {
3694
3753
  await transaction.set(this.storeName, change.data);
3695
3754
  const item = this.deserialize ? this.deserialize(change.data) : change.data;
3696
3755
  if (transactionCache) {
3697
- transactionCache.set(change.data._id, item);
3756
+ transactionCache.set(`${this.storeName}:${change.data._id}`, item);
3698
3757
  }
3699
3758
  return {
3700
3759
  from: null,
@@ -3708,6 +3767,9 @@ class MasterStoreState extends StoreState {
3708
3767
  }
3709
3768
  if (change.type === "delete") {
3710
3769
  await transaction.remove(this.storeName, change.id);
3770
+ if (transactionCache) {
3771
+ transactionCache.delete(`${this.storeName}:${change.id}`);
3772
+ }
3711
3773
  return {
3712
3774
  from: null,
3713
3775
  to: null,
@@ -3719,17 +3781,12 @@ class MasterStoreState extends StoreState {
3719
3781
  };
3720
3782
  }
3721
3783
  if (change.type === "modify") {
3722
- let existing;
3723
- if (transactionCache && transactionCache.has(change.id)) {
3724
- existing = transactionCache.get(change.id);
3725
- } else {
3726
- existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
3727
- }
3784
+ const existing = await this.readExisting(transaction, change.id, transactionCache);
3728
3785
  const updated = existing ? deepMerge(existing, change.data) : { _id: change.id, ...change.data };
3729
3786
  await transaction.set(this.storeName, updated);
3730
3787
  const item = this.deserialize ? this.deserialize(updated) : updated;
3731
3788
  if (transactionCache) {
3732
- transactionCache.set(change.id, item);
3789
+ transactionCache.set(`${this.storeName}:${change.id}`, item);
3733
3790
  }
3734
3791
  return {
3735
3792
  from: null,
@@ -3742,17 +3799,12 @@ class MasterStoreState extends StoreState {
3742
3799
  };
3743
3800
  }
3744
3801
  if (change.type === "mutate") {
3745
- let existing;
3746
- if (transactionCache && transactionCache.has(change.id)) {
3747
- existing = transactionCache.get(change.id);
3748
- } else {
3749
- existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
3750
- }
3802
+ const existing = await this.readExisting(transaction, change.id, transactionCache);
3751
3803
  const updated = apply(existing || {}, change.patches);
3752
3804
  await transaction.set(this.storeName, updated);
3753
3805
  const item = this.deserialize ? this.deserialize(updated) : updated;
3754
3806
  if (transactionCache) {
3755
- transactionCache.set(change.id, item);
3807
+ transactionCache.set(`${this.storeName}:${change.id}`, item);
3756
3808
  }
3757
3809
  return {
3758
3810
  from: null,
@@ -3988,7 +4040,8 @@ class ObservableDataStorage {
3988
4040
  }
3989
4041
  handleStoreChange(storeName, events) {
3990
4042
  let hasChanges = false;
3991
- for (const query of this.trackedQueries.values()) {
4043
+ const staleKeys = [];
4044
+ for (const [key, query] of this.trackedQueries) {
3992
4045
  if (query.storeName !== storeName)
3993
4046
  continue;
3994
4047
  let currentResult = query.result;
@@ -4000,10 +4053,20 @@ class ObservableDataStorage {
4000
4053
  queryChanged = true;
4001
4054
  }
4002
4055
  }
4003
- if (queryChanged) {
4004
- 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);
4005
4060
  hasChanges = true;
4061
+ continue;
4006
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);
4007
4070
  }
4008
4071
  if (hasChanges) {
4009
4072
  this.onChange();
@@ -4219,13 +4282,6 @@ class ScopedModel {
4219
4282
  }
4220
4283
  return wire.query(viewName, options, this.getAuth());
4221
4284
  }
4222
- subscribeQuery(descriptor, callback) {
4223
- const wire = this.parent.getAdapters().eventWire;
4224
- if (!wire) {
4225
- throw new Error(`Cannot subscribe to query: no eventWire available.`);
4226
- }
4227
- return wire.subscribeQuery(descriptor, callback, this.scopeName);
4228
- }
4229
4285
  get query() {
4230
4286
  return buildContextAccessor(this.context, this.scopedAdapters, "queryContext", (descriptor) => descriptor);
4231
4287
  }
@@ -4281,244 +4337,135 @@ class Model {
4281
4337
  return s;
4282
4338
  }
4283
4339
  }
4284
- class StreamingQueryCache {
4285
- stores = new Map;
4286
- views = [];
4287
- activeStreams = new Map;
4288
- pendingUnsubscribes = new Map;
4289
- streamScopes = new Map;
4290
- static UNSUBSCRIBE_DELAY_MS = 5000;
4291
- registerViews(views) {
4292
- this.views = views;
4293
- for (const view3 of views) {
4294
- if (!this.stores.has(view3.name)) {
4295
- this.stores.set(view3.name, new StreamingStore);
4296
- }
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);
4297
4347
  }
4298
4348
  }
4299
- getStore(viewName) {
4300
- if (!this.stores.has(viewName)) {
4301
- this.stores.set(viewName, new StreamingStore);
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);
4302
4355
  }
4303
- return this.stores.get(viewName);
4304
- }
4305
- hasData(viewName) {
4306
- const store = this.stores.get(viewName);
4307
- return store ? store.hasData() : false;
4308
- }
4309
- hasActiveStream(viewName) {
4310
- return this.activeStreams.has(viewName);
4311
4356
  }
4312
- registerStream(viewName, createStream) {
4313
- const pending = this.pendingUnsubscribes.get(viewName);
4314
- if (pending) {
4315
- clearTimeout(pending);
4316
- this.pendingUnsubscribes.delete(viewName);
4317
- }
4318
- const existing = this.activeStreams.get(viewName);
4319
- if (existing) {
4320
- existing.refCount++;
4321
- return {
4322
- unsubscribe: () => this.unregisterStream(viewName),
4323
- wasReused: true
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: ""
4324
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;
4325
4398
  }
4326
- const streamConn = createStream();
4327
- this.activeStreams.set(viewName, {
4328
- unsubscribe: streamConn.unsubscribe,
4329
- refCount: 1
4330
- });
4399
+ const subscribed = entry;
4400
+ subscribed.listeners.add(onChange);
4401
+ let active = true;
4331
4402
  return {
4332
- unsubscribe: () => this.unregisterStream(viewName),
4333
- wasReused: false
4334
- };
4335
- }
4336
- unregisterStream(viewName) {
4337
- const stream = this.activeStreams.get(viewName);
4338
- if (!stream)
4339
- return;
4340
- stream.refCount--;
4341
- if (stream.refCount <= 0) {
4342
- const timeout = setTimeout(() => {
4343
- this.pendingUnsubscribes.delete(viewName);
4344
- const current2 = this.activeStreams.get(viewName);
4345
- if (current2 && current2.refCount <= 0) {
4346
- current2.unsubscribe();
4347
- this.activeStreams.delete(viewName);
4348
- this.streamScopes.delete(viewName);
4349
- }
4350
- }, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
4351
- this.pendingUnsubscribes.set(viewName, timeout);
4352
- }
4353
- }
4354
- subscribeQuery(descriptor, eventWire, scope) {
4355
- const key = descriptor.element;
4356
- if (scope)
4357
- this.streamScopes.set(key, scope);
4358
- const { unsubscribe } = this.registerStream(key, () => {
4359
- const subId = eventWire.subscribeQuery(descriptor, (data) => {
4360
- this.setViewData(descriptor.element, data);
4361
- }, scope);
4362
- return { unsubscribe: () => eventWire.unsubscribeQuery(subId) };
4363
- });
4364
- return unsubscribe;
4365
- }
4366
- invalidateScope(scope) {
4367
- for (const [viewName, viewScope] of this.streamScopes) {
4368
- if (viewScope !== scope)
4369
- continue;
4370
- const pending = this.pendingUnsubscribes.get(viewName);
4371
- if (pending) {
4372
- clearTimeout(pending);
4373
- this.pendingUnsubscribes.delete(viewName);
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);
4374
4422
  }
4375
- const stream = this.activeStreams.get(viewName);
4376
- if (stream) {
4377
- try {
4378
- stream.unsubscribe();
4379
- } catch {}
4380
- this.activeStreams.delete(viewName);
4381
- }
4382
- this.streamScopes.delete(viewName);
4383
- const store = this.stores.get(viewName);
4384
- if (store)
4385
- store.clear();
4386
- }
4387
- }
4388
- setViewData(viewName, data) {
4389
- const store = this.stores.get(viewName);
4390
- if (!store)
4391
- return;
4392
- if (Array.isArray(data)) {
4393
- store.setAll(data);
4394
- } else if (data && typeof data === "object" && "_id" in data) {
4395
- store.setAll([data]);
4396
- } else {
4397
- store.setAll([]);
4398
- }
4423
+ };
4399
4424
  }
4400
- async applyEvent(event3) {
4401
- for (const view3 of this.views) {
4402
- const handlers = view3.getHandlers();
4403
- const handler = handlers[event3.type];
4404
- if (!handler)
4425
+ invalidateScope(scope, eventWire) {
4426
+ const prefix = `${scope}:`;
4427
+ for (const [key, entry] of this.entries) {
4428
+ if (!key.startsWith(prefix))
4405
4429
  continue;
4406
- const store = this.stores.get(view3.name);
4407
- if (!store)
4408
- continue;
4409
- const ctx = {
4410
- set: async (id3, data) => {
4411
- store.set(String(id3), { _id: String(id3), ...data });
4412
- },
4413
- modify: async (id3, data) => {
4414
- store.modify(String(id3), data);
4415
- },
4416
- remove: async (id3) => {
4417
- store.remove(String(id3));
4418
- },
4419
- find: async (options) => {
4420
- return store.find(options);
4421
- },
4422
- findOne: async (where) => {
4423
- return store.findOne(where);
4424
- },
4425
- $auth: {}
4426
- };
4427
- await handler(ctx, event3);
4428
- }
4429
- }
4430
- clear() {
4431
- for (const stream of this.activeStreams.values()) {
4432
- stream.unsubscribe();
4433
- }
4434
- this.activeStreams.clear();
4435
- this.streamScopes.clear();
4436
- for (const timeout of this.pendingUnsubscribes.values()) {
4437
- clearTimeout(timeout);
4438
- }
4439
- this.pendingUnsubscribes.clear();
4440
- for (const store of this.stores.values()) {
4441
- 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);
4442
4437
  }
4443
4438
  }
4444
- }
4445
-
4446
- class StreamingStore {
4447
- data = new Map;
4448
- listeners = new Set;
4449
- initialized = false;
4450
- hasData() {
4451
- return this.initialized;
4452
- }
4453
- setAll(items) {
4454
- this.initialized = true;
4455
- this.data.clear();
4456
- for (const item of items) {
4457
- this.data.set(item._id, item);
4458
- }
4459
- this.notifyListeners(null);
4460
- }
4461
- set(id3, item) {
4462
- this.data.set(id3, item);
4463
- this.notifyListeners([{ type: "set", id: id3, item }]);
4464
- }
4465
- modify(id3, updates) {
4466
- const existing = this.data.get(id3);
4467
- if (existing) {
4468
- const updated = { ...existing, ...updates };
4469
- this.data.set(id3, updated);
4470
- this.notifyListeners([{ type: "set", id: id3, item: updated }]);
4439
+ clear(eventWire) {
4440
+ for (const entry of this.entries.values()) {
4441
+ if (entry.pendingUnsub)
4442
+ clearTimeout(entry.pendingUnsub);
4443
+ eventWire?.unsubscribeQuery(entry.subscriptionId);
4471
4444
  }
4445
+ this.entries.clear();
4472
4446
  }
4473
- remove(id3) {
4474
- if (this.data.delete(id3)) {
4475
- this.notifyListeners([{ type: "delete", id: id3, item: null }]);
4476
- }
4477
- }
4478
- clear() {
4479
- this.initialized = false;
4480
- this.data.clear();
4481
- this.notifyListeners(null);
4482
- }
4483
- find(options = {}) {
4484
- let results = Array.from(this.data.values());
4485
- if (options.where) {
4486
- results = results.filter((item) => checkItemMatchesWhere(item, options.where));
4487
- }
4488
- return applyOrderByAndLimit(results, options);
4489
- }
4490
- findOne(where) {
4491
- const results = this.find({ where });
4492
- return results[0];
4493
- }
4494
- subscribe(listener4) {
4495
- this.listeners.add(listener4);
4496
- return () => {
4497
- this.listeners.delete(listener4);
4498
- };
4499
- }
4500
- notifyListeners(events) {
4501
- for (const listener4 of this.listeners) {
4502
- listener4(events);
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);
4453
+ }
4503
4454
  }
4504
4455
  }
4505
4456
  }
4506
4457
 
4507
4458
  class StreamingEventPublisher {
4508
- cache;
4509
4459
  eventWire;
4510
4460
  views = [];
4511
4461
  subscribers = new Map;
4512
- constructor(cache, eventWire) {
4513
- this.cache = cache;
4462
+ constructor(eventWire) {
4514
4463
  this.eventWire = eventWire;
4515
4464
  }
4516
4465
  registerViews(views) {
4517
4466
  this.views = views;
4518
- this.cache.registerViews(views);
4519
4467
  }
4520
4468
  async publish(event3) {
4521
- await this.cache.applyEvent(event3);
4522
4469
  await this.notifySubscribers(event3);
4523
4470
  this.eventWire.syncEvents([
4524
4471
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcote.tech/arc-adapter-db-sqlite",
3
- "version": "0.7.14",
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.14"
23
+ "@arcote.tech/arc": "^0.7.16"
24
24
  },
25
25
  "devDependencies": {
26
26
  "typescript": "^5.0.0"