@jqhtml/core 2.3.59 → 2.3.64
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/boot.d.ts +0 -0
- package/dist/boot.d.ts.map +0 -0
- package/dist/cache-key-serializer.d.ts +0 -0
- package/dist/cache-key-serializer.d.ts.map +0 -0
- package/dist/component-cache.d.ts +0 -0
- package/dist/component-cache.d.ts.map +0 -0
- package/dist/component-events.d.ts +0 -0
- package/dist/component-events.d.ts.map +0 -0
- package/dist/component-name.d.ts +13 -0
- package/dist/component-name.d.ts.map +1 -0
- package/dist/component-queue.d.ts +0 -0
- package/dist/component-queue.d.ts.map +0 -0
- package/dist/component-registry.d.ts +0 -0
- package/dist/component-registry.d.ts.map +1 -1
- package/dist/component.d.ts +2 -6
- package/dist/component.d.ts.map +1 -1
- package/dist/config.d.ts +0 -0
- package/dist/config.d.ts.map +0 -0
- package/dist/data-proxy.d.ts +0 -0
- package/dist/data-proxy.d.ts.map +0 -0
- package/dist/debug-entry.d.ts +0 -0
- package/dist/debug-entry.d.ts.map +0 -0
- package/dist/debug.d.ts +0 -0
- package/dist/debug.d.ts.map +0 -0
- package/dist/index.cjs +60 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +58 -45
- package/dist/index.js.map +1 -1
- package/dist/instruction-processor.d.ts +2 -1
- package/dist/instruction-processor.d.ts.map +1 -1
- package/dist/jqhtml-core.esm.js +59 -46
- package/dist/jqhtml-core.esm.js.map +1 -1
- package/dist/jqhtml-debug.esm.js +0 -0
- package/dist/jqhtml-debug.esm.js.map +0 -0
- package/dist/jquery-plugin.d.ts +0 -0
- package/dist/jquery-plugin.d.ts.map +1 -1
- package/dist/lifecycle-manager.d.ts +0 -0
- package/dist/lifecycle-manager.d.ts.map +0 -0
- package/dist/load-coordinator.d.ts +0 -0
- package/dist/load-coordinator.d.ts.map +0 -0
- package/dist/local-storage.d.ts +0 -0
- package/dist/local-storage.d.ts.map +0 -0
- package/dist/preload-data.d.ts +0 -0
- package/dist/preload-data.d.ts.map +0 -0
- package/dist/template-renderer.d.ts +0 -0
- package/dist/template-renderer.d.ts.map +0 -0
- package/dist/viewport.d.ts +0 -0
- package/dist/viewport.d.ts.map +0 -0
- package/package.json +1 -1
- package/dist/boot.js +0 -130
- package/dist/boot.js.map +0 -1
- package/dist/cache-key-serializer.js +0 -140
- package/dist/cache-key-serializer.js.map +0 -1
- package/dist/component-cache.js +0 -270
- package/dist/component-cache.js.map +0 -1
- package/dist/component-events.js +0 -141
- package/dist/component-events.js.map +0 -1
- package/dist/component-queue.js +0 -118
- package/dist/component-queue.js.map +0 -1
- package/dist/component-registry.js +0 -298
- package/dist/component-registry.js.map +0 -1
- package/dist/component.js +0 -1892
- package/dist/component.js.map +0 -1
- package/dist/config.js +0 -64
- package/dist/config.js.map +0 -1
- package/dist/data-proxy.js +0 -223
- package/dist/data-proxy.js.map +0 -1
- package/dist/debug-entry.js +0 -8
- package/dist/debug-entry.js.map +0 -1
- package/dist/debug.js +0 -203
- package/dist/debug.js.map +0 -1
- package/dist/instruction-processor.js +0 -563
- package/dist/instruction-processor.js.map +0 -1
- package/dist/jquery-plugin.js +0 -472
- package/dist/jquery-plugin.js.map +0 -1
- package/dist/lifecycle-manager.js +0 -201
- package/dist/lifecycle-manager.js.map +0 -1
- package/dist/load-coordinator.js +0 -309
- package/dist/load-coordinator.js.map +0 -1
- package/dist/local-storage.js +0 -699
- package/dist/local-storage.js.map +0 -1
- package/dist/preload-data.js +0 -136
- package/dist/preload-data.js.map +0 -1
- package/dist/template-renderer.js +0 -278
- package/dist/template-renderer.js.map +0 -1
- package/dist/viewport.js +0 -69
- package/dist/viewport.js.map +0 -1
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JQHTML v2 Lifecycle Manager
|
|
3
|
-
*
|
|
4
|
-
* Simple lifecycle orchestration - no queues, no batching.
|
|
5
|
-
* Components boot when created. That's it.
|
|
6
|
-
*
|
|
7
|
-
* Lifecycle order:
|
|
8
|
-
* 1. create() - SYNC - Calls on_create() BEFORE first render
|
|
9
|
-
* 2. render() - SYNC - Creates DOM, instantiates child components, calls on_render()
|
|
10
|
-
* 3. _load() - ASYNC - Calls on_load() if overridden, may trigger re-render if this.data changes
|
|
11
|
-
* 4. ready() - ASYNC - Waits for children to be ready, calls on_ready()
|
|
12
|
-
*
|
|
13
|
-
* Key insight: create/render/on_render are synchronous. If a component doesn't
|
|
14
|
-
* override on_load(), the entire create→render→on_render chain completes without
|
|
15
|
-
* yielding to the event loop. This means parent components can access child
|
|
16
|
-
* components in their on_render() as long as the children don't have async on_load().
|
|
17
|
-
*/
|
|
18
|
-
export class LifecycleManager {
|
|
19
|
-
static get_instance() {
|
|
20
|
-
if (!LifecycleManager.instance) {
|
|
21
|
-
LifecycleManager.instance = new LifecycleManager();
|
|
22
|
-
}
|
|
23
|
-
return LifecycleManager.instance;
|
|
24
|
-
}
|
|
25
|
-
constructor() {
|
|
26
|
-
this.active_components = new Set();
|
|
27
|
-
// No automatic cleanup on DOM removal - components stop explicitly via:
|
|
28
|
-
// 1. Parent component re-render (calls .empty() which stops children)
|
|
29
|
-
// 2. Manual .empty(), .html(), .text() calls (overridden to stop children)
|
|
30
|
-
// 3. Explicit .stop() call
|
|
31
|
-
// This allows components to be moved in DOM without lifecycle interruption
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Boot a component - run its full lifecycle
|
|
35
|
-
* Called when component is created
|
|
36
|
-
*
|
|
37
|
-
* Supports lifecycle truncation flags:
|
|
38
|
-
* - _load_only: on_create + on_load only. No render, no children, no on_render, no on_loaded, no on_ready.
|
|
39
|
-
* - _load_render_only: on_create + render + on_load + re-render. No on_render, no on_loaded, no on_ready.
|
|
40
|
-
*/
|
|
41
|
-
async boot_component(component) {
|
|
42
|
-
this.active_components.add(component);
|
|
43
|
-
try {
|
|
44
|
-
// Create phase - SYNCHRONOUS, runs BEFORE first render
|
|
45
|
-
component.create();
|
|
46
|
-
// Check if stopped during create
|
|
47
|
-
if (component._stopped)
|
|
48
|
-
return;
|
|
49
|
-
// Trigger create event
|
|
50
|
-
component.trigger('create');
|
|
51
|
-
// Check for lifecycle truncation flags
|
|
52
|
-
const load_only = component._load_only;
|
|
53
|
-
const load_render_only = component._load_render_only;
|
|
54
|
-
const is_detached = component._is_detached;
|
|
55
|
-
let render_id;
|
|
56
|
-
if (load_only || is_detached) {
|
|
57
|
-
// _load_only or detached: skip initial render entirely
|
|
58
|
-
render_id = 0;
|
|
59
|
-
component._render_count = 0;
|
|
60
|
-
}
|
|
61
|
-
else if (load_render_only) {
|
|
62
|
-
// _load_render_only: render to create children, but skip on_render()
|
|
63
|
-
render_id = component._render(null, { skip_on_render: true });
|
|
64
|
-
// Check if stopped during render
|
|
65
|
-
if (component._stopped)
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
// Normal: render with on_render()
|
|
70
|
-
render_id = component._render();
|
|
71
|
-
// Check if stopped during render
|
|
72
|
-
if (component._stopped)
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// Load phase - ASYNC, but only if on_load() is overridden
|
|
76
|
-
// Skip entirely if component uses default stub to avoid unnecessary yield
|
|
77
|
-
if (component._has_on_load()) {
|
|
78
|
-
// Load gates: await any promises registered via gate_load() during
|
|
79
|
-
// on_create() before the FIRST on_load(). Gates delay ONLY this load
|
|
80
|
-
// phase — create/render/on_render/cached-paint already happened above.
|
|
81
|
-
// Released early by reload()/refresh()/stop() while gated (see component).
|
|
82
|
-
// Returns null (no await) for the common no-gate case to keep timing
|
|
83
|
-
// identical for ungated components.
|
|
84
|
-
const gate_wait = component._await_load_gates();
|
|
85
|
-
if (gate_wait) {
|
|
86
|
-
await gate_wait;
|
|
87
|
-
// Check if stopped while awaiting gates
|
|
88
|
-
if (component._stopped)
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
await component._load();
|
|
92
|
-
// Yield to microtask queue after on_load completes
|
|
93
|
-
// This ensures async queue tasks always run before the on_load process completes,
|
|
94
|
-
// even if on_load() itself completes instantly (deterministic behavior)
|
|
95
|
-
await Promise.resolve();
|
|
96
|
-
}
|
|
97
|
-
// Check if stopped during load
|
|
98
|
-
if (component._stopped)
|
|
99
|
-
return;
|
|
100
|
-
// If _load_only, mark component as ready now and return
|
|
101
|
-
if (load_only) {
|
|
102
|
-
component._ready_state = 4;
|
|
103
|
-
component._update_debug_attrs();
|
|
104
|
-
component._log_lifecycle('ready', 'complete (_load_only)');
|
|
105
|
-
component.trigger('ready');
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
// Detached elements always render here (initial render was skipped)
|
|
109
|
-
// Normal elements re-render only if data changed during on_load
|
|
110
|
-
if (is_detached || component._should_rerender()) {
|
|
111
|
-
// Disable animations during re-render to prevent visual artifacts
|
|
112
|
-
// from CSS transitions/animations firing on newly rendered elements
|
|
113
|
-
const $el = component.$;
|
|
114
|
-
if ($el && $el[0]) {
|
|
115
|
-
$el[0].classList.add('__jqhtml_disable_animations');
|
|
116
|
-
// Re-enable animations after animation frame + 5ms
|
|
117
|
-
// This ensures the browser has painted the new DOM before animations resume
|
|
118
|
-
requestAnimationFrame(() => {
|
|
119
|
-
setTimeout(() => {
|
|
120
|
-
// Check component still exists and element is still in DOM
|
|
121
|
-
if (!component._stopped && $el[0].isConnected) {
|
|
122
|
-
$el[0].classList.remove('__jqhtml_disable_animations');
|
|
123
|
-
}
|
|
124
|
-
}, 5);
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
// _load_render_only: re-render with skip_on_render to suppress DOM hooks
|
|
128
|
-
if (load_render_only) {
|
|
129
|
-
render_id = component._render(null, { skip_on_render: true });
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
render_id = component._render();
|
|
133
|
-
}
|
|
134
|
-
// Check if stopped during re-render
|
|
135
|
-
if (component._stopped)
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
// _load_render_only: skip waiting for children, on_ready — mark ready and return
|
|
139
|
-
if (load_render_only) {
|
|
140
|
-
component._ready_state = 4;
|
|
141
|
-
component._update_debug_attrs();
|
|
142
|
-
component._log_lifecycle('ready', 'complete (_load_render_only)');
|
|
143
|
-
component.trigger('ready');
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
// Fire 'rendered' event - component has completed its synchronous render chain
|
|
147
|
-
// This happens once, after the final on_render (whether from first render or re-render after on_load)
|
|
148
|
-
if (!component._has_rendered) {
|
|
149
|
-
component._has_rendered = true;
|
|
150
|
-
component.trigger('rendered');
|
|
151
|
-
}
|
|
152
|
-
// Check if this render is still current before proceeding to ready
|
|
153
|
-
// If _render_count changed, another render happened and we should skip ready
|
|
154
|
-
if (component._render_count !== render_id) {
|
|
155
|
-
return; // Stale render, don't call ready
|
|
156
|
-
}
|
|
157
|
-
// Yield to microtask queue before ready phase
|
|
158
|
-
// This allows any queued async callbacks (e.g., from child component boots)
|
|
159
|
-
// to execute before on_ready() runs, without triggering a paint cycle.
|
|
160
|
-
// Promise.resolve() schedules on microtask queue (not macrotask like setTimeout)
|
|
161
|
-
await Promise.resolve();
|
|
162
|
-
// Re-check stopped state after yield - something may have stopped us
|
|
163
|
-
if (component._stopped)
|
|
164
|
-
return;
|
|
165
|
-
// Re-check render count after yield - another render may have started
|
|
166
|
-
if (component._render_count !== render_id) {
|
|
167
|
-
return; // Stale render, don't call ready
|
|
168
|
-
}
|
|
169
|
-
// Ready phase - waits for children, then calls on_ready()
|
|
170
|
-
await component._ready();
|
|
171
|
-
// Check if stopped during ready
|
|
172
|
-
if (component._stopped)
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
catch (error) {
|
|
176
|
-
console.error(`Error booting component ${component.component_name()}:`, error);
|
|
177
|
-
throw error;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* Unregister a component (called on destroy)
|
|
182
|
-
*/
|
|
183
|
-
unregister_component(component) {
|
|
184
|
-
this.active_components.delete(component);
|
|
185
|
-
}
|
|
186
|
-
/**
|
|
187
|
-
* Wait for all active components to reach ready state
|
|
188
|
-
*/
|
|
189
|
-
async wait_for_ready() {
|
|
190
|
-
const ready_promises = [];
|
|
191
|
-
for (const component of this.active_components) {
|
|
192
|
-
if (component._ready_state < 4) {
|
|
193
|
-
ready_promises.push(new Promise((resolve) => {
|
|
194
|
-
component.on('ready', () => resolve());
|
|
195
|
-
}));
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
await Promise.all(ready_promises);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
//# sourceMappingURL=lifecycle-manager.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle-manager.js","sourceRoot":"","sources":["../src/lifecycle-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/load-coordinator.js
DELETED
|
@@ -1,309 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Load Coordinator - Request deduplication for component on_load() calls
|
|
3
|
-
*
|
|
4
|
-
* Coordinates parallel component loading to prevent duplicate requests.
|
|
5
|
-
* When multiple components with identical names and args load simultaneously,
|
|
6
|
-
* only the first (leader) executes on_load(). Others (followers) wait for
|
|
7
|
-
* the leader's result.
|
|
8
|
-
*
|
|
9
|
-
* Key Concepts:
|
|
10
|
-
* - **INVOCATION_KEY**: Unique identifier for component name + args combination
|
|
11
|
-
* - **Leader**: First component to reach on_load() for a given INVOCATION_KEY
|
|
12
|
-
* - **Follower**: Subsequent components that wait for leader's result
|
|
13
|
-
*
|
|
14
|
-
* Lifecycle:
|
|
15
|
-
* 1. Leader reaches on_load() → create coordination entry
|
|
16
|
-
* 2. Followers reach on_load() → join waiting queue
|
|
17
|
-
* 3. Leader completes → distribute data to all followers
|
|
18
|
-
* 4. Clear coordination entry (no caching)
|
|
19
|
-
*
|
|
20
|
-
* @internal This class is not exposed in the public API
|
|
21
|
-
*/
|
|
22
|
-
import { serialize_for_cache_key } from './cache-key-serializer.js';
|
|
23
|
-
export class Load_Coordinator {
|
|
24
|
-
/**
|
|
25
|
-
* Generate INVOCATION_KEY from component name and args
|
|
26
|
-
* Uses deterministic JSON serialization (sorted keys)
|
|
27
|
-
* Excludes internal properties (those starting with _)
|
|
28
|
-
*
|
|
29
|
-
* For functions/objects:
|
|
30
|
-
* - Checks for ._jqhtml_cache_id property (assigned by RSpade)
|
|
31
|
-
* - Falls back to .jqhtml_cache_id() method if property doesn't exist
|
|
32
|
-
* - If neither exists, marks property as uncacheable
|
|
33
|
-
*
|
|
34
|
-
* Returns object with:
|
|
35
|
-
* - key: Cache key string, or null if uncacheable
|
|
36
|
-
* - uncacheable_property: Name of first property that prevented caching (for debugging)
|
|
37
|
-
*/
|
|
38
|
-
static generate_invocation_key(component_name, args, options = {}) {
|
|
39
|
-
let uncacheable_property;
|
|
40
|
-
let uncacheable_reason;
|
|
41
|
-
// Filter out internal properties (starting with _) and serialize args
|
|
42
|
-
const serializable_args = {};
|
|
43
|
-
for (const key of Object.keys(args).sort()) {
|
|
44
|
-
if (key.startsWith('_')) {
|
|
45
|
-
continue; // Skip internal properties
|
|
46
|
-
}
|
|
47
|
-
// Skip framework properties that shouldn't affect cache identity
|
|
48
|
-
// Note: _load_only and _load_render_only are already filtered by the _ prefix check above
|
|
49
|
-
if (key === 'use_cached_data') {
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const value = args[key];
|
|
53
|
-
const value_type = typeof value;
|
|
54
|
-
// Handle primitives (string, number, boolean, null, undefined)
|
|
55
|
-
if (value === null || value === undefined ||
|
|
56
|
-
value_type === 'string' || value_type === 'number' ||
|
|
57
|
-
value_type === 'boolean') {
|
|
58
|
-
serializable_args[key] = value;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
// Handle functions and objects
|
|
62
|
-
if (value_type === 'function' || value_type === 'object') {
|
|
63
|
-
// Check for ._jqhtml_cache_id property (fastest, what RSpade assigns)
|
|
64
|
-
if (value._jqhtml_cache_id !== undefined) {
|
|
65
|
-
serializable_args[key] = `__JQHTML_CACHE_ID__:${String(value._jqhtml_cache_id)}`;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
// Check for .jqhtml_cache_id() method (more flexible, for custom objects)
|
|
69
|
-
if (typeof value.jqhtml_cache_id === 'function') {
|
|
70
|
-
try {
|
|
71
|
-
const cache_id = value.jqhtml_cache_id();
|
|
72
|
-
serializable_args[key] = `__JQHTML_CACHE_ID__:${String(cache_id)}`;
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
// Method threw error - treat as uncacheable
|
|
77
|
-
if (!uncacheable_property) {
|
|
78
|
-
uncacheable_property = key;
|
|
79
|
-
uncacheable_reason = 'cache-id-threw';
|
|
80
|
-
}
|
|
81
|
-
return { key: null, uncacheable_property, uncacheable_reason };
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// No author-supplied id. The cache may fall back to keying by
|
|
85
|
-
// deterministic content; deduplication deliberately may not.
|
|
86
|
-
if (options.allow_content_serialization) {
|
|
87
|
-
const serialized = serialize_for_cache_key(value);
|
|
88
|
-
if (serialized.ok) {
|
|
89
|
-
serializable_args[key] = `__JQHTML_CONTENT__:${serialized.text}`;
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
if (!uncacheable_property) {
|
|
93
|
-
uncacheable_property = key;
|
|
94
|
-
// This package compiles with strictNullChecks off, and without it
|
|
95
|
-
// TypeScript will not narrow a discriminated union by its boolean
|
|
96
|
-
// discriminant - so `serialized` is still the full Serialize_Result
|
|
97
|
-
// here even though `ok` has been ruled out above. The cast states
|
|
98
|
-
// what the control flow already guarantees.
|
|
99
|
-
uncacheable_reason = serialized.reason;
|
|
100
|
-
}
|
|
101
|
-
return { key: null, uncacheable_property, uncacheable_reason };
|
|
102
|
-
}
|
|
103
|
-
if (!uncacheable_property) {
|
|
104
|
-
uncacheable_property = key;
|
|
105
|
-
uncacheable_reason = value_type === 'function' ? 'function' : 'object';
|
|
106
|
-
}
|
|
107
|
-
return { key: null, uncacheable_property, uncacheable_reason };
|
|
108
|
-
}
|
|
109
|
-
// Unknown type (symbol, bigint, etc.) - uncacheable
|
|
110
|
-
if (!uncacheable_property) {
|
|
111
|
-
uncacheable_property = key;
|
|
112
|
-
uncacheable_reason = value_type;
|
|
113
|
-
}
|
|
114
|
-
return { key: null, uncacheable_property, uncacheable_reason };
|
|
115
|
-
}
|
|
116
|
-
// Try to serialize - if it fails (shouldn't happen now, but safety net), return null
|
|
117
|
-
try {
|
|
118
|
-
const sorted_args = JSON.stringify(serializable_args);
|
|
119
|
-
return { key: `${component_name}::${sorted_args}` };
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
// Serialization failed unexpectedly
|
|
123
|
-
return { key: null, uncacheable_property };
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* Check if a component should execute on_load() or wait for existing request
|
|
128
|
-
* Returns true if component should execute (is leader), false if should wait (is follower)
|
|
129
|
-
*/
|
|
130
|
-
static should_execute_on_load(component) {
|
|
131
|
-
const { key } = this.generate_invocation_key(component.component_name(), component.args);
|
|
132
|
-
// No identity means no coordination. Without this, every un-keyable component
|
|
133
|
-
// would share the single `null` registry entry and adopt an unrelated
|
|
134
|
-
// component's data - the worst failure this system can produce.
|
|
135
|
-
if (key === null) {
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
const entry = this._registry.get(key);
|
|
139
|
-
if (!entry) {
|
|
140
|
-
// No existing request - this component becomes the leader
|
|
141
|
-
return true;
|
|
142
|
-
}
|
|
143
|
-
if (entry.status === 'loading') {
|
|
144
|
-
// Request in progress - this component becomes a follower
|
|
145
|
-
entry.waiting.push(component);
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
// Entry exists but completed/failed - should have been cleaned up
|
|
149
|
-
// Treat as new leader
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Register a leader component that will execute on_load()
|
|
154
|
-
* Creates coordination entry and returns a function to call when data is ready
|
|
155
|
-
*
|
|
156
|
-
* @returns A function that accepts the final data and completes coordination
|
|
157
|
-
*/
|
|
158
|
-
static register_leader(component, on_load_promise) {
|
|
159
|
-
const { key } = this.generate_invocation_key(component.component_name(), component.args);
|
|
160
|
-
// Un-keyable component: run alone, register nothing. See should_execute_on_load().
|
|
161
|
-
if (key === null) {
|
|
162
|
-
return () => { };
|
|
163
|
-
}
|
|
164
|
-
// Create a promise that we control - it resolves when complete_coordination is called
|
|
165
|
-
let resolve_promise;
|
|
166
|
-
const coordination_promise = new Promise((resolve) => {
|
|
167
|
-
resolve_promise = resolve;
|
|
168
|
-
});
|
|
169
|
-
const entry = {
|
|
170
|
-
status: 'loading',
|
|
171
|
-
promise: coordination_promise, // Followers await THIS promise, not on_load_promise
|
|
172
|
-
resolve_promise,
|
|
173
|
-
leader_component: component,
|
|
174
|
-
leader_data: null,
|
|
175
|
-
leader_error: null,
|
|
176
|
-
waiting: []
|
|
177
|
-
};
|
|
178
|
-
this._registry.set(key, entry);
|
|
179
|
-
// Return cleanup function that accepts the final data
|
|
180
|
-
return (final_data) => this._complete_coordination(key, component, final_data);
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Get the coordination promise for a follower component
|
|
184
|
-
* Returns a promise that resolves when the leader completes
|
|
185
|
-
*/
|
|
186
|
-
static get_coordination_promise(component) {
|
|
187
|
-
const { key } = this.generate_invocation_key(component.component_name(), component.args);
|
|
188
|
-
const entry = this._registry.get(key);
|
|
189
|
-
if (!entry || entry.status !== 'loading') {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
return entry.promise;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Complete coordination after leader's on_load() finishes
|
|
196
|
-
* Stores leader's data, marks entry as completed, and resolves the promise.
|
|
197
|
-
* Followers retrieve the data themselves via get_leader_data().
|
|
198
|
-
*
|
|
199
|
-
* @param key - The coordination key
|
|
200
|
-
* @param leader - The leader component
|
|
201
|
-
* @param final_data - The final data after on_load and normalization
|
|
202
|
-
* @private
|
|
203
|
-
*/
|
|
204
|
-
static _complete_coordination(key, leader, final_data) {
|
|
205
|
-
const entry = this._registry.get(key);
|
|
206
|
-
if (!entry) {
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
// Store the final data (already normalized by _apply_load_result)
|
|
210
|
-
// Deep clone to avoid sharing proxy objects between components
|
|
211
|
-
try {
|
|
212
|
-
entry.leader_data = JSON.parse(JSON.stringify(final_data));
|
|
213
|
-
}
|
|
214
|
-
catch (error) {
|
|
215
|
-
// If data can't be serialized, use direct reference (may have issues)
|
|
216
|
-
entry.leader_data = final_data;
|
|
217
|
-
}
|
|
218
|
-
entry.status = 'completed';
|
|
219
|
-
if (window.jqhtml?.debug?.verbose) {
|
|
220
|
-
console.log(`[Load Coordinator] Leader ${leader._cid} completed, data available for ${entry.waiting.length} followers`, { key, data: entry.leader_data });
|
|
221
|
-
}
|
|
222
|
-
// Resolve the promise - followers waiting on it will now wake up
|
|
223
|
-
entry.resolve_promise();
|
|
224
|
-
// Note: We do NOT delete the entry here anymore.
|
|
225
|
-
// Followers need to retrieve the data after the promise resolves.
|
|
226
|
-
// Entry will be cleaned up when last follower retrieves data.
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Get leader's data for a follower component
|
|
230
|
-
* Called by follower after coordination promise resolves
|
|
231
|
-
* Returns the data and cleans up if this is the last follower
|
|
232
|
-
*/
|
|
233
|
-
static get_leader_data(component) {
|
|
234
|
-
const { key } = this.generate_invocation_key(component.component_name(), component.args);
|
|
235
|
-
if (!key) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
const entry = this._registry.get(key);
|
|
239
|
-
if (!entry || entry.status !== 'completed') {
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
// Remove this follower from the waiting list
|
|
243
|
-
const follower_index = entry.waiting.indexOf(component);
|
|
244
|
-
if (follower_index !== -1) {
|
|
245
|
-
entry.waiting.splice(follower_index, 1);
|
|
246
|
-
}
|
|
247
|
-
if (window.jqhtml?.debug?.verbose) {
|
|
248
|
-
console.log(`[Load Coordinator] Follower ${component._cid} retrieving data from leader ${entry.leader_component._cid}`, { key, remaining_followers: entry.waiting.length });
|
|
249
|
-
}
|
|
250
|
-
// If this was the last follower, clean up the entry
|
|
251
|
-
if (entry.waiting.length === 0) {
|
|
252
|
-
this._registry.delete(key);
|
|
253
|
-
if (window.jqhtml?.debug?.verbose) {
|
|
254
|
-
console.log(`[Load Coordinator] Coordination complete for key: ${key}`, { registry_size: this._registry.size });
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
return entry.leader_data;
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Handle leader on_load() error
|
|
261
|
-
* Propagates error to all followers and cleans up entry
|
|
262
|
-
*/
|
|
263
|
-
static handle_leader_error(component, error) {
|
|
264
|
-
const { key } = this.generate_invocation_key(component.component_name(), component.args);
|
|
265
|
-
const entry = this._registry.get(key);
|
|
266
|
-
if (!entry) {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
entry.leader_error = error;
|
|
270
|
-
entry.status = 'failed';
|
|
271
|
-
console.error(`[Load Coordinator] Leader ${component._cid} on_load() failed for key: ${key}`, error);
|
|
272
|
-
// Propagate error to all followers
|
|
273
|
-
// Note: Followers will handle errors the same way as if their own on_load() failed
|
|
274
|
-
// This is transparent to the developer
|
|
275
|
-
for (const follower of entry.waiting) {
|
|
276
|
-
console.error(`[Load Coordinator] Follower ${follower._cid} failed due to leader error`, error);
|
|
277
|
-
// The follower's lifecycle will handle the error naturally
|
|
278
|
-
// as the promise rejection will propagate
|
|
279
|
-
}
|
|
280
|
-
// Clear coordination entry so future requests can retry
|
|
281
|
-
this._registry.delete(key);
|
|
282
|
-
if (window.jqhtml?.debug?.verbose) {
|
|
283
|
-
console.log(`[Load Coordinator] Cleared failed coordination for key: ${key}`, { followers_count: entry.waiting.length });
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Get current registry state (for debugging)
|
|
288
|
-
*/
|
|
289
|
-
static get_registry_state() {
|
|
290
|
-
const state = {};
|
|
291
|
-
for (const [key, entry] of this._registry.entries()) {
|
|
292
|
-
state[key] = {
|
|
293
|
-
status: entry.status,
|
|
294
|
-
leader_cid: entry.leader_component._cid,
|
|
295
|
-
waiting_count: entry.waiting.length,
|
|
296
|
-
waiting_cids: entry.waiting.map(c => c._cid)
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
return state;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Clear all coordination entries (for testing/debugging)
|
|
303
|
-
*/
|
|
304
|
-
static clear_all() {
|
|
305
|
-
this._registry.clear();
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
Load_Coordinator._registry = new Map();
|
|
309
|
-
//# sourceMappingURL=load-coordinator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"load-coordinator.js","sourceRoot":"","sources":["../src/load-coordinator.ts"],"names":[],"mappings":"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"}
|