@darajs/core 1.25.1 → 1.25.2
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/{dara_core-1.25.1-py3-none-any.whl → dara_core-1.25.2-py3-none-any.whl} +0 -0
- package/dist/shared/interactivity/find-stream-variables.d.ts +29 -0
- package/dist/shared/interactivity/find-stream-variables.d.ts.map +1 -0
- package/dist/shared/interactivity/find-stream-variables.js +98 -0
- package/dist/shared/interactivity/find-stream-variables.js.map +1 -0
- package/dist/shared/interactivity/stream-usage-tracker.d.ts +114 -0
- package/dist/shared/interactivity/stream-usage-tracker.d.ts.map +1 -0
- package/dist/shared/interactivity/stream-usage-tracker.js +304 -0
- package/dist/shared/interactivity/stream-usage-tracker.js.map +1 -0
- package/dist/shared/interactivity/stream-variable.d.ts +6 -4
- package/dist/shared/interactivity/stream-variable.d.ts.map +1 -1
- package/dist/shared/interactivity/stream-variable.js +82 -101
- package/dist/shared/interactivity/stream-variable.js.map +1 -1
- package/dist/shared/interactivity/use-server-component.d.ts.map +1 -1
- package/dist/shared/interactivity/use-server-component.js +8 -1
- package/dist/shared/interactivity/use-server-component.js.map +1 -1
- package/dist/shared/interactivity/use-stream-subscription.d.ts +12 -0
- package/dist/shared/interactivity/use-stream-subscription.d.ts.map +1 -0
- package/dist/shared/interactivity/use-stream-subscription.js +40 -0
- package/dist/shared/interactivity/use-stream-subscription.js.map +1 -0
- package/dist/shared/interactivity/use-variable.d.ts.map +1 -1
- package/dist/shared/interactivity/use-variable.js +8 -0
- package/dist/shared/interactivity/use-variable.js.map +1 -1
- package/dist/umd/dara.core.umd.cjs +617 -279
- package/package.json +9 -9
|
Binary file
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find Stream Variables
|
|
3
|
+
*
|
|
4
|
+
* Recursively walks a variable's dependency tree to find all StreamVariables.
|
|
5
|
+
* Used for tracking stream usage when components mount/unmount.
|
|
6
|
+
*/
|
|
7
|
+
import { type AnyVariable, type StreamVariable } from '../../types';
|
|
8
|
+
/**
|
|
9
|
+
* Recursively find all StreamVariables in a variable's dependency tree.
|
|
10
|
+
*
|
|
11
|
+
* Handles all variable types:
|
|
12
|
+
* - DerivedVariable: walks `variables` array
|
|
13
|
+
* - SwitchVariable: walks `value`, `value_map`, `default`
|
|
14
|
+
* - StateVariable: walks `parent_variable`
|
|
15
|
+
* - SingleVariable: walks `default` (can be DerivedVariable via create_from_derived)
|
|
16
|
+
* - StreamVariable: collects it and walks its `variables` array
|
|
17
|
+
*
|
|
18
|
+
* @param variable The variable to search
|
|
19
|
+
* @returns Array of all StreamVariables found in the dependency tree
|
|
20
|
+
*/
|
|
21
|
+
export declare function findStreamVariables(variable: AnyVariable<unknown>): StreamVariable[];
|
|
22
|
+
/**
|
|
23
|
+
* Find all StreamVariables in an array of variables.
|
|
24
|
+
*
|
|
25
|
+
* @param variables Array of variables to search
|
|
26
|
+
* @returns Array of all unique StreamVariables found
|
|
27
|
+
*/
|
|
28
|
+
export declare function findStreamVariablesInArray(variables: unknown[]): StreamVariable[];
|
|
29
|
+
//# sourceMappingURL=find-stream-variables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-stream-variables.d.ts","sourceRoot":"","sources":["../../../js/shared/interactivity/find-stream-variables.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,cAAc,EAOtB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,cAAc,EAAE,CA6DpF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAiBjF"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Find Stream Variables
|
|
3
|
+
*
|
|
4
|
+
* Recursively walks a variable's dependency tree to find all StreamVariables.
|
|
5
|
+
* Used for tracking stream usage when components mount/unmount.
|
|
6
|
+
*/
|
|
7
|
+
import { isCondition, isDerivedVariable, isStateVariable, isStreamVariable, isSwitchVariable, isVariable, } from '../../types';
|
|
8
|
+
/**
|
|
9
|
+
* Recursively find all StreamVariables in a variable's dependency tree.
|
|
10
|
+
*
|
|
11
|
+
* Handles all variable types:
|
|
12
|
+
* - DerivedVariable: walks `variables` array
|
|
13
|
+
* - SwitchVariable: walks `value`, `value_map`, `default`
|
|
14
|
+
* - StateVariable: walks `parent_variable`
|
|
15
|
+
* - SingleVariable: walks `default` (can be DerivedVariable via create_from_derived)
|
|
16
|
+
* - StreamVariable: collects it and walks its `variables` array
|
|
17
|
+
*
|
|
18
|
+
* @param variable The variable to search
|
|
19
|
+
* @returns Array of all StreamVariables found in the dependency tree
|
|
20
|
+
*/
|
|
21
|
+
export function findStreamVariables(variable) {
|
|
22
|
+
const streams = [];
|
|
23
|
+
const visited = new Set();
|
|
24
|
+
function walk(v) {
|
|
25
|
+
if (!isVariable(v)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Prevent infinite loops from circular dependencies
|
|
29
|
+
if (visited.has(v.uid)) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
visited.add(v.uid);
|
|
33
|
+
if (isStreamVariable(v)) {
|
|
34
|
+
streams.push(v);
|
|
35
|
+
// Also walk stream's own dependencies (stream can depend on other variables)
|
|
36
|
+
if (v.variables && Array.isArray(v.variables)) {
|
|
37
|
+
v.variables.forEach(walk);
|
|
38
|
+
}
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (isDerivedVariable(v)) {
|
|
42
|
+
if (v.variables && Array.isArray(v.variables)) {
|
|
43
|
+
v.variables.forEach(walk);
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (isSwitchVariable(v)) {
|
|
48
|
+
// value can be Variable or Condition (which has .variable)
|
|
49
|
+
if (isVariable(v.value)) {
|
|
50
|
+
walk(v.value);
|
|
51
|
+
}
|
|
52
|
+
else if (isCondition(v.value)) {
|
|
53
|
+
walk(v.value.variable);
|
|
54
|
+
}
|
|
55
|
+
// value_map is Record<string, Variable> - walk all values
|
|
56
|
+
if (v.value_map && typeof v.value_map === 'object') {
|
|
57
|
+
Object.values(v.value_map).forEach(walk);
|
|
58
|
+
}
|
|
59
|
+
if (isVariable(v.default)) {
|
|
60
|
+
walk(v.default);
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (isStateVariable(v)) {
|
|
65
|
+
walk(v.parent_variable);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// SingleVariable (plain variable) - default can be DerivedVariable
|
|
69
|
+
if ('default' in v && isVariable(v.default)) {
|
|
70
|
+
walk(v.default);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
walk(variable);
|
|
74
|
+
return streams;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Find all StreamVariables in an array of variables.
|
|
78
|
+
*
|
|
79
|
+
* @param variables Array of variables to search
|
|
80
|
+
* @returns Array of all unique StreamVariables found
|
|
81
|
+
*/
|
|
82
|
+
export function findStreamVariablesInArray(variables) {
|
|
83
|
+
const allStreams = [];
|
|
84
|
+
const seenUids = new Set();
|
|
85
|
+
for (const v of variables) {
|
|
86
|
+
if (isVariable(v)) {
|
|
87
|
+
const streams = findStreamVariables(v);
|
|
88
|
+
for (const stream of streams) {
|
|
89
|
+
if (!seenUids.has(stream.uid)) {
|
|
90
|
+
seenUids.add(stream.uid);
|
|
91
|
+
allStreams.push(stream);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return allStreams;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=find-stream-variables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-stream-variables.js","sourceRoot":"","sources":["../../../js/shared/interactivity/find-stream-variables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream Usage Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks which stream variables are actively used by components via useEffect.
|
|
5
|
+
* This is the ONLY reliable signal for component lifecycle (not render-time).
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* 1. Atom effect starts SSE immediately and registers a cleanup callback
|
|
9
|
+
* 2. Components register via useEffect (increment count)
|
|
10
|
+
* 3. Components unregister via useEffect cleanup (decrement count)
|
|
11
|
+
* 4. When count hits 0 → debounce → call cleanup callbacks → SSE stops
|
|
12
|
+
*
|
|
13
|
+
* The atom effect cleanup is NOT reliable (Recoil caching), so we actively
|
|
14
|
+
* manage cleanup from here when components unregister.
|
|
15
|
+
*
|
|
16
|
+
* Subscriptions are keyed by uid+extras to handle different auth contexts
|
|
17
|
+
* using the same variable independently.
|
|
18
|
+
*/
|
|
19
|
+
import { type RequestExtras } from '../../api/http';
|
|
20
|
+
interface StreamConnection {
|
|
21
|
+
/** Function to start/restart the SSE connection, returns cleanup and controller */
|
|
22
|
+
start: () => {
|
|
23
|
+
cleanup: () => void;
|
|
24
|
+
controller: AbortController;
|
|
25
|
+
};
|
|
26
|
+
/** Cleanup function to abort SSE connection (set when start() is called) */
|
|
27
|
+
cleanup?: () => void;
|
|
28
|
+
/** AbortController for this connection (for direct abort access) */
|
|
29
|
+
controller?: AbortController;
|
|
30
|
+
/** Whether connection is currently active */
|
|
31
|
+
active: boolean;
|
|
32
|
+
}
|
|
33
|
+
interface StreamUsage {
|
|
34
|
+
/** Number of components actively subscribed (via useEffect) */
|
|
35
|
+
count: number;
|
|
36
|
+
/** Timer for debounced cleanup when count reaches 0 */
|
|
37
|
+
cleanupTimer?: ReturnType<typeof setTimeout>;
|
|
38
|
+
/** Timer for orphan cleanup when connection registers but no subscription arrives */
|
|
39
|
+
orphanTimer?: ReturnType<typeof setTimeout>;
|
|
40
|
+
/** Registered connections for this uid (atomKey -> connection) */
|
|
41
|
+
connections: Map<string, StreamConnection>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Abort an existing connection for the given atomKey, if one exists.
|
|
45
|
+
* Called before starting a new connection to ensure no duplicates.
|
|
46
|
+
*
|
|
47
|
+
* @param atomKey Unique key for the connection (serialized params)
|
|
48
|
+
* @returns true if a connection was aborted, false otherwise
|
|
49
|
+
*/
|
|
50
|
+
export declare function abortExistingConnection(atomKey: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Register a stream connection from atom effect.
|
|
53
|
+
* The start function is called immediately, and will be called again
|
|
54
|
+
* if the connection needs to restart after cleanup.
|
|
55
|
+
*
|
|
56
|
+
* @param uid Stream variable uid
|
|
57
|
+
* @param extras Request extras (auth headers, etc.)
|
|
58
|
+
* @param atomKey Unique key for this connection (serialized params)
|
|
59
|
+
* @param start Function to start the SSE connection, returns { cleanup, controller }
|
|
60
|
+
* @returns Unregister function (backup cleanup, not relied upon)
|
|
61
|
+
*/
|
|
62
|
+
export declare function registerStreamConnection(uid: string, extras: RequestExtras, atomKey: string, start: () => {
|
|
63
|
+
cleanup: () => void;
|
|
64
|
+
controller: AbortController;
|
|
65
|
+
}): () => void;
|
|
66
|
+
/**
|
|
67
|
+
* Subscribe to a stream. Call this from component useEffect.
|
|
68
|
+
*
|
|
69
|
+
* @param uid Stream variable uid
|
|
70
|
+
* @param extras Request extras (auth headers, etc.)
|
|
71
|
+
* @returns Unsubscribe function to call in useEffect cleanup
|
|
72
|
+
*/
|
|
73
|
+
export declare function subscribeStream(uid: string, extras: RequestExtras): () => void;
|
|
74
|
+
/**
|
|
75
|
+
* Check if a stream has active subscribers.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isStreamActive(uid: string, extras: RequestExtras): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Get subscriber count for a stream.
|
|
80
|
+
*/
|
|
81
|
+
export declare function getStreamSubscriberCount(uid: string, extras: RequestExtras): number;
|
|
82
|
+
/**
|
|
83
|
+
* Force cleanup all streams. Useful for testing or app shutdown.
|
|
84
|
+
*/
|
|
85
|
+
export declare function cleanupAllStreams(): void;
|
|
86
|
+
/**
|
|
87
|
+
* Clear all stream usage tracking. Used for testing.
|
|
88
|
+
*/
|
|
89
|
+
export declare function clearStreamUsage_TEST(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Get total count of active connections across all subscription keys.
|
|
92
|
+
* Useful for testing.
|
|
93
|
+
*/
|
|
94
|
+
export declare function getActiveConnectionCount(): number;
|
|
95
|
+
/**
|
|
96
|
+
* Get all active connection keys (atomKeys).
|
|
97
|
+
* Useful for testing.
|
|
98
|
+
*/
|
|
99
|
+
export declare function getActiveConnectionKeys(): string[];
|
|
100
|
+
/**
|
|
101
|
+
* Get the AbortController for a specific atomKey, if active.
|
|
102
|
+
* Useful for testing.
|
|
103
|
+
*/
|
|
104
|
+
export declare function getConnectionController(atomKey: string): AbortController | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Internal exports for testing
|
|
107
|
+
*/
|
|
108
|
+
export declare const _internal: {
|
|
109
|
+
streamUsage: Map<string, StreamUsage>;
|
|
110
|
+
PAUSE_DEBOUNCE_MS: number;
|
|
111
|
+
ORPHAN_TIMEOUT_MS: number;
|
|
112
|
+
};
|
|
113
|
+
export {};
|
|
114
|
+
//# sourceMappingURL=stream-usage-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-usage-tracker.d.ts","sourceRoot":"","sources":["../../../js/shared/interactivity/stream-usage-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAgBhD,UAAU,gBAAgB;IACtB,mFAAmF;IACnF,KAAK,EAAE,MAAM;QAAE,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,UAAU,EAAE,eAAe,CAAA;KAAE,CAAC;IAClE,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,oEAAoE;IACpE,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,WAAW;IACjB,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC7C,qFAAqF;IACrF,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAC5C,kEAAkE;IAClE,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC9C;AAwED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAahE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wBAAwB,CACpC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM;IAAE,OAAO,EAAE,MAAM,IAAI,CAAC;IAAC,UAAU,EAAE,eAAe,CAAA;CAAE,GAClE,MAAM,IAAI,CAkDZ;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,IAAI,CAuC9E;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAI1E;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAGnF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAexC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAUjD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAUlD;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAQpF;AAED;;GAEG;AACH,eAAO,MAAM,SAAS;;;;CAIrB,CAAC"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stream Usage Tracker
|
|
3
|
+
*
|
|
4
|
+
* Tracks which stream variables are actively used by components via useEffect.
|
|
5
|
+
* This is the ONLY reliable signal for component lifecycle (not render-time).
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* 1. Atom effect starts SSE immediately and registers a cleanup callback
|
|
9
|
+
* 2. Components register via useEffect (increment count)
|
|
10
|
+
* 3. Components unregister via useEffect cleanup (decrement count)
|
|
11
|
+
* 4. When count hits 0 → debounce → call cleanup callbacks → SSE stops
|
|
12
|
+
*
|
|
13
|
+
* The atom effect cleanup is NOT reliable (Recoil caching), so we actively
|
|
14
|
+
* manage cleanup from here when components unregister.
|
|
15
|
+
*
|
|
16
|
+
* Subscriptions are keyed by uid+extras to handle different auth contexts
|
|
17
|
+
* using the same variable independently.
|
|
18
|
+
*/
|
|
19
|
+
import {} from '../../api/http';
|
|
20
|
+
/** Debounce period before pausing an unused stream (ms) */
|
|
21
|
+
const PAUSE_DEBOUNCE_MS = 1500;
|
|
22
|
+
/** Timeout for orphaned connections - if no subscription arrives within this period, cleanup (ms) */
|
|
23
|
+
const ORPHAN_TIMEOUT_MS = 5000;
|
|
24
|
+
/**
|
|
25
|
+
* Create a stable subscription key from uid and extras.
|
|
26
|
+
* Different extras (auth contexts) get independent subscription tracking.
|
|
27
|
+
*/
|
|
28
|
+
function createSubscriptionKey(uid, extras) {
|
|
29
|
+
return `${uid}::${JSON.stringify(extras)}`;
|
|
30
|
+
}
|
|
31
|
+
/** Map of subscription key (uid+extras) -> usage state */
|
|
32
|
+
const streamUsage = new Map();
|
|
33
|
+
/**
|
|
34
|
+
* Get or create usage entry for a subscription key
|
|
35
|
+
*/
|
|
36
|
+
function getOrCreateUsage(key) {
|
|
37
|
+
let usage = streamUsage.get(key);
|
|
38
|
+
if (!usage) {
|
|
39
|
+
usage = { count: 0, connections: new Map() };
|
|
40
|
+
streamUsage.set(key, usage);
|
|
41
|
+
}
|
|
42
|
+
return usage;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Try to cleanup all connections for a subscription key.
|
|
46
|
+
* Called after debounce when count reaches 0.
|
|
47
|
+
*/
|
|
48
|
+
function cleanupConnections(key) {
|
|
49
|
+
const usage = streamUsage.get(key);
|
|
50
|
+
if (!usage) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Only cleanup if count is still 0
|
|
54
|
+
if (usage.count > 0) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Abort all active connections
|
|
58
|
+
for (const [, conn] of usage.connections) {
|
|
59
|
+
if (conn.active) {
|
|
60
|
+
if (conn.controller) {
|
|
61
|
+
conn.controller.abort();
|
|
62
|
+
}
|
|
63
|
+
conn.cleanup = undefined;
|
|
64
|
+
conn.controller = undefined;
|
|
65
|
+
conn.active = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Restart inactive connections for a subscription key.
|
|
71
|
+
* Called when a new subscription comes in after cleanup.
|
|
72
|
+
*/
|
|
73
|
+
function restartConnections(key) {
|
|
74
|
+
const usage = streamUsage.get(key);
|
|
75
|
+
if (!usage) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
// Restart any inactive connections
|
|
79
|
+
for (const [atomKey, conn] of usage.connections) {
|
|
80
|
+
if (!conn.active) {
|
|
81
|
+
try {
|
|
82
|
+
const { cleanup, controller } = conn.start();
|
|
83
|
+
conn.cleanup = cleanup;
|
|
84
|
+
conn.controller = controller;
|
|
85
|
+
conn.active = true;
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
// Log but don't throw - allow other connections to restart
|
|
89
|
+
// eslint-disable-next-line no-console
|
|
90
|
+
console.error(`Failed to restart stream connection ${atomKey}:`, err);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Abort an existing connection for the given atomKey, if one exists.
|
|
97
|
+
* Called before starting a new connection to ensure no duplicates.
|
|
98
|
+
*
|
|
99
|
+
* @param atomKey Unique key for the connection (serialized params)
|
|
100
|
+
* @returns true if a connection was aborted, false otherwise
|
|
101
|
+
*/
|
|
102
|
+
export function abortExistingConnection(atomKey) {
|
|
103
|
+
// Search all usage entries for this atomKey
|
|
104
|
+
for (const usage of streamUsage.values()) {
|
|
105
|
+
const conn = usage.connections.get(atomKey);
|
|
106
|
+
if ((conn === null || conn === void 0 ? void 0 : conn.active) && conn.controller) {
|
|
107
|
+
conn.controller.abort();
|
|
108
|
+
conn.active = false;
|
|
109
|
+
conn.cleanup = undefined;
|
|
110
|
+
conn.controller = undefined;
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Register a stream connection from atom effect.
|
|
118
|
+
* The start function is called immediately, and will be called again
|
|
119
|
+
* if the connection needs to restart after cleanup.
|
|
120
|
+
*
|
|
121
|
+
* @param uid Stream variable uid
|
|
122
|
+
* @param extras Request extras (auth headers, etc.)
|
|
123
|
+
* @param atomKey Unique key for this connection (serialized params)
|
|
124
|
+
* @param start Function to start the SSE connection, returns { cleanup, controller }
|
|
125
|
+
* @returns Unregister function (backup cleanup, not relied upon)
|
|
126
|
+
*/
|
|
127
|
+
export function registerStreamConnection(uid, extras, atomKey, start) {
|
|
128
|
+
const key = createSubscriptionKey(uid, extras);
|
|
129
|
+
const usage = getOrCreateUsage(key);
|
|
130
|
+
// Abort any existing connection for this atomKey (defensive)
|
|
131
|
+
abortExistingConnection(atomKey);
|
|
132
|
+
// Start the connection immediately
|
|
133
|
+
const { cleanup, controller } = start();
|
|
134
|
+
// Register the connection with the start function for potential restart
|
|
135
|
+
usage.connections.set(atomKey, { start, cleanup, controller, active: true });
|
|
136
|
+
// If no subscribers yet, start orphan timer - cleanup if no subscription arrives
|
|
137
|
+
if (usage.count === 0 && !usage.orphanTimer) {
|
|
138
|
+
usage.orphanTimer = setTimeout(() => {
|
|
139
|
+
usage.orphanTimer = undefined;
|
|
140
|
+
// If still no subscribers, this connection is orphaned
|
|
141
|
+
if (usage.count === 0) {
|
|
142
|
+
cleanupConnections(key);
|
|
143
|
+
}
|
|
144
|
+
}, ORPHAN_TIMEOUT_MS);
|
|
145
|
+
}
|
|
146
|
+
// Return unregister function (backup, called if atom effect cleanup actually runs)
|
|
147
|
+
return () => {
|
|
148
|
+
const currentUsage = streamUsage.get(key);
|
|
149
|
+
if (!currentUsage) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const conn = currentUsage.connections.get(atomKey);
|
|
153
|
+
if (conn === null || conn === void 0 ? void 0 : conn.active) {
|
|
154
|
+
if (conn.controller) {
|
|
155
|
+
conn.controller.abort();
|
|
156
|
+
}
|
|
157
|
+
conn.cleanup = undefined;
|
|
158
|
+
conn.controller = undefined;
|
|
159
|
+
conn.active = false;
|
|
160
|
+
}
|
|
161
|
+
currentUsage.connections.delete(atomKey);
|
|
162
|
+
// Clean up usage entry if no connections remain
|
|
163
|
+
if (currentUsage.connections.size === 0 && currentUsage.count === 0) {
|
|
164
|
+
if (currentUsage.cleanupTimer) {
|
|
165
|
+
clearTimeout(currentUsage.cleanupTimer);
|
|
166
|
+
}
|
|
167
|
+
streamUsage.delete(key);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Subscribe to a stream. Call this from component useEffect.
|
|
173
|
+
*
|
|
174
|
+
* @param uid Stream variable uid
|
|
175
|
+
* @param extras Request extras (auth headers, etc.)
|
|
176
|
+
* @returns Unsubscribe function to call in useEffect cleanup
|
|
177
|
+
*/
|
|
178
|
+
export function subscribeStream(uid, extras) {
|
|
179
|
+
const key = createSubscriptionKey(uid, extras);
|
|
180
|
+
const usage = getOrCreateUsage(key);
|
|
181
|
+
// Cancel any pending cleanup or orphan timers
|
|
182
|
+
if (usage.cleanupTimer) {
|
|
183
|
+
clearTimeout(usage.cleanupTimer);
|
|
184
|
+
usage.cleanupTimer = undefined;
|
|
185
|
+
}
|
|
186
|
+
if (usage.orphanTimer) {
|
|
187
|
+
clearTimeout(usage.orphanTimer);
|
|
188
|
+
usage.orphanTimer = undefined;
|
|
189
|
+
}
|
|
190
|
+
const wasEmpty = usage.count === 0;
|
|
191
|
+
usage.count++;
|
|
192
|
+
// If count was 0, restart any inactive connections
|
|
193
|
+
if (wasEmpty) {
|
|
194
|
+
restartConnections(key);
|
|
195
|
+
}
|
|
196
|
+
// Return unsubscribe function
|
|
197
|
+
return () => {
|
|
198
|
+
const currentUsage = streamUsage.get(key);
|
|
199
|
+
if (!currentUsage) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
currentUsage.count = Math.max(0, currentUsage.count - 1);
|
|
203
|
+
if (currentUsage.count === 0) {
|
|
204
|
+
// Schedule cleanup after debounce
|
|
205
|
+
currentUsage.cleanupTimer = setTimeout(() => {
|
|
206
|
+
currentUsage.cleanupTimer = undefined;
|
|
207
|
+
cleanupConnections(key);
|
|
208
|
+
}, PAUSE_DEBOUNCE_MS);
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if a stream has active subscribers.
|
|
214
|
+
*/
|
|
215
|
+
export function isStreamActive(uid, extras) {
|
|
216
|
+
const key = createSubscriptionKey(uid, extras);
|
|
217
|
+
const usage = streamUsage.get(key);
|
|
218
|
+
return usage !== undefined && usage.count > 0;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Get subscriber count for a stream.
|
|
222
|
+
*/
|
|
223
|
+
export function getStreamSubscriberCount(uid, extras) {
|
|
224
|
+
var _a, _b;
|
|
225
|
+
const key = createSubscriptionKey(uid, extras);
|
|
226
|
+
return (_b = (_a = streamUsage.get(key)) === null || _a === void 0 ? void 0 : _a.count) !== null && _b !== void 0 ? _b : 0;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Force cleanup all streams. Useful for testing or app shutdown.
|
|
230
|
+
*/
|
|
231
|
+
export function cleanupAllStreams() {
|
|
232
|
+
for (const [, usage] of streamUsage) {
|
|
233
|
+
if (usage.cleanupTimer) {
|
|
234
|
+
clearTimeout(usage.cleanupTimer);
|
|
235
|
+
}
|
|
236
|
+
if (usage.orphanTimer) {
|
|
237
|
+
clearTimeout(usage.orphanTimer);
|
|
238
|
+
}
|
|
239
|
+
for (const conn of usage.connections.values()) {
|
|
240
|
+
if (conn.active && conn.controller) {
|
|
241
|
+
conn.controller.abort();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
streamUsage.clear();
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Clear all stream usage tracking. Used for testing.
|
|
249
|
+
*/
|
|
250
|
+
export function clearStreamUsage_TEST() {
|
|
251
|
+
cleanupAllStreams();
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Get total count of active connections across all subscription keys.
|
|
255
|
+
* Useful for testing.
|
|
256
|
+
*/
|
|
257
|
+
export function getActiveConnectionCount() {
|
|
258
|
+
let count = 0;
|
|
259
|
+
for (const usage of streamUsage.values()) {
|
|
260
|
+
for (const conn of usage.connections.values()) {
|
|
261
|
+
if (conn.active) {
|
|
262
|
+
count++;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return count;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Get all active connection keys (atomKeys).
|
|
270
|
+
* Useful for testing.
|
|
271
|
+
*/
|
|
272
|
+
export function getActiveConnectionKeys() {
|
|
273
|
+
const keys = [];
|
|
274
|
+
for (const usage of streamUsage.values()) {
|
|
275
|
+
for (const [atomKey, conn] of usage.connections) {
|
|
276
|
+
if (conn.active) {
|
|
277
|
+
keys.push(atomKey);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return keys;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get the AbortController for a specific atomKey, if active.
|
|
285
|
+
* Useful for testing.
|
|
286
|
+
*/
|
|
287
|
+
export function getConnectionController(atomKey) {
|
|
288
|
+
for (const usage of streamUsage.values()) {
|
|
289
|
+
const conn = usage.connections.get(atomKey);
|
|
290
|
+
if ((conn === null || conn === void 0 ? void 0 : conn.active) && conn.controller) {
|
|
291
|
+
return conn.controller;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Internal exports for testing
|
|
298
|
+
*/
|
|
299
|
+
export const _internal = {
|
|
300
|
+
streamUsage,
|
|
301
|
+
PAUSE_DEBOUNCE_MS,
|
|
302
|
+
ORPHAN_TIMEOUT_MS,
|
|
303
|
+
};
|
|
304
|
+
//# sourceMappingURL=stream-usage-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-usage-tracker.js","sourceRoot":"","sources":["../../../js/shared/interactivity/stream-usage-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -97,13 +97,16 @@ interface StreamConnectionCallbacks {
|
|
|
97
97
|
*
|
|
98
98
|
* @param params Stream atom params (contains uid, resolved values, etc.)
|
|
99
99
|
* @param callbacks Callbacks for stream events
|
|
100
|
-
* @returns
|
|
100
|
+
* @returns Object with cleanup function and AbortController
|
|
101
101
|
*/
|
|
102
|
-
declare function startStreamConnection(params: StreamAtomParams, callbacks: StreamConnectionCallbacks):
|
|
102
|
+
declare function startStreamConnection(params: StreamAtomParams, callbacks: StreamConnectionCallbacks): {
|
|
103
|
+
cleanup: () => void;
|
|
104
|
+
controller: AbortController;
|
|
105
|
+
};
|
|
103
106
|
/**
|
|
104
107
|
* Get or create a stream variable atom for the given params.
|
|
105
108
|
* The atom has effects that manage the SSE connection lifecycle.
|
|
106
|
-
*
|
|
109
|
+
* Uses Recoil's atomFamily internal caching - no external registry needed.
|
|
107
110
|
*
|
|
108
111
|
* @param atomKey Serialized StreamAtomParams
|
|
109
112
|
* @returns Recoil atom for stream state
|
|
@@ -127,7 +130,6 @@ export declare function getOrRegisterStreamVariable(variable: StreamVariable, cl
|
|
|
127
130
|
*/
|
|
128
131
|
export declare const _internal: {
|
|
129
132
|
streamAtomFamily: (param: string) => RecoilState<StreamState>;
|
|
130
|
-
activeConnections: Map<string, AbortController>;
|
|
131
133
|
getBackoffDelay: typeof getBackoffDelay;
|
|
132
134
|
serializeAtomParams: typeof serializeAtomParams;
|
|
133
135
|
deserializeAtomParams: typeof deserializeAtomParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-variable.d.ts","sourceRoot":"","sources":["../../../js/shared/interactivity/stream-variable.tsx"],"names":[],"mappings":"AA6BA,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,WAAW,EAA8B,MAAM,QAAQ,CAAC;AAIzG,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAc,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"stream-variable.d.ts","sourceRoot":"","sources":["../../../js/shared/interactivity/stream-variable.tsx"],"names":[],"mappings":"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"}
|