Fix infinite hydration loop and stabilize global store synchronization

- Refactored layouts to derive account data from stable props instead of reactive stores.
- Wrapped store updates in untrack() with deep equality guards to prevent infinite re-renders.
- Resolved duplicate untrack declarations and missing imports across the project.
- Added fetch safeguards to Element_data_store to prevent redundant API calls.
- Standardized hydration patterns to break circular dependencies during initial load.
This commit is contained in:
Scott Idem
2026-02-08 17:15:20 -05:00
parent 88bc18cf15
commit 718de1457d
33 changed files with 455 additions and 1567 deletions

View File

@@ -3,6 +3,7 @@
let log_lvl: number = $state(0);
// *** Import Svelte specific
import { untrack } from 'svelte';
// import { browser } from '$app/environment';
import { goto, invalidateAll } from '$app/navigation';
@@ -36,23 +37,27 @@
let { data, children }: Props = $props();
$events_loc.qry__enabled = 'enabled';
$events_loc.qry__hidden = 'not_hidden';
$events_loc.qry__limit = 15;
$events_loc.qry__offset = 0;
// Use effects for store initializations to prevent render-phase updates
$effect(() => {
untrack(() => {
$events_loc.qry__enabled = 'enabled';
$events_loc.qry__hidden = 'not_hidden';
$events_loc.qry__limit = 15;
$events_loc.qry__offset = 0;
});
});
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
console.log(`$slct.account_id = `, $slct.account_id);
if (log_lvl) {
console.log(`$slct.account_id = `, $slct.account_id);
}
let ae_acct = data[$slct.account_id];
// console.log(`ae_acct = `, ae_acct);
let ae_acct = $derived(data[data.account_id]);
$events_slct.event_id = ae_acct.slct.event_id;
// $events_slct.event_obj = ae_acct.slct.event_obj;
$events_slct.event_obj_li = ae_acct.slct.event_obj_li;
$effect(() => {
if (ae_acct) {
untrack(() => {
$events_slct.event_id = ae_acct.slct.event_id;
$events_slct.event_obj_li = ae_acct.slct.event_obj_li;
});
}
});
let ae_promises: key_val = {};

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { untrack } from 'svelte';
interface Props {
/** @type {import('./$types').PageData} */
data: any;
@@ -8,7 +9,6 @@
let { data, log_lvl = $bindable(1) }: Props = $props();
// *** Import Svelte specific
import { untrack } from 'svelte';
// *** Import other supporting libraries
import { liveQuery } from 'dexie';

View File

@@ -1,8 +1,8 @@
<script lang="ts">
import { untrack } from 'svelte';
import type { key_val } from '$lib/stores/ae_stores';
import { events_func } from '$lib/ae_events_functions';
import { ae_api } from '$lib/stores/ae_stores';
import { untrack } from 'svelte';
interface Props {
event_id: string;

View File

@@ -9,6 +9,7 @@
let { data, children }: Props = $props();
// *** Import Svelte specific
import { untrack } from 'svelte';
// import { onMount, tick } from 'svelte';
import { goto } from '$app/navigation';
import { sineIn } from 'svelte/easing';
@@ -56,7 +57,9 @@
import Element_websocket_v2 from '$lib/elements/element_websocket_v2.svelte';
// *** Set initial variables
let ae_acct = $derived(data[$slct.account_id]);
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
import { online } from 'svelte/reactivity/window';
@@ -83,33 +86,41 @@
`event_session_id: ${data.url.searchParams.get('session_id')}`
);
}
$events_slct.event_id = data.params.event_id;
$events_slct.event_location_id = data.params.event_location_id;
$events_slct.event_session_id = data.url.searchParams.get('session_id');
untrack(() => {
$events_slct.event_id = data.params.event_id;
$events_slct.event_location_id = data.params.event_location_id;
$events_slct.event_session_id = data.url.searchParams.get('session_id');
});
});
// String-Only ID Vision: Sync the device ID from the native environment
const native_dev = $derived($ae_loc.native_device);
$effect(() => {
if (native_dev) {
$events_slct.event_device_id =
native_dev.event_device_id ||
native_dev.id ||
native_dev.event_device_id_random ||
native_dev.id_random;
untrack(() => {
$events_slct.event_device_id =
native_dev.event_device_id ||
native_dev.id ||
native_dev.event_device_id_random ||
native_dev.id_random;
});
}
});
$effect(() => {
if (ae_acct) {
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li ?? [
''
];
untrack(() => {
const new_location_obj_li = ae_acct.slct.event_location_obj_li ?? [''];
if (JSON.stringify($events_slct.event_location_obj_li) !== JSON.stringify(new_location_obj_li)) {
$events_slct.event_location_obj_li = new_location_obj_li;
}
const new_id_li__event_location = ae_acct.slct.id_li__event_location ?? [''];
if (JSON.stringify($events_slct.id_li__event_location) !== JSON.stringify(new_id_li__event_location)) {
$events_slct.id_li__event_location = new_id_li__event_location;
}
});
}
});
$events_slct.id_li__event_location = ae_acct.slct.id_li__event_location ?? [
''
];
// *** Functions and Logic

View File

