@arcote.tech/arc-adapter-db-sqlite-wasm 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
@@ -1484,12 +1484,13 @@ class EventWire {
1484
1484
  onSyncedCallback;
1485
1485
  reconnectTimeout;
1486
1486
  syncRequested = false;
1487
- viewSubscriptions = new Map;
1488
- viewSubCounter = 0;
1489
- pendingViewSubs = [];
1490
- constructor(baseUrl) {
1487
+ querySubscriptions = new Map;
1488
+ querySubCounter = 0;
1489
+ enableEventSync;
1490
+ constructor(baseUrl, options) {
1491
1491
  this.baseUrl = baseUrl;
1492
1492
  this.instanceId = ++eventWireInstanceCounter;
1493
+ this.enableEventSync = options?.enableEventSync ?? true;
1493
1494
  }
1494
1495
  setScopeToken(scope, token) {
1495
1496
  if (token === null) {
@@ -1535,9 +1536,11 @@ class EventWire {
1535
1536
  if (this.ws && this.ws.readyState === WebSocket.OPEN) {
1536
1537
  this.state = "connected";
1537
1538
  this.sendAllScopeTokens();
1538
- this.requestSync();
1539
+ if (this.enableEventSync) {
1540
+ this.requestSync();
1541
+ }
1539
1542
  this.flushPendingEvents();
1540
- this.flushPendingViewSubs();
1543
+ this.sendAllQuerySubscriptions();
1541
1544
  } else {
1542
1545
  console.log(`[EventWire] onopen called but ws is not OPEN, readyState:`, this.ws?.readyState);
1543
1546
  }
@@ -1613,9 +1616,13 @@ class EventWire {
1613
1616
  onSynced(callback) {
1614
1617
  this.onSyncedCallback = callback;
1615
1618
  }
1616
- subscribeQuery(descriptor, callback, scope) {
1617
- const subscriptionId = `qs_${++this.viewSubCounter}_${Date.now()}`;
1618
- this.viewSubscriptions.set(subscriptionId, callback);
1619
+ subscribeQuery(descriptor, scope, callbacks) {
1620
+ const subscriptionId = `qs_${this.instanceId}_${++this.querySubCounter}`;
1621
+ this.querySubscriptions.set(subscriptionId, {
1622
+ descriptor,
1623
+ scope,
1624
+ callbacks
1625
+ });
1619
1626
  if (this.state === "connected" && this.ws) {
1620
1627
  this.ws.send(JSON.stringify({
1621
1628
  type: "subscribe-query",
@@ -1623,20 +1630,17 @@ class EventWire {
1623
1630
  descriptor,
1624
1631
  scope
1625
1632
  }));
1626
- } else {
1627
- this.pendingViewSubs.push({ subscriptionId, descriptor, scope });
1628
1633
  }
1629
1634
  return subscriptionId;
1630
1635
  }
1631
1636
  unsubscribeQuery(subscriptionId) {
1632
- this.viewSubscriptions.delete(subscriptionId);
1637
+ this.querySubscriptions.delete(subscriptionId);
1633
1638
  if (this.state === "connected" && this.ws) {
1634
1639
  this.ws.send(JSON.stringify({
1635
1640
  type: "unsubscribe-query",
1636
1641
  subscriptionId
1637
1642
  }));
1638
1643
  }
1639
- this.pendingViewSubs = this.pendingViewSubs.filter((s) => s.subscriptionId !== subscriptionId);
1640
1644
  }
1641
1645
  getState() {
1642
1646
  return this.state;
@@ -1669,10 +1673,17 @@ class EventWire {
1669
1673
  this.lastHostEventId = message.lastHostEventId;
1670
1674
  }
1671
1675
  break;
1672
- case "query-data": {
1673
- const cb = this.viewSubscriptions.get(message.subscriptionId);
1674
- if (cb) {
1675
- cb(message.data);
1676
+ case "query-snapshot": {
1677
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1678
+ if (sub) {
1679
+ sub.callbacks.onSnapshot(message.result ?? null);
1680
+ }
1681
+ break;
1682
+ }
1683
+ case "query-changes": {
1684
+ const sub = this.querySubscriptions.get(message.subscriptionId);
1685
+ if (sub && Array.isArray(message.changes)) {
1686
+ sub.callbacks.onChanges(message.changes);
1676
1687
  }
1677
1688
  break;
1678
1689
  }
@@ -1700,18 +1711,17 @@ class EventWire {
1700
1711
  this.pendingEvents = [];
1701
1712
  }
1702
1713
  }
1703
- flushPendingViewSubs() {
1714
+ sendAllQuerySubscriptions() {
1704
1715
  if (!this.ws || this.state !== "connected")
1705
1716
  return;
1706
- for (const sub of this.pendingViewSubs) {
1717
+ for (const [subscriptionId, sub] of this.querySubscriptions) {
1707
1718
  this.ws.send(JSON.stringify({
1708
1719
  type: "subscribe-query",
1709
- subscriptionId: sub.subscriptionId,
1720
+ subscriptionId,
1710
1721
  descriptor: sub.descriptor,
1711
1722
  scope: sub.scope
1712
1723
  }));
1713
1724
  }
1714
- this.pendingViewSubs = [];
1715
1725
  }
1716
1726
  scheduleReconnect() {
1717
1727
  if (this.reconnectTimeout)
@@ -3538,6 +3548,48 @@ function deepMerge(target, source) {
3538
3548
  function isPlainObject(item) {
3539
3549
  return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
3540
3550
  }
3551
+ function murmurHash(key, seed = 0) {
3552
+ let remainder, bytes, h1, h1b, c1, c2, k1, i;
3553
+ remainder = key.length & 3;
3554
+ bytes = key.length - remainder;
3555
+ h1 = seed;
3556
+ c1 = 3432918353;
3557
+ c2 = 461845907;
3558
+ i = 0;
3559
+ while (i < bytes) {
3560
+ k1 = key.charCodeAt(i) & 255 | (key.charCodeAt(++i) & 255) << 8 | (key.charCodeAt(++i) & 255) << 16 | (key.charCodeAt(++i) & 255) << 24;
3561
+ ++i;
3562
+ k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
3563
+ k1 = k1 << 15 | k1 >>> 17;
3564
+ k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
3565
+ h1 ^= k1;
3566
+ h1 = h1 << 13 | h1 >>> 19;
3567
+ h1b = (h1 & 65535) * 5 + (((h1 >>> 16) * 5 & 65535) << 16) & 4294967295;
3568
+ h1 = (h1b & 65535) + 27492 + (((h1b >>> 16) + 58964 & 65535) << 16);
3569
+ }
3570
+ k1 = 0;
3571
+ if (remainder >= 3) {
3572
+ k1 ^= (key.charCodeAt(i + 2) & 255) << 16;
3573
+ }
3574
+ if (remainder >= 2) {
3575
+ k1 ^= (key.charCodeAt(i + 1) & 255) << 8;
3576
+ }
3577
+ if (remainder >= 1) {
3578
+ k1 ^= key.charCodeAt(i) & 255;
3579
+ k1 = (k1 & 65535) * c1 + (((k1 >>> 16) * c1 & 65535) << 16) & 4294967295;
3580
+ k1 = k1 << 15 | k1 >>> 17;
3581
+ k1 = (k1 & 65535) * c2 + (((k1 >>> 16) * c2 & 65535) << 16) & 4294967295;
3582
+ h1 ^= k1;
3583
+ }
3584
+ h1 ^= key.length;
3585
+ h1 ^= h1 >>> 16;
3586
+ h1 = (h1 & 65535) * 2246822507 + (((h1 >>> 16) * 2246822507 & 65535) << 16) & 4294967295;
3587
+ h1 ^= h1 >>> 13;
3588
+ h1 = (h1 & 65535) * 3266489909 + (((h1 >>> 16) * 3266489909 & 65535) << 16) & 4294967295;
3589
+ h1 ^= h1 >>> 16;
3590
+ return h1 >>> 0;
3591
+ }
3592
+
3541
3593
  class ForkedStoreState extends StoreState {
3542
3594
  master;
3543
3595
  changedItems = new Map;
@@ -3686,12 +3738,19 @@ class MasterStoreState extends StoreState {
3686
3738
  constructor(storeName, dataStorage, deserialize) {
3687
3739
  super(storeName, dataStorage, deserialize);
3688
3740
  }
3741
+ async readExisting(transaction, id2, transactionCache) {
3742
+ const cacheKey = `${this.storeName}:${id2}`;
3743
+ if (transactionCache && transactionCache.has(cacheKey)) {
3744
+ return transactionCache.get(cacheKey);
3745
+ }
3746
+ return transaction.find(this.storeName, { where: { _id: id2 } }).then((results) => results[0]);
3747
+ }
3689
3748
  async applyChangeAndReturnEvent(transaction, change, transactionCache) {
3690
3749
  if (change.type === "set") {
3691
3750
  await transaction.set(this.storeName, change.data);
3692
3751
  const item = this.deserialize ? this.deserialize(change.data) : change.data;
3693
3752
  if (transactionCache) {
3694
- transactionCache.set(change.data._id, item);
3753
+ transactionCache.set(`${this.storeName}:${change.data._id}`, item);
3695
3754
  }
3696
3755
  return {
3697
3756
  from: null,
@@ -3705,6 +3764,9 @@ class MasterStoreState extends StoreState {
3705
3764
  }
3706
3765
  if (change.type === "delete") {
3707
3766
  await transaction.remove(this.storeName, change.id);
3767
+ if (transactionCache) {
3768
+ transactionCache.delete(`${this.storeName}:${change.id}`);
3769
+ }
3708
3770
  return {
3709
3771
  from: null,
3710
3772
  to: null,
@@ -3716,17 +3778,12 @@ class MasterStoreState extends StoreState {
3716
3778
  };
3717
3779
  }
3718
3780
  if (change.type === "modify") {
3719
- let existing;
3720
- if (transactionCache && transactionCache.has(change.id)) {
3721
- existing = transactionCache.get(change.id);
3722
- } else {
3723
- existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
3724
- }
3781
+ const existing = await this.readExisting(transaction, change.id, transactionCache);
3725
3782
  const updated = existing ? deepMerge(existing, change.data) : { _id: change.id, ...change.data };
3726
3783
  await transaction.set(this.storeName, updated);
3727
3784
  const item = this.deserialize ? this.deserialize(updated) : updated;
3728
3785
  if (transactionCache) {
3729
- transactionCache.set(change.id, item);
3786
+ transactionCache.set(`${this.storeName}:${change.id}`, item);
3730
3787
  }
3731
3788
  return {
3732
3789
  from: null,
@@ -3739,17 +3796,12 @@ class MasterStoreState extends StoreState {
3739
3796
  };
3740
3797
  }
3741
3798
  if (change.type === "mutate") {
3742
- let existing;
3743
- if (transactionCache && transactionCache.has(change.id)) {
3744
- existing = transactionCache.get(change.id);
3745
- } else {
3746
- existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
3747
- }
3799
+ const existing = await this.readExisting(transaction, change.id, transactionCache);
3748
3800
  const updated = apply(existing || {}, change.patches);
3749
3801
  await transaction.set(this.storeName, updated);
3750
3802
  const item = this.deserialize ? this.deserialize(updated) : updated;
3751
3803
  if (transactionCache) {
3752
- transactionCache.set(change.id, item);
3804
+ transactionCache.set(`${this.storeName}:${change.id}`, item);
3753
3805
  }
3754
3806
  return {
3755
3807
  from: null,
@@ -3985,7 +4037,8 @@ class ObservableDataStorage {
3985
4037
  }
3986
4038
  handleStoreChange(storeName, events) {
3987
4039
  let hasChanges = false;
3988
- for (const query of this.trackedQueries.values()) {
4040
+ const staleKeys = [];
4041
+ for (const [key, query] of this.trackedQueries) {
3989
4042
  if (query.storeName !== storeName)
3990
4043
  continue;
3991
4044
  let currentResult = query.result;
@@ -3997,10 +4050,20 @@ class ObservableDataStorage {
3997
4050
  queryChanged = true;
3998
4051
  }
3999
4052
  }
4000
- if (queryChanged) {
4001
- query.result = currentResult;
4053
+ if (!queryChanged)
4054
+ continue;
4055
+ if (query.options.limit !== undefined && query.result.length === query.options.limit && currentResult.length < query.options.limit) {
4056
+ staleKeys.push(key);
4002
4057
  hasChanges = true;
4058
+ continue;
4003
4059
  }
4060
+ query.result = currentResult;
4061
+ hasChanges = true;
4062
+ }
4063
+ for (const key of staleKeys) {
4064
+ const query = this.trackedQueries.get(key);
4065
+ this.source.getStore(query.storeName).unsubscribe(query.listener);
4066
+ this.trackedQueries.delete(key);
4004
4067
  }
4005
4068
  if (hasChanges) {
4006
4069
  this.onChange();
@@ -4216,13 +4279,6 @@ class ScopedModel {
4216
4279
  }
4217
4280
  return wire.query(viewName, options, this.getAuth());
4218
4281
  }
4219
- subscribeQuery(descriptor, callback) {
4220
- const wire = this.parent.getAdapters().eventWire;
4221
- if (!wire) {
4222
- throw new Error(`Cannot subscribe to query: no eventWire available.`);
4223
- }
4224
- return wire.subscribeQuery(descriptor, callback, this.scopeName);
4225
- }
4226
4282
  get query() {
4227
4283
  return buildContextAccessor(this.context, this.scopedAdapters, "queryContext", (descriptor) => descriptor);
4228
4284
  }
@@ -4278,244 +4334,135 @@ class Model {
4278
4334
  return s;
4279
4335
  }
4280
4336
  }
4281
- class StreamingQueryCache {
4282
- stores = new Map;
4283
- views = [];
4284
- activeStreams = new Map;
4285
- pendingUnsubscribes = new Map;
4286
- streamScopes = new Map;
4287
- static UNSUBSCRIBE_DELAY_MS = 5000;
4288
- registerViews(views) {
4289
- this.views = views;
4290
- for (const view3 of views) {
4291
- if (!this.stores.has(view3.name)) {
4292
- this.stores.set(view3.name, new StreamingStore);
4293
- }
4337
+ function applyQueryChanges(result, changes) {
4338
+ const next = [...result];
4339
+ for (const change of changes) {
4340
+ if (change.type === "delete") {
4341
+ const idx = next.findIndex((it) => it._id === change.id);
4342
+ if (idx !== -1)
4343
+ next.splice(idx, 1);
4294
4344
  }
4295
4345
  }
4296
- getStore(viewName) {
4297
- if (!this.stores.has(viewName)) {
4298
- this.stores.set(viewName, new StreamingStore);
4346
+ for (const change of changes) {
4347
+ if (change.type === "set") {
4348
+ const idx = next.findIndex((it) => it._id === change.id);
4349
+ if (idx !== -1)
4350
+ next.splice(idx, 1);
4351
+ next.splice(change.index, 0, change.item);
4299
4352
  }
4300
- return this.stores.get(viewName);
4301
- }
4302
- hasData(viewName) {
4303
- const store = this.stores.get(viewName);
4304
- return store ? store.hasData() : false;
4305
- }
4306
- hasActiveStream(viewName) {
4307
- return this.activeStreams.has(viewName);
4308
4353
  }
4309
- registerStream(viewName, createStream) {
4310
- const pending = this.pendingUnsubscribes.get(viewName);
4311
- if (pending) {
4312
- clearTimeout(pending);
4313
- this.pendingUnsubscribes.delete(viewName);
4314
- }
4315
- const existing = this.activeStreams.get(viewName);
4316
- if (existing) {
4317
- existing.refCount++;
4318
- return {
4319
- unsubscribe: () => this.unregisterStream(viewName),
4320
- wasReused: true
4354
+ return next;
4355
+ }
4356
+ class StreamingQueryCache {
4357
+ entries = new Map;
4358
+ static UNSUBSCRIBE_DELAY_MS = 5000;
4359
+ entryKey(descriptor, scope) {
4360
+ return `${scope ?? "default"}:${murmurHash(JSON.stringify(descriptor))}`;
4361
+ }
4362
+ subscribe(descriptor, scope, eventWire, onChange) {
4363
+ const key = this.entryKey(descriptor, scope);
4364
+ let entry = this.entries.get(key);
4365
+ if (entry) {
4366
+ if (entry.pendingUnsub) {
4367
+ clearTimeout(entry.pendingUnsub);
4368
+ entry.pendingUnsub = undefined;
4369
+ }
4370
+ entry.refCount++;
4371
+ } else {
4372
+ const newEntry = {
4373
+ result: undefined,
4374
+ hasResult: false,
4375
+ listeners: new Set,
4376
+ refCount: 1,
4377
+ subscriptionId: ""
4321
4378
  };
4379
+ newEntry.subscriptionId = eventWire.subscribeQuery(descriptor, scope, {
4380
+ onSnapshot: (result) => {
4381
+ newEntry.result = result;
4382
+ newEntry.hasResult = true;
4383
+ this.notify(newEntry);
4384
+ },
4385
+ onChanges: (changes) => {
4386
+ if (!newEntry.hasResult || !Array.isArray(newEntry.result)) {
4387
+ return;
4388
+ }
4389
+ newEntry.result = applyQueryChanges(newEntry.result, changes);
4390
+ this.notify(newEntry);
4391
+ }
4392
+ });
4393
+ this.entries.set(key, newEntry);
4394
+ entry = newEntry;
4322
4395
  }
4323
- const streamConn = createStream();
4324
- this.activeStreams.set(viewName, {
4325
- unsubscribe: streamConn.unsubscribe,
4326
- refCount: 1
4327
- });
4396
+ const subscribed = entry;
4397
+ subscribed.listeners.add(onChange);
4398
+ let active = true;
4328
4399
  return {
4329
- unsubscribe: () => this.unregisterStream(viewName),
4330
- wasReused: false
4331
- };
4332
- }
4333
- unregisterStream(viewName) {
4334
- const stream = this.activeStreams.get(viewName);
4335
- if (!stream)
4336
- return;
4337
- stream.refCount--;
4338
- if (stream.refCount <= 0) {
4339
- const timeout = setTimeout(() => {
4340
- this.pendingUnsubscribes.delete(viewName);
4341
- const current2 = this.activeStreams.get(viewName);
4342
- if (current2 && current2.refCount <= 0) {
4343
- current2.unsubscribe();
4344
- this.activeStreams.delete(viewName);
4345
- this.streamScopes.delete(viewName);
4346
- }
4347
- }, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
4348
- this.pendingUnsubscribes.set(viewName, timeout);
4349
- }
4350
- }
4351
- subscribeQuery(descriptor, eventWire, scope) {
4352
- const key = descriptor.element;
4353
- if (scope)
4354
- this.streamScopes.set(key, scope);
4355
- const { unsubscribe } = this.registerStream(key, () => {
4356
- const subId = eventWire.subscribeQuery(descriptor, (data) => {
4357
- this.setViewData(descriptor.element, data);
4358
- }, scope);
4359
- return { unsubscribe: () => eventWire.unsubscribeQuery(subId) };
4360
- });
4361
- return unsubscribe;
4362
- }
4363
- invalidateScope(scope) {
4364
- for (const [viewName, viewScope] of this.streamScopes) {
4365
- if (viewScope !== scope)
4366
- continue;
4367
- const pending = this.pendingUnsubscribes.get(viewName);
4368
- if (pending) {
4369
- clearTimeout(pending);
4370
- this.pendingUnsubscribes.delete(viewName);
4400
+ read: () => ({
4401
+ result: subscribed.result,
4402
+ loading: !subscribed.hasResult
4403
+ }),
4404
+ unsubscribe: () => {
4405
+ if (!active)
4406
+ return;
4407
+ active = false;
4408
+ subscribed.listeners.delete(onChange);
4409
+ subscribed.refCount--;
4410
+ if (subscribed.refCount > 0)
4411
+ return;
4412
+ subscribed.pendingUnsub = setTimeout(() => {
4413
+ subscribed.pendingUnsub = undefined;
4414
+ if (subscribed.refCount > 0)
4415
+ return;
4416
+ eventWire.unsubscribeQuery(subscribed.subscriptionId);
4417
+ this.entries.delete(key);
4418
+ }, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
4371
4419
  }
4372
- const stream = this.activeStreams.get(viewName);
4373
- if (stream) {
4374
- try {
4375
- stream.unsubscribe();
4376
- } catch {}
4377
- this.activeStreams.delete(viewName);
4378
- }
4379
- this.streamScopes.delete(viewName);
4380
- const store = this.stores.get(viewName);
4381
- if (store)
4382
- store.clear();
4383
- }
4384
- }
4385
- setViewData(viewName, data) {
4386
- const store = this.stores.get(viewName);
4387
- if (!store)
4388
- return;
4389
- if (Array.isArray(data)) {
4390
- store.setAll(data);
4391
- } else if (data && typeof data === "object" && "_id" in data) {
4392
- store.setAll([data]);
4393
- } else {
4394
- store.setAll([]);
4395
- }
4420
+ };
4396
4421
  }
4397
- async applyEvent(event3) {
4398
- for (const view3 of this.views) {
4399
- const handlers = view3.getHandlers();
4400
- const handler = handlers[event3.type];
4401
- if (!handler)
4422
+ invalidateScope(scope, eventWire) {
4423
+ const prefix = `${scope}:`;
4424
+ for (const [key, entry] of this.entries) {
4425
+ if (!key.startsWith(prefix))
4402
4426
  continue;
4403
- const store = this.stores.get(view3.name);
4404
- if (!store)
4405
- continue;
4406
- const ctx = {
4407
- set: async (id3, data) => {
4408
- store.set(String(id3), { _id: String(id3), ...data });
4409
- },
4410
- modify: async (id3, data) => {
4411
- store.modify(String(id3), data);
4412
- },
4413
- remove: async (id3) => {
4414
- store.remove(String(id3));
4415
- },
4416
- find: async (options) => {
4417
- return store.find(options);
4418
- },
4419
- findOne: async (where) => {
4420
- return store.findOne(where);
4421
- },
4422
- $auth: {}
4423
- };
4424
- await handler(ctx, event3);
4425
- }
4426
- }
4427
- clear() {
4428
- for (const stream of this.activeStreams.values()) {
4429
- stream.unsubscribe();
4430
- }
4431
- this.activeStreams.clear();
4432
- this.streamScopes.clear();
4433
- for (const timeout of this.pendingUnsubscribes.values()) {
4434
- clearTimeout(timeout);
4435
- }
4436
- this.pendingUnsubscribes.clear();
4437
- for (const store of this.stores.values()) {
4438
- store.clear();
4427
+ if (entry.pendingUnsub)
4428
+ clearTimeout(entry.pendingUnsub);
4429
+ eventWire?.unsubscribeQuery(entry.subscriptionId);
4430
+ this.entries.delete(key);
4431
+ entry.result = undefined;
4432
+ entry.hasResult = false;
4433
+ this.notify(entry);
4439
4434
  }
4440
4435
  }
4441
- }
4442
-
4443
- class StreamingStore {
4444
- data = new Map;
4445
- listeners = new Set;
4446
- initialized = false;
4447
- hasData() {
4448
- return this.initialized;
4449
- }
4450
- setAll(items) {
4451
- this.initialized = true;
4452
- this.data.clear();
4453
- for (const item of items) {
4454
- this.data.set(item._id, item);
4455
- }
4456
- this.notifyListeners(null);
4457
- }
4458
- set(id3, item) {
4459
- this.data.set(id3, item);
4460
- this.notifyListeners([{ type: "set", id: id3, item }]);
4461
- }
4462
- modify(id3, updates) {
4463
- const existing = this.data.get(id3);
4464
- if (existing) {
4465
- const updated = { ...existing, ...updates };
4466
- this.data.set(id3, updated);
4467
- this.notifyListeners([{ type: "set", id: id3, item: updated }]);
4436
+ clear(eventWire) {
4437
+ for (const entry of this.entries.values()) {
4438
+ if (entry.pendingUnsub)
4439
+ clearTimeout(entry.pendingUnsub);
4440
+ eventWire?.unsubscribeQuery(entry.subscriptionId);
4468
4441
  }
4442
+ this.entries.clear();
4469
4443
  }
4470
- remove(id3) {
4471
- if (this.data.delete(id3)) {
4472
- this.notifyListeners([{ type: "delete", id: id3, item: null }]);
4473
- }
4474
- }
4475
- clear() {
4476
- this.initialized = false;
4477
- this.data.clear();
4478
- this.notifyListeners(null);
4479
- }
4480
- find(options = {}) {
4481
- let results = Array.from(this.data.values());
4482
- if (options.where) {
4483
- results = results.filter((item) => checkItemMatchesWhere(item, options.where));
4484
- }
4485
- return applyOrderByAndLimit(results, options);
4486
- }
4487
- findOne(where) {
4488
- const results = this.find({ where });
4489
- return results[0];
4490
- }
4491
- subscribe(listener4) {
4492
- this.listeners.add(listener4);
4493
- return () => {
4494
- this.listeners.delete(listener4);
4495
- };
4496
- }
4497
- notifyListeners(events) {
4498
- for (const listener4 of this.listeners) {
4499
- listener4(events);
4444
+ notify(entry) {
4445
+ for (const listener4 of entry.listeners) {
4446
+ try {
4447
+ listener4();
4448
+ } catch (err) {
4449
+ console.error(`[Arc] Query cache listener error:`, err);
4450
+ }
4500
4451
  }
4501
4452
  }
4502
4453
  }
4503
4454
 
4504
4455
  class StreamingEventPublisher {
4505
- cache;
4506
4456
  eventWire;
4507
4457
  views = [];
4508
4458
  subscribers = new Map;
4509
- constructor(cache, eventWire) {
4510
- this.cache = cache;
4459
+ constructor(eventWire) {
4511
4460
  this.eventWire = eventWire;
4512
4461
  }
4513
4462
  registerViews(views) {
4514
4463
  this.views = views;
4515
- this.cache.registerViews(views);
4516
4464
  }
4517
4465
  async publish(event3) {
4518
- await this.cache.applyEvent(event3);
4519
4466
  await this.notifySubscribers(event3);
4520
4467
  this.eventWire.syncEvents([
4521
4468
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcote.tech/arc-adapter-db-sqlite-wasm",
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",
@@ -39,7 +39,7 @@
39
39
  "dev": "bun build ./src/index.ts ./src/worker.ts --outdir ./dist --target browser --format esm --watch"
40
40
  },
41
41
  "peerDependencies": {
42
- "@arcote.tech/arc": "^0.7.14",
42
+ "@arcote.tech/arc": "^0.7.16",
43
43
  "@sqlite.org/sqlite-wasm": "^3.46.0-build1"
44
44
  },
45
45
  "devDependencies": {