Framework updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2026-03-12 19:09:07 +00:00
parent 3294fc7337
commit daa9bb2fb1
47 changed files with 2495 additions and 525 deletions

View File

@@ -1 +1 @@
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}

View File

@@ -2837,6 +2837,141 @@ class Component_Queue {
}
}
/**
* JQHTML SSR Preload Data System
*
* Captures component data during SSR rendering and replays it on the client
* to skip redundant on_load() calls during hydration.
*
* Server-side: start_data_capture() → render → get_captured_data()
* Client-side: set_preload_data(entries) → components boot with preloaded data → clear_preload_data()
*/
// --- Capture (Server Side) ---
let _capture_enabled = false;
let _capture_buffer = [];
// Track captured keys to avoid duplicates from Load Coordinator followers
let _captured_keys = new Set();
/**
* Enable data capture mode. After this call, every component that completes
* on_load() has its final this.data recorded.
*
* Idempotent — calling twice is fine.
*/
function start_data_capture() {
_capture_enabled = true;
_capture_buffer = [];
_captured_keys.clear();
}
/**
* Record a component's data after on_load() completes.
* Called internally from _apply_load_result().
*
* @param component_name - Component name
* @param args - Component args at time of on_load()
* @param data - this.data after on_load() completed
* @param cache_key - The cache key for deduplication (null = always capture)
*/
function capture_component_data(component_name, args, data, cache_key) {
if (!_capture_enabled)
return;
// Deduplicate: if Load Coordinator already captured this key, skip
if (cache_key !== null) {
if (_captured_keys.has(cache_key))
return;
_captured_keys.add(cache_key);
}
// Deep clone args and data to plain objects (no proxies, no class instances)
try {
const cloned_args = JSON.parse(JSON.stringify(args));
const cloned_data = JSON.parse(JSON.stringify(data));
_capture_buffer.push({
component: component_name,
args: cloned_args,
data: cloned_data,
});
}
catch (error) {
// Non-serializable data — skip capture for this component
if (typeof console !== 'undefined') {
console.warn(`[JQHTML SSR Capture] Failed to serialize data for ${component_name}:`, error);
}
}
}
/**
* Returns all captured component data and resets the capture buffer.
* One-shot: calling clears the buffer.
*/
function get_captured_data() {
const result = _capture_buffer;
_capture_buffer = [];
_captured_keys.clear();
return result;
}
/**
* Check if data capture is currently enabled.
*/
function is_capture_enabled() {
return _capture_enabled;
}
/**
* Stop data capture and clear all state.
*/
function stop_data_capture() {
_capture_enabled = false;
_capture_buffer = [];
_captured_keys.clear();
}
// --- Preload (Client Side) ---
let _preload_cache = new Map();
/**
* Seed the preload cache with SSR-captured data.
* Must be called before any component _load() runs.
*
* @param entries - Array of { component, args, data } entries from get_captured_data()
*/
function set_preload_data(entries) {
if (!entries || entries.length === 0)
return;
_preload_cache.clear();
for (const entry of entries) {
// Generate key using the same algorithm as Load Coordinator
const result = Load_Coordinator.generate_invocation_key(entry.component, entry.args);
if (result.key !== null) {
_preload_cache.set(result.key, entry.data);
}
}
}
/**
* Check if preloaded data exists for a given cache key.
* If found, returns the data and removes the entry (one-shot).
*
* @param cache_key - The cache key (same format as Load Coordinator)
* @returns The preloaded data, or null if no match
*/
function consume_preload_data(cache_key) {
if (_preload_cache.size === 0)
return null;
const data = _preload_cache.get(cache_key);
if (data !== undefined) {
_preload_cache.delete(cache_key);
return data;
}
return null;
}
/**
* Clear any remaining unconsumed preload entries.
* Call after initial page hydration is complete.
*/
function clear_preload_data() {
_preload_cache.clear();
}
/**
* Check if any preload data is available (for fast early exit in _load).
*/
function has_preload_data() {
return _preload_cache.size > 0;
}
/**
* JQHTML v2 Component Base Class
*
@@ -3515,7 +3650,7 @@ class Jqhtml_Component {
}
return;
}
// Check if component implements cache_id() for custom cache key
// Generate cache key (needed for both preload check and load deduplication)
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
@@ -3534,6 +3669,19 @@ class Jqhtml_Component {
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// SSR preload check: if preloaded data exists for this component+args, use it
if (cache_key !== null && has_preload_data()) {
const preloaded_data = consume_preload_data(cache_key);
if (preloaded_data !== null) {
this._cache_key = cache_key;
if (window.jqhtml?.debug?.verbose) {
console.log(`[SSR Preload] Component ${this._cid} (${this.component_name()}) using preloaded data`, { cache_key });
}
const data_before_load = JSON.stringify(this.data);
await this._apply_load_result(preloaded_data, data_before_load);
return;
}
}
// Store cache key for later use
this._cache_key = cache_key;
// If cache_key is null, args are not serializable - skip load deduplication and caching
@@ -3653,6 +3801,10 @@ class Jqhtml_Component {
}
// Freeze this.data
this.__data_frozen = true;
// SSR data capture: record this component's data for preloading
if (is_capture_enabled() && this._has_on_load()) {
capture_component_data(this.component_name(), this.args, this.data, this._cache_key);
}
// Calculate if data changed
const data_after_load = JSON.stringify(this.data);
const data_changed = data_before_load !== null && data_after_load !== data_before_load;
@@ -5336,7 +5488,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.3.41';
const version = '2.3.42';
// Default export with all functionality
const jqhtml = {
// Core
@@ -5433,7 +5585,13 @@ const jqhtml = {
// Required for ES6 class instances to be stored and restored from localStorage
register_cache_class,
// Boot - hydrate server-rendered component placeholders
boot
boot,
// SSR Preload - capture data during SSR, replay on client to skip on_load()
start_data_capture,
get_captured_data,
stop_data_capture,
set_preload_data,
clear_preload_data
};
// Auto-register on window for browser environments
// This is REQUIRED for compiled templates which use window.jqhtml.register_template()
@@ -5470,12 +5628,14 @@ exports.LifecycleManager = LifecycleManager;
exports.Load_Coordinator = Load_Coordinator;
exports.applyDebugDelay = applyDebugDelay;
exports.boot = boot;
exports.clear_preload_data = clear_preload_data;
exports.create_component = create_component;
exports.default = jqhtml;
exports.devWarn = devWarn;
exports.escape_html = escape_html;
exports.escape_html_nl2br = escape_html_nl2br;
exports.extract_slots = extract_slots;
exports.get_captured_data = get_captured_data;
exports.get_component_class = get_component_class;
exports.get_component_names = get_component_names;
exports.get_registered_templates = get_registered_templates;
@@ -5497,5 +5657,8 @@ exports.register_cache_class = register_cache_class;
exports.register_component = register_component;
exports.register_template = register_template;
exports.render_template = render_template;
exports.set_preload_data = set_preload_data;
exports.start_data_capture = start_data_capture;
exports.stop_data_capture = stop_data_capture;
exports.version = version;
//# sourceMappingURL=index.cjs.map

File diff suppressed because one or more lines are too long

View File

@@ -29,6 +29,9 @@ export { Jqhtml_Local_Storage, register_cache_class };
export type { CacheMode } from './local-storage.js';
import { Load_Coordinator } from './load-coordinator.js';
export { Load_Coordinator };
import { start_data_capture, get_captured_data, stop_data_capture, set_preload_data, clear_preload_data } from './preload-data.js';
export { start_data_capture, get_captured_data, stop_data_capture, set_preload_data, clear_preload_data };
export type { PreloadEntry } from './preload-data.js';
export declare const version = "__VERSION__";
export interface DebugSettings {
verbose?: boolean;
@@ -89,6 +92,11 @@ declare const jqhtml: {
get_cache_mode(): import("./local-storage.js").CacheMode;
register_cache_class: typeof register_cache_class;
boot: typeof boot;
start_data_capture: typeof start_data_capture;
get_captured_data: typeof get_captured_data;
stop_data_capture: typeof stop_data_capture;
set_preload_data: typeof set_preload_data;
clear_preload_data: typeof clear_preload_data;
};
export default jqhtml;
//# sourceMappingURL=index.d.ts.map

View File

@@ -1 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}

View File

@@ -2833,6 +2833,141 @@ class Component_Queue {
}
}
/**
* JQHTML SSR Preload Data System
*
* Captures component data during SSR rendering and replays it on the client
* to skip redundant on_load() calls during hydration.
*
* Server-side: start_data_capture() → render → get_captured_data()
* Client-side: set_preload_data(entries) → components boot with preloaded data → clear_preload_data()
*/
// --- Capture (Server Side) ---
let _capture_enabled = false;
let _capture_buffer = [];
// Track captured keys to avoid duplicates from Load Coordinator followers
let _captured_keys = new Set();
/**
* Enable data capture mode. After this call, every component that completes
* on_load() has its final this.data recorded.
*
* Idempotent — calling twice is fine.
*/
function start_data_capture() {
_capture_enabled = true;
_capture_buffer = [];
_captured_keys.clear();
}
/**
* Record a component's data after on_load() completes.
* Called internally from _apply_load_result().
*
* @param component_name - Component name
* @param args - Component args at time of on_load()
* @param data - this.data after on_load() completed
* @param cache_key - The cache key for deduplication (null = always capture)
*/
function capture_component_data(component_name, args, data, cache_key) {
if (!_capture_enabled)
return;
// Deduplicate: if Load Coordinator already captured this key, skip
if (cache_key !== null) {
if (_captured_keys.has(cache_key))
return;
_captured_keys.add(cache_key);
}
// Deep clone args and data to plain objects (no proxies, no class instances)
try {
const cloned_args = JSON.parse(JSON.stringify(args));
const cloned_data = JSON.parse(JSON.stringify(data));
_capture_buffer.push({
component: component_name,
args: cloned_args,
data: cloned_data,
});
}
catch (error) {
// Non-serializable data — skip capture for this component
if (typeof console !== 'undefined') {
console.warn(`[JQHTML SSR Capture] Failed to serialize data for ${component_name}:`, error);
}
}
}
/**
* Returns all captured component data and resets the capture buffer.
* One-shot: calling clears the buffer.
*/
function get_captured_data() {
const result = _capture_buffer;
_capture_buffer = [];
_captured_keys.clear();
return result;
}
/**
* Check if data capture is currently enabled.
*/
function is_capture_enabled() {
return _capture_enabled;
}
/**
* Stop data capture and clear all state.
*/
function stop_data_capture() {
_capture_enabled = false;
_capture_buffer = [];
_captured_keys.clear();
}
// --- Preload (Client Side) ---
let _preload_cache = new Map();
/**
* Seed the preload cache with SSR-captured data.
* Must be called before any component _load() runs.
*
* @param entries - Array of { component, args, data } entries from get_captured_data()
*/
function set_preload_data(entries) {
if (!entries || entries.length === 0)
return;
_preload_cache.clear();
for (const entry of entries) {
// Generate key using the same algorithm as Load Coordinator
const result = Load_Coordinator.generate_invocation_key(entry.component, entry.args);
if (result.key !== null) {
_preload_cache.set(result.key, entry.data);
}
}
}
/**
* Check if preloaded data exists for a given cache key.
* If found, returns the data and removes the entry (one-shot).
*
* @param cache_key - The cache key (same format as Load Coordinator)
* @returns The preloaded data, or null if no match
*/
function consume_preload_data(cache_key) {
if (_preload_cache.size === 0)
return null;
const data = _preload_cache.get(cache_key);
if (data !== undefined) {
_preload_cache.delete(cache_key);
return data;
}
return null;
}
/**
* Clear any remaining unconsumed preload entries.
* Call after initial page hydration is complete.
*/
function clear_preload_data() {
_preload_cache.clear();
}
/**
* Check if any preload data is available (for fast early exit in _load).
*/
function has_preload_data() {
return _preload_cache.size > 0;
}
/**
* JQHTML v2 Component Base Class
*
@@ -3511,7 +3646,7 @@ class Jqhtml_Component {
}
return;
}
// Check if component implements cache_id() for custom cache key
// Generate cache key (needed for both preload check and load deduplication)
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
@@ -3530,6 +3665,19 @@ class Jqhtml_Component {
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// SSR preload check: if preloaded data exists for this component+args, use it
if (cache_key !== null && has_preload_data()) {
const preloaded_data = consume_preload_data(cache_key);
if (preloaded_data !== null) {
this._cache_key = cache_key;
if (window.jqhtml?.debug?.verbose) {
console.log(`[SSR Preload] Component ${this._cid} (${this.component_name()}) using preloaded data`, { cache_key });
}
const data_before_load = JSON.stringify(this.data);
await this._apply_load_result(preloaded_data, data_before_load);
return;
}
}
// Store cache key for later use
this._cache_key = cache_key;
// If cache_key is null, args are not serializable - skip load deduplication and caching
@@ -3649,6 +3797,10 @@ class Jqhtml_Component {
}
// Freeze this.data
this.__data_frozen = true;
// SSR data capture: record this component's data for preloading
if (is_capture_enabled() && this._has_on_load()) {
capture_component_data(this.component_name(), this.args, this.data, this._cache_key);
}
// Calculate if data changed
const data_after_load = JSON.stringify(this.data);
const data_changed = data_before_load !== null && data_after_load !== data_before_load;
@@ -5332,7 +5484,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.3.41';
const version = '2.3.42';
// Default export with all functionality
const jqhtml = {
// Core
@@ -5429,7 +5581,13 @@ const jqhtml = {
// Required for ES6 class instances to be stored and restored from localStorage
register_cache_class,
// Boot - hydrate server-rendered component placeholders
boot
boot,
// SSR Preload - capture data during SSR, replay on client to skip on_load()
start_data_capture,
get_captured_data,
stop_data_capture,
set_preload_data,
clear_preload_data
};
// Auto-register on window for browser environments
// This is REQUIRED for compiled templates which use window.jqhtml.register_template()
@@ -5459,5 +5617,5 @@ if (typeof window !== 'undefined' && !window.jqhtml) {
}
}
export { Jqhtml_Component, LifecycleManager as Jqhtml_LifecycleManager, Jqhtml_Local_Storage, LifecycleManager, Load_Coordinator, applyDebugDelay, boot, create_component, jqhtml as default, devWarn, escape_html, escape_html_nl2br, extract_slots, get_component_class, get_component_names, get_registered_templates, get_template, get_template_by_class, handleComponentError, has_component, init, init_jquery_plugin, isSequentialProcessing, list_components, logDataChange, logDispatch, logInstruction, logLifecycle, process_instructions, register, register_cache_class, register_component, register_template, render_template, version };
export { Jqhtml_Component, LifecycleManager as Jqhtml_LifecycleManager, Jqhtml_Local_Storage, LifecycleManager, Load_Coordinator, applyDebugDelay, boot, clear_preload_data, create_component, jqhtml as default, devWarn, escape_html, escape_html_nl2br, extract_slots, get_captured_data, get_component_class, get_component_names, get_registered_templates, get_template, get_template_by_class, handleComponentError, has_component, init, init_jquery_plugin, isSequentialProcessing, list_components, logDataChange, logDispatch, logInstruction, logLifecycle, process_instructions, register, register_cache_class, register_component, register_template, render_template, set_preload_data, start_data_capture, stop_data_capture, version };
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/**
* JQHTML Core v2.3.41
* JQHTML Core v2.3.42
* (c) 2025 JQHTML Team
* Released under the MIT License
*/
@@ -2838,6 +2838,141 @@ class Component_Queue {
}
}
/**
* JQHTML SSR Preload Data System
*
* Captures component data during SSR rendering and replays it on the client
* to skip redundant on_load() calls during hydration.
*
* Server-side: start_data_capture() → render → get_captured_data()
* Client-side: set_preload_data(entries) → components boot with preloaded data → clear_preload_data()
*/
// --- Capture (Server Side) ---
let _capture_enabled = false;
let _capture_buffer = [];
// Track captured keys to avoid duplicates from Load Coordinator followers
let _captured_keys = new Set();
/**
* Enable data capture mode. After this call, every component that completes
* on_load() has its final this.data recorded.
*
* Idempotent — calling twice is fine.
*/
function start_data_capture() {
_capture_enabled = true;
_capture_buffer = [];
_captured_keys.clear();
}
/**
* Record a component's data after on_load() completes.
* Called internally from _apply_load_result().
*
* @param component_name - Component name
* @param args - Component args at time of on_load()
* @param data - this.data after on_load() completed
* @param cache_key - The cache key for deduplication (null = always capture)
*/
function capture_component_data(component_name, args, data, cache_key) {
if (!_capture_enabled)
return;
// Deduplicate: if Load Coordinator already captured this key, skip
if (cache_key !== null) {
if (_captured_keys.has(cache_key))
return;
_captured_keys.add(cache_key);
}
// Deep clone args and data to plain objects (no proxies, no class instances)
try {
const cloned_args = JSON.parse(JSON.stringify(args));
const cloned_data = JSON.parse(JSON.stringify(data));
_capture_buffer.push({
component: component_name,
args: cloned_args,
data: cloned_data,
});
}
catch (error) {
// Non-serializable data — skip capture for this component
if (typeof console !== 'undefined') {
console.warn(`[JQHTML SSR Capture] Failed to serialize data for ${component_name}:`, error);
}
}
}
/**
* Returns all captured component data and resets the capture buffer.
* One-shot: calling clears the buffer.
*/
function get_captured_data() {
const result = _capture_buffer;
_capture_buffer = [];
_captured_keys.clear();
return result;
}
/**
* Check if data capture is currently enabled.
*/
function is_capture_enabled() {
return _capture_enabled;
}
/**
* Stop data capture and clear all state.
*/
function stop_data_capture() {
_capture_enabled = false;
_capture_buffer = [];
_captured_keys.clear();
}
// --- Preload (Client Side) ---
let _preload_cache = new Map();
/**
* Seed the preload cache with SSR-captured data.
* Must be called before any component _load() runs.
*
* @param entries - Array of { component, args, data } entries from get_captured_data()
*/
function set_preload_data(entries) {
if (!entries || entries.length === 0)
return;
_preload_cache.clear();
for (const entry of entries) {
// Generate key using the same algorithm as Load Coordinator
const result = Load_Coordinator.generate_invocation_key(entry.component, entry.args);
if (result.key !== null) {
_preload_cache.set(result.key, entry.data);
}
}
}
/**
* Check if preloaded data exists for a given cache key.
* If found, returns the data and removes the entry (one-shot).
*
* @param cache_key - The cache key (same format as Load Coordinator)
* @returns The preloaded data, or null if no match
*/
function consume_preload_data(cache_key) {
if (_preload_cache.size === 0)
return null;
const data = _preload_cache.get(cache_key);
if (data !== undefined) {
_preload_cache.delete(cache_key);
return data;
}
return null;
}
/**
* Clear any remaining unconsumed preload entries.
* Call after initial page hydration is complete.
*/
function clear_preload_data() {
_preload_cache.clear();
}
/**
* Check if any preload data is available (for fast early exit in _load).
*/
function has_preload_data() {
return _preload_cache.size > 0;
}
/**
* JQHTML v2 Component Base Class
*
@@ -3516,7 +3651,7 @@ class Jqhtml_Component {
}
return;
}
// Check if component implements cache_id() for custom cache key
// Generate cache key (needed for both preload check and load deduplication)
let cache_key = null;
let uncacheable_property;
if (typeof this.cache_id === 'function') {
@@ -3535,6 +3670,19 @@ class Jqhtml_Component {
cache_key = result.key;
uncacheable_property = result.uncacheable_property;
}
// SSR preload check: if preloaded data exists for this component+args, use it
if (cache_key !== null && has_preload_data()) {
const preloaded_data = consume_preload_data(cache_key);
if (preloaded_data !== null) {
this._cache_key = cache_key;
if (window.jqhtml?.debug?.verbose) {
console.log(`[SSR Preload] Component ${this._cid} (${this.component_name()}) using preloaded data`, { cache_key });
}
const data_before_load = JSON.stringify(this.data);
await this._apply_load_result(preloaded_data, data_before_load);
return;
}
}
// Store cache key for later use
this._cache_key = cache_key;
// If cache_key is null, args are not serializable - skip load deduplication and caching
@@ -3654,6 +3802,10 @@ class Jqhtml_Component {
}
// Freeze this.data
this.__data_frozen = true;
// SSR data capture: record this component's data for preloading
if (is_capture_enabled() && this._has_on_load()) {
capture_component_data(this.component_name(), this.args, this.data, this._cache_key);
}
// Calculate if data changed
const data_after_load = JSON.stringify(this.data);
const data_changed = data_before_load !== null && data_after_load !== data_before_load;
@@ -5337,7 +5489,7 @@ function init(jQuery) {
}
}
// Version - will be replaced during build with actual version from package.json
const version = '2.3.41';
const version = '2.3.42';
// Default export with all functionality
const jqhtml = {
// Core
@@ -5434,7 +5586,13 @@ const jqhtml = {
// Required for ES6 class instances to be stored and restored from localStorage
register_cache_class,
// Boot - hydrate server-rendered component placeholders
boot
boot,
// SSR Preload - capture data during SSR, replay on client to skip on_load()
start_data_capture,
get_captured_data,
stop_data_capture,
set_preload_data,
clear_preload_data
};
// Auto-register on window for browser environments
// This is REQUIRED for compiled templates which use window.jqhtml.register_template()
@@ -5464,5 +5622,5 @@ if (typeof window !== 'undefined' && !window.jqhtml) {
}
}
export { Jqhtml_Component, LifecycleManager as Jqhtml_LifecycleManager, Jqhtml_Local_Storage, LifecycleManager, Load_Coordinator, applyDebugDelay, boot, create_component, jqhtml as default, devWarn, escape_html, escape_html_nl2br, extract_slots, get_component_class, get_component_names, get_registered_templates, get_template, get_template_by_class, handleComponentError, has_component, init, init_jquery_plugin, isSequentialProcessing, list_components, logDataChange, logDispatch, logInstruction, logLifecycle, process_instructions, register, register_cache_class, register_component, register_template, render_template, version };
export { Jqhtml_Component, LifecycleManager as Jqhtml_LifecycleManager, Jqhtml_Local_Storage, LifecycleManager, Load_Coordinator, applyDebugDelay, boot, clear_preload_data, create_component, jqhtml as default, devWarn, escape_html, escape_html_nl2br, extract_slots, get_captured_data, get_component_class, get_component_names, get_registered_templates, get_template, get_template_by_class, handleComponentError, has_component, init, init_jquery_plugin, isSequentialProcessing, list_components, logDataChange, logDispatch, logInstruction, logLifecycle, process_instructions, register, register_cache_class, register_component, register_template, render_template, set_preload_data, start_data_capture, stop_data_capture, version };
//# sourceMappingURL=jqhtml-core.esm.js.map

File diff suppressed because one or more lines are too long

69
node_modules/@jqhtml/core/dist/preload-data.d.ts generated vendored Executable file
View File

@@ -0,0 +1,69 @@
/**
* JQHTML SSR Preload Data System
*
* Captures component data during SSR rendering and replays it on the client
* to skip redundant on_load() calls during hydration.
*
* Server-side: start_data_capture() → render → get_captured_data()
* Client-side: set_preload_data(entries) → components boot with preloaded data → clear_preload_data()
*/
export interface PreloadEntry {
component: string;
args: Record<string, any>;
data: Record<string, any>;
}
/**
* Enable data capture mode. After this call, every component that completes
* on_load() has its final this.data recorded.
*
* Idempotent — calling twice is fine.
*/
export declare function start_data_capture(): void;
/**
* Record a component's data after on_load() completes.
* Called internally from _apply_load_result().
*
* @param component_name - Component name
* @param args - Component args at time of on_load()
* @param data - this.data after on_load() completed
* @param cache_key - The cache key for deduplication (null = always capture)
*/
export declare function capture_component_data(component_name: string, args: Record<string, any>, data: Record<string, any>, cache_key: string | null): void;
/**
* Returns all captured component data and resets the capture buffer.
* One-shot: calling clears the buffer.
*/
export declare function get_captured_data(): PreloadEntry[];
/**
* Check if data capture is currently enabled.
*/
export declare function is_capture_enabled(): boolean;
/**
* Stop data capture and clear all state.
*/
export declare function stop_data_capture(): void;
/**
* Seed the preload cache with SSR-captured data.
* Must be called before any component _load() runs.
*
* @param entries - Array of { component, args, data } entries from get_captured_data()
*/
export declare function set_preload_data(entries: PreloadEntry[] | null): void;
/**
* Check if preloaded data exists for a given cache key.
* If found, returns the data and removes the entry (one-shot).
*
* @param cache_key - The cache key (same format as Load Coordinator)
* @returns The preloaded data, or null if no match
*/
export declare function consume_preload_data(cache_key: string): Record<string, any> | null;
/**
* Clear any remaining unconsumed preload entries.
* Call after initial page hydration is complete.
*/
export declare function clear_preload_data(): void;
/**
* Check if any preload data is available (for fast early exit in _load).
*/
export declare function has_preload_data(): boolean;
//# sourceMappingURL=preload-data.d.ts.map

1
node_modules/@jqhtml/core/dist/preload-data.d.ts.map generated vendored Executable file
View File

@@ -0,0 +1 @@
{"version":3,"file":"preload-data.d.ts","sourceRoot":"","sources":["../src/preload-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC3B;AASD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,IAAI,CA4BN;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,EAAE,CAKlD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,IAAI,GAAG,IAAI,CAYrE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CASlF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}

View File

@@ -1,6 +1,6 @@
{
"name": "@jqhtml/core",
"version": "2.3.41",
"version": "2.3.42",
"description": "Core runtime library for JQHTML",
"type": "module",
"main": "./dist/index.js",