@@ -8,6 +8,7 @@
let log_lvl: number = $state(0);
// Imports
import { untrack } from 'svelte';
import {
ae_snip,
ae_loc,
@@ -37,7 +38,9 @@
// Variables
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
let ae_acct = $derived(data[$slct.account_id]);
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
// $ae_loc.url_origin = data.url.origin;
@@ -47,27 +50,31 @@
console.log(`event_id: ${data.params.event_id}`);
console.log(`event_location_id: ${data.params.event_location_id}`);
}
$events_slct.event_id = data.params.event_id;
$events_slct.event_location_id = data.params.event_location_id;
untrack(() => {
$events_slct.event_id = data.params.event_id;
$events_slct.event_location_id = data.params.event_location_id;
});
});
$effect(() => {
if (ae_acct) {
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li ?? [
''
];
$events_slct.id_li__event_location = ae_acct.slct.id_li__event_location ?? [
''
];
if (log_lvl) {
console.log(
`$events_slct.event_location_obj_li:`,
$events_slct.event_location_obj_li
);
}
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li ?? [
''
];
untrack(() => {
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li ?? [
''
];
$events_slct.id_li__event_location = ae_acct.slct.id_li__event_location ?? [
''
];
if (log_lvl) {
console.log(
`$events_slct.event_location_obj_li:`,
$events_slct.event_location_obj_li
);
}
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li ?? [
''
];
});
}
});

View File

@@ -51,7 +51,7 @@
}
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
let ae_acct = data[$slct.account_id];
let ae_acct = data[data.account_id];
$ae_loc.url_origin = data.url.origin;

View File

@@ -55,7 +55,7 @@
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
// console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
let ae_acct = data[data.account_id];
// console.log(`ae_acct = `, ae_acct);
$ae_loc.url_origin = data.url.origin;

View File

@@ -46,7 +46,7 @@
// Variables
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
let ae_acct = data[$slct.account_id];
let ae_acct = data[data.account_id];
if (log_lvl) {
console.log(`ae_acct = `, ae_acct);
}

View File

@@ -42,7 +42,7 @@
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
let ae_acct = data[data.account_id];
console.log(`ae_acct = `, ae_acct);
// console.log(`TEST data`, data);

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { untrack } from 'svelte';
interface Props {
/** @type {import('./$types').PageData} */
data: any;
@@ -58,7 +59,7 @@
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
// console.log(`$slct.account_id = `, $slct.account_id);
let ae_acct = data[$slct.account_id];
let ae_acct = data[data.account_id];
// console.log(`ae_acct = `, ae_acct);
$ae_loc.url_origin = data.url.origin;
@@ -155,18 +156,13 @@
// JSON formatted configuration options for an event, and specifically for the presentation management module.
$effect(() => {
if ($lq__event_obj?.mod_pres_mgmt_json) {
// if (log_lvl) {
// console.log(`*** Event Pres Mgmt JSON *** pres_mgmt_cfg_local`, $events_loc.pres_mgmt);
// }
// $events_loc.pres_mgmt =
events_func.sync_config__event_pres_mgmt({
pres_mgmt_cfg_remote: $lq__event_obj?.mod_pres_mgmt_json,
pres_mgmt_cfg_local: $events_loc?.pres_mgmt,
log_lvl: log_lvl
untrack(() => {
events_func.sync_config__event_pres_mgmt({
pres_mgmt_cfg_remote: $lq__event_obj?.mod_pres_mgmt_json,
pres_mgmt_cfg_local: $events_loc?.pres_mgmt,
log_lvl: log_lvl
});
});
// if (log_lvl) {
// console.log(`*** Event Pres Mgmt JSON *** pres_mgmt_cfg_local`, $events_loc.pres_mgmt);
// }
}
});

View File

@@ -1,4 +1,5 @@
<script lang="ts">
import { untrack } from 'svelte';
interface Props {
/** @type {import('./$types').LayoutData} */
data: any;
@@ -27,7 +28,9 @@
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
// $slct.account_id = data.account_id;
let ae_acct = $derived(data[$slct.account_id]);
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
$effect(() => {
if (log_lvl) {
@@ -43,8 +46,14 @@
$effect(() => {
if (ae_acct) {
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li;
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li;
untrack(() => {
if (JSON.stringify($events_slct.event_session_obj_li) !== JSON.stringify(ae_acct.slct.event_session_obj_li)) {
$events_slct.event_session_obj_li = ae_acct.slct.event_session_obj_li;
}
if (JSON.stringify($events_slct.event_location_obj_li) !== JSON.stringify(ae_acct.slct.event_location_obj_li)) {
$events_slct.event_location_obj_li = ae_acct.slct.event_location_obj_li;
}
});
}
});
</script>

View File

@@ -39,12 +39,16 @@
import Event_page_menu from './event_page_menu.svelte';
// Quickly save the data passed from the parent(s) to the Svelte stores, localStorage, and other.
let ae_acct = $derived(data[$slct.account_id]);
// NOTE: Derived from data.account_id (prop) instead of $slct.account_id (store)
// to prevent circular dependency loops during hydration.
let ae_acct = $derived(data[data.account_id]);
let event_id = $derived(data.params.event_id);
$effect(() => {
if (ae_acct) {
$events_slct.event_id = ae_acct.slct.event_id;
untrack(() => {
$events_slct.event_id = ae_acct.slct.event_id;
});
}
});
@@ -74,11 +78,15 @@
// JSON formatted configuration options for an event, and specifically for the presentation management module.
$effect(() => {
if ($lq__event_obj?.mod_pres_mgmt_json) {
events_func.sync_config__event_pres_mgmt({
pres_mgmt_cfg_remote: $lq__event_obj.mod_pres_mgmt_json,
pres_mgmt_cfg_local: $events_loc.pres_mgmt,
log_lvl: log_lvl
const remote_cfg = $lq__event_obj?.mod_pres_mgmt_json;
const local_cfg = $events_loc.pres_mgmt;
if (remote_cfg && local_cfg) {
untrack(() => {
events_func.sync_config__event_pres_mgmt({
pres_mgmt_cfg_remote: remote_cfg,
pres_mgmt_cfg_local: local_cfg,
log_lvl: log_lvl
});
});
}
});