dalila 1.9.16 → 1.9.17
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/core/devtools.js +8 -0
- package/dist/core/persist.d.ts +1 -1
- package/dist/core/persist.js +40 -52
- package/dist/core/scope.d.ts +1 -1
- package/package.json +1 -1
package/dist/core/devtools.js
CHANGED
|
@@ -322,6 +322,14 @@ export function getSnapshot() {
|
|
|
322
322
|
export function registerScope(scopeRef, parentScopeRef, name) {
|
|
323
323
|
if (!enabled)
|
|
324
324
|
return;
|
|
325
|
+
const scopeId = getNodeId(scopeRef);
|
|
326
|
+
const existingNode = nodes.get(scopeId);
|
|
327
|
+
if (existingNode) {
|
|
328
|
+
if (name) {
|
|
329
|
+
existingNode.label = name;
|
|
330
|
+
}
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
325
333
|
createNode(scopeRef, "scope", name || "scope", {
|
|
326
334
|
parentScopeRef,
|
|
327
335
|
});
|
package/dist/core/persist.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export interface PersistedSignal<T> extends Signal<T> {
|
|
|
49
49
|
/**
|
|
50
50
|
* Create a persisted signal that automatically syncs with storage.
|
|
51
51
|
*/
|
|
52
|
-
export declare function persist<T>(baseSignal: Signal<T>, options: PersistOptions<T>):
|
|
52
|
+
export declare function persist<T>(baseSignal: Signal<T>, options: PersistOptions<T>): PersistedSignal<T>;
|
|
53
53
|
/**
|
|
54
54
|
* Helper to create JSON storage wrapper
|
|
55
55
|
*/
|
package/dist/core/persist.js
CHANGED
|
@@ -47,6 +47,13 @@ export function persist(baseSignal, options) {
|
|
|
47
47
|
}
|
|
48
48
|
const storageKey = name;
|
|
49
49
|
const versionKey = version !== undefined ? `${name}:version` : undefined;
|
|
50
|
+
const handleError = (err, ctx) => {
|
|
51
|
+
const e = toError(err);
|
|
52
|
+
if (onError)
|
|
53
|
+
onError(e);
|
|
54
|
+
else
|
|
55
|
+
console.error(`[Dalila] persist(): ${ctx} "${name}"`, e);
|
|
56
|
+
};
|
|
50
57
|
// ---- Tab Sync (BroadcastChannel) ----
|
|
51
58
|
const { syncTabs = false } = options;
|
|
52
59
|
let channel = null;
|
|
@@ -57,39 +64,20 @@ export function persist(baseSignal, options) {
|
|
|
57
64
|
try {
|
|
58
65
|
channel = new BroadcastChannel(`dalila:${name}`);
|
|
59
66
|
channel.onmessage = (event) => {
|
|
60
|
-
const { type, value, version: remoteVersion } = event.data;
|
|
61
67
|
// Ignore our own messages (prevent echo loop)
|
|
62
68
|
if (isHandlingRemoteChange)
|
|
63
69
|
return;
|
|
64
|
-
// Only handle update events
|
|
65
|
-
if (type !== 'update')
|
|
66
|
-
return;
|
|
67
|
-
// Mark as handling remote to prevent echo
|
|
68
|
-
isHandlingRemoteChange = true;
|
|
69
70
|
try {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
baseSignal.set(deserialized);
|
|
84
|
-
}
|
|
85
|
-
// Update local tracking
|
|
86
|
-
lastSaved = value;
|
|
87
|
-
pendingSaved = null;
|
|
88
|
-
// Handle version sync
|
|
89
|
-
if (versionKey && remoteVersion !== undefined) {
|
|
90
|
-
lastSavedVersion = String(remoteVersion);
|
|
91
|
-
pendingSavedVersion = null;
|
|
92
|
-
}
|
|
71
|
+
const { type, value, version: remoteVersion } = event.data;
|
|
72
|
+
// Only handle update events
|
|
73
|
+
if (type !== 'update')
|
|
74
|
+
return;
|
|
75
|
+
// Mark as handling remote to prevent echo
|
|
76
|
+
isHandlingRemoteChange = true;
|
|
77
|
+
applyRemoteStoredValue(value, versionKey && remoteVersion !== undefined ? String(remoteVersion) : null);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
handleError(err, 'failed to apply remote sync payload');
|
|
93
81
|
}
|
|
94
82
|
finally {
|
|
95
83
|
isHandlingRemoteChange = false;
|
|
@@ -110,23 +98,17 @@ export function persist(baseSignal, options) {
|
|
|
110
98
|
// Ignore our own changes
|
|
111
99
|
if (isHandlingRemoteChange)
|
|
112
100
|
return;
|
|
113
|
-
isHandlingRemoteChange = true;
|
|
114
101
|
try {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
baseSignal.set(deserialized);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
baseSignal.set(deserialized);
|
|
102
|
+
isHandlingRemoteChange = true;
|
|
103
|
+
let remoteVersionRaw = null;
|
|
104
|
+
if (versionKey) {
|
|
105
|
+
const v = storage.getItem(versionKey);
|
|
106
|
+
remoteVersionRaw = isPromiseLike(v) ? null : typeof v === 'string' ? v : null;
|
|
127
107
|
}
|
|
128
|
-
|
|
129
|
-
|
|
108
|
+
applyRemoteStoredValue(e.newValue, remoteVersionRaw);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
handleError(err, 'failed to apply remote sync payload');
|
|
130
112
|
}
|
|
131
113
|
finally {
|
|
132
114
|
isHandlingRemoteChange = false;
|
|
@@ -165,14 +147,10 @@ export function persist(baseSignal, options) {
|
|
|
165
147
|
// Same idea for version key (when enabled)
|
|
166
148
|
let lastSavedVersion = null;
|
|
167
149
|
let pendingSavedVersion = null;
|
|
168
|
-
|
|
169
|
-
const e = toError(err);
|
|
170
|
-
if (onError)
|
|
171
|
-
onError(e);
|
|
172
|
-
else
|
|
173
|
-
console.error(`[Dalila] persist(): ${ctx} "${name}"`, e);
|
|
174
|
-
};
|
|
150
|
+
let disposed = false;
|
|
175
151
|
const applyHydration = (value) => {
|
|
152
|
+
if (disposed)
|
|
153
|
+
return;
|
|
176
154
|
// Ensure dirty listener does not treat hydration as user mutation.
|
|
177
155
|
const setHydratedValue = (next) => {
|
|
178
156
|
isHydrationWrite = true;
|
|
@@ -273,7 +251,7 @@ export function persist(baseSignal, options) {
|
|
|
273
251
|
};
|
|
274
252
|
const persistValue = (value) => {
|
|
275
253
|
// Don't write until hydration finishes (prevents overwriting stored state).
|
|
276
|
-
if (!hydrated)
|
|
254
|
+
if (disposed || !hydrated)
|
|
277
255
|
return;
|
|
278
256
|
let serialized;
|
|
279
257
|
try {
|
|
@@ -319,6 +297,9 @@ export function persist(baseSignal, options) {
|
|
|
319
297
|
}
|
|
320
298
|
applyHydration(deserialized);
|
|
321
299
|
};
|
|
300
|
+
const applyRemoteStoredValue = (storedValue, storedVersionRaw) => {
|
|
301
|
+
hydrateFromStored(storedValue, storedVersionRaw);
|
|
302
|
+
};
|
|
322
303
|
const finalizeHydration = (didUserChangeBefore) => {
|
|
323
304
|
hydrated = true;
|
|
324
305
|
// Remove temporary dirty listener (no longer needed after hydration)
|
|
@@ -326,6 +307,8 @@ export function persist(baseSignal, options) {
|
|
|
326
307
|
removeDirtyListener();
|
|
327
308
|
removeDirtyListener = null;
|
|
328
309
|
}
|
|
310
|
+
if (disposed)
|
|
311
|
+
return;
|
|
329
312
|
// If user changed before hydrate finished, we must persist current value at least once,
|
|
330
313
|
// because the change already happened while hydrated=false and won't re-trigger.
|
|
331
314
|
if (didUserChangeBefore) {
|
|
@@ -447,7 +430,12 @@ export function persist(baseSignal, options) {
|
|
|
447
430
|
// Add dispose method for manual cleanup
|
|
448
431
|
const persistedSignal = baseSignal;
|
|
449
432
|
persistedSignal.dispose = () => {
|
|
433
|
+
disposed = true;
|
|
450
434
|
removeSubscription();
|
|
435
|
+
if (removeDirtyListener) {
|
|
436
|
+
removeDirtyListener();
|
|
437
|
+
removeDirtyListener = null;
|
|
438
|
+
}
|
|
451
439
|
cleanup();
|
|
452
440
|
};
|
|
453
441
|
return persistedSignal;
|
package/dist/core/scope.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export declare function isScopeDisposed(scope: Scope): boolean;
|
|
|
43
43
|
export declare function createScope(): Scope;
|
|
44
44
|
export declare function createScope(parentOverride?: Scope | null): Scope;
|
|
45
45
|
export declare function createScope(options: CreateScopeOptions): Scope;
|
|
46
|
-
export declare function createScope(parentOverride: Scope | null, options?: CreateScopeOptions): Scope;
|
|
46
|
+
export declare function createScope(parentOverride: Scope | null | undefined, options?: CreateScopeOptions): Scope;
|
|
47
47
|
/** Returns the current active scope (or null if none). */
|
|
48
48
|
export declare function getCurrentScope(): Scope | null;
|
|
49
49
|
/**
|