@arcote.tech/arc 0.7.10 → 0.7.12
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.js
CHANGED
|
@@ -2491,7 +2491,11 @@ class ArcCommand extends ArcContextElement {
|
|
|
2491
2491
|
if (!adapters.commandWire) {
|
|
2492
2492
|
throw new Error(`Command "${this.data.name}" has no handler and no commandWire adapter available for remote execution`);
|
|
2493
2493
|
}
|
|
2494
|
-
|
|
2494
|
+
const wireAuth = adapters.scope ? {
|
|
2495
|
+
scope: adapters.scope.scopeName,
|
|
2496
|
+
token: adapters.scope.getToken()
|
|
2497
|
+
} : undefined;
|
|
2498
|
+
return await adapters.commandWire.executeCommand(this.data.name, params, wireAuth);
|
|
2495
2499
|
};
|
|
2496
2500
|
return Object.assign(executeFunc, { params: this.data.params });
|
|
2497
2501
|
}
|
|
@@ -4597,6 +4601,7 @@ class StreamingQueryCache {
|
|
|
4597
4601
|
views = [];
|
|
4598
4602
|
activeStreams = new Map;
|
|
4599
4603
|
pendingUnsubscribes = new Map;
|
|
4604
|
+
streamScopes = new Map;
|
|
4600
4605
|
static UNSUBSCRIBE_DELAY_MS = 5000;
|
|
4601
4606
|
registerViews(views) {
|
|
4602
4607
|
this.views = views;
|
|
@@ -4655,6 +4660,7 @@ class StreamingQueryCache {
|
|
|
4655
4660
|
if (current && current.refCount <= 0) {
|
|
4656
4661
|
current.unsubscribe();
|
|
4657
4662
|
this.activeStreams.delete(viewName);
|
|
4663
|
+
this.streamScopes.delete(viewName);
|
|
4658
4664
|
}
|
|
4659
4665
|
}, StreamingQueryCache.UNSUBSCRIBE_DELAY_MS);
|
|
4660
4666
|
this.pendingUnsubscribes.set(viewName, timeout);
|
|
@@ -4662,6 +4668,8 @@ class StreamingQueryCache {
|
|
|
4662
4668
|
}
|
|
4663
4669
|
subscribeQuery(descriptor, eventWire, scope) {
|
|
4664
4670
|
const key = descriptor.element;
|
|
4671
|
+
if (scope)
|
|
4672
|
+
this.streamScopes.set(key, scope);
|
|
4665
4673
|
const { unsubscribe } = this.registerStream(key, () => {
|
|
4666
4674
|
const subId = eventWire.subscribeQuery(descriptor, (data) => {
|
|
4667
4675
|
this.setViewData(descriptor.element, data);
|
|
@@ -4670,6 +4678,28 @@ class StreamingQueryCache {
|
|
|
4670
4678
|
});
|
|
4671
4679
|
return unsubscribe;
|
|
4672
4680
|
}
|
|
4681
|
+
invalidateScope(scope) {
|
|
4682
|
+
for (const [viewName, viewScope] of this.streamScopes) {
|
|
4683
|
+
if (viewScope !== scope)
|
|
4684
|
+
continue;
|
|
4685
|
+
const pending = this.pendingUnsubscribes.get(viewName);
|
|
4686
|
+
if (pending) {
|
|
4687
|
+
clearTimeout(pending);
|
|
4688
|
+
this.pendingUnsubscribes.delete(viewName);
|
|
4689
|
+
}
|
|
4690
|
+
const stream = this.activeStreams.get(viewName);
|
|
4691
|
+
if (stream) {
|
|
4692
|
+
try {
|
|
4693
|
+
stream.unsubscribe();
|
|
4694
|
+
} catch {}
|
|
4695
|
+
this.activeStreams.delete(viewName);
|
|
4696
|
+
}
|
|
4697
|
+
this.streamScopes.delete(viewName);
|
|
4698
|
+
const store = this.stores.get(viewName);
|
|
4699
|
+
if (store)
|
|
4700
|
+
store.clear();
|
|
4701
|
+
}
|
|
4702
|
+
}
|
|
4673
4703
|
setViewData(viewName, data) {
|
|
4674
4704
|
const store = this.stores.get(viewName);
|
|
4675
4705
|
if (!store)
|
|
@@ -4717,6 +4747,11 @@ class StreamingQueryCache {
|
|
|
4717
4747
|
stream.unsubscribe();
|
|
4718
4748
|
}
|
|
4719
4749
|
this.activeStreams.clear();
|
|
4750
|
+
this.streamScopes.clear();
|
|
4751
|
+
for (const timeout of this.pendingUnsubscribes.values()) {
|
|
4752
|
+
clearTimeout(timeout);
|
|
4753
|
+
}
|
|
4754
|
+
this.pendingUnsubscribes.clear();
|
|
4720
4755
|
for (const store of this.stores.values()) {
|
|
4721
4756
|
store.clear();
|
|
4722
4757
|
}
|
|
@@ -38,6 +38,15 @@ export declare class StreamingQueryCache {
|
|
|
38
38
|
private views;
|
|
39
39
|
private activeStreams;
|
|
40
40
|
private pendingUnsubscribes;
|
|
41
|
+
/**
|
|
42
|
+
* Tag each active stream with the scope name that subscribed it. Used by
|
|
43
|
+
* `invalidateScope()` to force-close streams when a scope's token changes
|
|
44
|
+
* (workspace switch / re-auth) — without this tag, `registerStream()` would
|
|
45
|
+
* reuse the stale WS subscription (refCount > 0, or within the
|
|
46
|
+
* UNSUBSCRIBE_DELAY_MS grace window) and the client would keep receiving
|
|
47
|
+
* data filtered by the previous token.
|
|
48
|
+
*/
|
|
49
|
+
private streamScopes;
|
|
41
50
|
private static UNSUBSCRIBE_DELAY_MS;
|
|
42
51
|
/**
|
|
43
52
|
* Register views that this cache will handle
|
|
@@ -83,6 +92,23 @@ export declare class StreamingQueryCache {
|
|
|
83
92
|
method: string;
|
|
84
93
|
args: any[];
|
|
85
94
|
}, eventWire: EventWire, scope?: string): () => void;
|
|
95
|
+
/**
|
|
96
|
+
* Force-close every active stream tagged with `scope`. Called when a
|
|
97
|
+
* scope's token changes (workspace switch / re-auth) so the next
|
|
98
|
+
* `subscribeQuery()` creates a fresh WS subscription with the new token
|
|
99
|
+
* instead of reusing the stale one (which would keep pumping data filtered
|
|
100
|
+
* by the previous token until the page reload).
|
|
101
|
+
*
|
|
102
|
+
* Bypasses both `refCount` (other subscribers still mounted) and the
|
|
103
|
+
* UNSUBSCRIBE_DELAY_MS grace window — both became invalid the moment the
|
|
104
|
+
* token changed. React's `useQuery` re-subscribes immediately afterwards
|
|
105
|
+
* via the `subKey` change (token is in the key), getting a fresh stream.
|
|
106
|
+
*
|
|
107
|
+
* Bonus: each affected store is also cleared so any in-progress render
|
|
108
|
+
* that reads `store.find()` between `setToken` and the new WS data
|
|
109
|
+
* arriving gets `[]` rather than stale rows from the previous workspace.
|
|
110
|
+
*/
|
|
111
|
+
invalidateScope(scope: string): void;
|
|
86
112
|
/**
|
|
87
113
|
* Set data for a view. Accepts array or single item (from queryMethod findOne).
|
|
88
114
|
*/
|
package/package.json
CHANGED