memorio 4.9.35 → 5.1.0
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/AGENTS.md +3 -3
- package/README.md +95 -516
- package/SECURITY.md +159 -33
- package/SUMMARY.md +59 -45
- package/adr/001-state-proxy-model.md +95 -0
- package/adr/002-observer-semantics.md +179 -0
- package/adr/003-deep-mutation-semantics.md +128 -0
- package/adr/004-array-mutation-semantics.md +127 -0
- package/adr/005-scheduler-contract.md +148 -0
- package/adr/006-context-isolation.md +91 -0
- package/adr/007-mutation-records.md +117 -0
- package/adr/008-transactions.md +105 -0
- package/adr/009-history-model.md +109 -0
- package/adr/README.md +46 -0
- package/adr/template.md +48 -0
- package/bin/cli.js +68 -0
- package/examples/basic.ts +115 -115
- package/examples/browser-vanilla.html +358 -358
- package/examples/cache.ts +72 -72
- package/examples/cross-platform-guards.ts +57 -57
- package/examples/history.ts +104 -0
- package/examples/idb.ts +109 -109
- package/examples/multi-tenant-context.ts +44 -44
- package/examples/node-server.ts +308 -308
- package/examples/observer.ts +60 -60
- package/examples/platform.ts +115 -115
- package/examples/react-app.tsx +362 -362
- package/examples/react-observer.tsx +63 -63
- package/examples/semantic-memory.ts +60 -60
- package/examples/session-advanced.ts +91 -91
- package/examples/sqlite-batched-writes.ts +57 -57
- package/examples/state-advanced.ts +89 -89
- package/examples/store-advanced.ts +117 -117
- package/examples/sync.ts +90 -0
- package/examples/typed-and-schema.ts +102 -100
- package/examples/useObserver.tsx +140 -141
- package/global.cjs +5733 -0
- package/global.d.ts +8 -0
- package/global.js +5667 -0
- package/index.cjs +2202 -1041
- package/index.d.ts +2 -0
- package/index.js +2178 -1040
- package/llms.txt +113 -8
- package/markdown/AUDIT-REPORT.md +134 -0
- package/markdown/CACHE.md +191 -0
- package/markdown/DEVTOOLS.md +128 -0
- package/markdown/DISPATCH.md +176 -0
- package/markdown/HISTORY.md +198 -0
- package/markdown/IDB.md +177 -0
- package/markdown/IMPORT.md +152 -0
- package/markdown/INSPECT.md +122 -0
- package/markdown/LOGGER.md +153 -0
- package/markdown/MEMORY-ATTACHMENT.md +95 -0
- package/markdown/MEMORY.md +161 -0
- package/markdown/OBSERVER.md +208 -0
- package/markdown/PLATFORM.md +277 -0
- package/markdown/REDUX.md +54 -0
- package/markdown/SCHEMA.md +175 -0
- package/markdown/SESSION.md +164 -0
- package/markdown/SQLITE.md +189 -0
- package/markdown/STATE.md +159 -0
- package/markdown/STORE.md +170 -0
- package/markdown/SYNC.md +318 -0
- package/markdown/TYPED.md +164 -0
- package/markdown/USEOBSERVER.md +256 -0
- package/modules/redux.cjs +701 -177
- package/modules/redux.cjs.map +1 -1
- package/modules/redux.js +701 -177
- package/modules/redux.js.map +1 -1
- package/package.json +26 -4
- package/types/broadcast.d.ts +61 -0
- package/types/computed.d.ts +96 -0
- package/types/encryption.d.ts +129 -0
- package/types/env.d.ts +19 -9
- package/types/exports.d.ts +29 -0
- package/types/history.d.ts +13 -1
- package/types/memorio.d.ts +25 -6
- package/types/mutation.d.ts +75 -0
- package/types/security.d.ts +67 -0
- package/types/session.d.ts +23 -5
- package/types/store.d.ts +19 -3
- package/vsix/memorio.vsix +0 -0
package/index.cjs
CHANGED
|
@@ -8,6 +8,10 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
|
|
|
8
8
|
var __esm = (fn, res) => function __init() {
|
|
9
9
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
10
|
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
11
15
|
|
|
12
16
|
// node_modules/tsup/assets/cjs_shims.js
|
|
13
17
|
var init_cjs_shims = __esm({
|
|
@@ -20,8 +24,11 @@ exports.DEV = void 0; exports.PROD = void 0;
|
|
|
20
24
|
var init_env = __esm({
|
|
21
25
|
"core/env.ts"() {
|
|
22
26
|
init_cjs_shims();
|
|
23
|
-
exports.DEV =
|
|
27
|
+
exports.DEV = false ;
|
|
24
28
|
exports.PROD = !exports.DEV;
|
|
29
|
+
if (typeof globalThis !== "undefined") {
|
|
30
|
+
globalThis["__DEV__"] = exports.DEV;
|
|
31
|
+
}
|
|
25
32
|
}
|
|
26
33
|
});
|
|
27
34
|
|
|
@@ -205,6 +212,241 @@ var init_message = __esm({
|
|
|
205
212
|
}
|
|
206
213
|
});
|
|
207
214
|
|
|
215
|
+
// functions/encryption/index.ts
|
|
216
|
+
function _hasWebCrypto() {
|
|
217
|
+
const g3 = globalThis;
|
|
218
|
+
return typeof g3.crypto !== "undefined" && typeof g3.crypto.subtle !== "undefined" && typeof g3.crypto.subtle.encrypt === "function";
|
|
219
|
+
}
|
|
220
|
+
function _b64encode(buf) {
|
|
221
|
+
const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
222
|
+
if (typeof btoa === "function") {
|
|
223
|
+
let binary = "";
|
|
224
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
225
|
+
return btoa(binary);
|
|
226
|
+
}
|
|
227
|
+
if (typeof Buffer !== "undefined") {
|
|
228
|
+
return Buffer.from(bytes).toString("base64");
|
|
229
|
+
}
|
|
230
|
+
return "";
|
|
231
|
+
}
|
|
232
|
+
function _b64decode(b64) {
|
|
233
|
+
if (typeof Buffer !== "undefined") {
|
|
234
|
+
return new Uint8Array(Buffer.from(b64, "base64"));
|
|
235
|
+
}
|
|
236
|
+
if (typeof atob === "function") {
|
|
237
|
+
const binary = atob(b64);
|
|
238
|
+
const out = new Uint8Array(binary.length);
|
|
239
|
+
for (let i = 0; i < binary.length; i++) out[i] = binary.charCodeAt(i);
|
|
240
|
+
return out;
|
|
241
|
+
}
|
|
242
|
+
throw new Error("memorio encryption: no base64 decoder available");
|
|
243
|
+
}
|
|
244
|
+
function _isEncrypted(value) {
|
|
245
|
+
return typeof value === "object" && value !== null && value.__memorio_encrypted === true && typeof value.alg === "string";
|
|
246
|
+
}
|
|
247
|
+
var AES_GCM, PBKDF2_ITERATIONS; exports.encryption = void 0;
|
|
248
|
+
var init_encryption = __esm({
|
|
249
|
+
"functions/encryption/index.ts"() {
|
|
250
|
+
init_cjs_shims();
|
|
251
|
+
init_env();
|
|
252
|
+
init_message();
|
|
253
|
+
__name(_hasWebCrypto, "_hasWebCrypto");
|
|
254
|
+
__name(_b64encode, "_b64encode");
|
|
255
|
+
__name(_b64decode, "_b64decode");
|
|
256
|
+
__name(_isEncrypted, "_isEncrypted");
|
|
257
|
+
AES_GCM = { name: "AES-GCM", length: 256 };
|
|
258
|
+
PBKDF2_ITERATIONS = 6e5;
|
|
259
|
+
exports.encryption = {
|
|
260
|
+
///
|
|
261
|
+
// Capability detection
|
|
262
|
+
///
|
|
263
|
+
isAvailable() {
|
|
264
|
+
return _hasWebCrypto();
|
|
265
|
+
},
|
|
266
|
+
///
|
|
267
|
+
// Derive a CryptoKey from a password using PBKDF2.
|
|
268
|
+
//
|
|
269
|
+
// @param password The password string.
|
|
270
|
+
// @param salt Salt (string or Uint8Array). Defaults to a static value.
|
|
271
|
+
// @param alg 'AES-GCM' (default) or 'AES-CBC'.
|
|
272
|
+
// @returns A Promise<CryptoKey>.
|
|
273
|
+
///
|
|
274
|
+
async deriveKey(password, salt, alg = "AES-GCM", iterations = PBKDF2_ITERATIONS) {
|
|
275
|
+
if (!_hasWebCrypto()) {
|
|
276
|
+
throw new Error("memorio encryption: Web Crypto API is not available in this environment");
|
|
277
|
+
}
|
|
278
|
+
const enc = new TextEncoder();
|
|
279
|
+
const saltBytes = typeof salt === "string" ? enc.encode(salt) : salt ?? enc.encode("memorio:salt");
|
|
280
|
+
const keyMaterial = await globalThis.crypto.subtle.importKey(
|
|
281
|
+
"raw",
|
|
282
|
+
enc.encode(password),
|
|
283
|
+
{ name: "PBKDF2" },
|
|
284
|
+
false,
|
|
285
|
+
["deriveKey"]
|
|
286
|
+
);
|
|
287
|
+
return globalThis.crypto.subtle.deriveKey(
|
|
288
|
+
{ name: "PBKDF2", salt: saltBytes, iterations, hash: "SHA-256" },
|
|
289
|
+
keyMaterial,
|
|
290
|
+
{ name: alg, length: 256 },
|
|
291
|
+
false,
|
|
292
|
+
["encrypt", "decrypt"]
|
|
293
|
+
);
|
|
294
|
+
},
|
|
295
|
+
///
|
|
296
|
+
// Generate a fresh random CryptoKey (AES-GCM, 256-bit).
|
|
297
|
+
///
|
|
298
|
+
async generateKey(alg = "AES-GCM") {
|
|
299
|
+
if (!_hasWebCrypto()) {
|
|
300
|
+
throw new Error("memorio encryption: Web Crypto API is not available in this environment");
|
|
301
|
+
}
|
|
302
|
+
return globalThis.crypto.subtle.generateKey(
|
|
303
|
+
{ name: alg, length: 256 },
|
|
304
|
+
true,
|
|
305
|
+
["encrypt", "decrypt"]
|
|
306
|
+
);
|
|
307
|
+
},
|
|
308
|
+
///
|
|
309
|
+
// Generate a random salt for PBKDF2 key derivation.
|
|
310
|
+
///
|
|
311
|
+
generateSalt(bytes = 16) {
|
|
312
|
+
const arr = new Uint8Array(bytes);
|
|
313
|
+
globalThis.crypto?.getRandomValues?.(arr);
|
|
314
|
+
return _b64encode(arr);
|
|
315
|
+
},
|
|
316
|
+
///
|
|
317
|
+
// Export a CryptoKey to portable base64 strings so it can be stored
|
|
318
|
+
// (e.g. in an httpOnly cookie) and re-imported later with importKey().
|
|
319
|
+
//
|
|
320
|
+
// @param cryptoKey A raw CryptoKey (not a password string).
|
|
321
|
+
// @returns { key: string, iv: string } base64-encoded.
|
|
322
|
+
///
|
|
323
|
+
async exportKey(cryptoKey) {
|
|
324
|
+
if (!_hasWebCrypto()) {
|
|
325
|
+
throw new Error("memorio encryption: Web Crypto API is not available in this environment");
|
|
326
|
+
}
|
|
327
|
+
const exported = await globalThis.crypto.subtle.exportKey("raw", cryptoKey);
|
|
328
|
+
return {
|
|
329
|
+
key: _b64encode(exported),
|
|
330
|
+
iv: ""
|
|
331
|
+
};
|
|
332
|
+
},
|
|
333
|
+
///
|
|
334
|
+
// Import a CryptoKey from base64 strings produced by exportKey().
|
|
335
|
+
//
|
|
336
|
+
// @param keyData Base64-encoded raw key bytes.
|
|
337
|
+
// @param _ivData Ignored (kept for API compatibility with exportKey return).
|
|
338
|
+
// @returns A Promise<CryptoKey>.
|
|
339
|
+
///
|
|
340
|
+
async importKey(keyData, _ivData) {
|
|
341
|
+
if (!_hasWebCrypto()) {
|
|
342
|
+
throw new Error("memorio encryption: Web Crypto API is not available in this environment");
|
|
343
|
+
}
|
|
344
|
+
const keyBytes = _b64decode(keyData);
|
|
345
|
+
if (keyBytes.length !== 32) {
|
|
346
|
+
throw new Error(`memorio encryption: AES-256 key must be exactly 32 bytes, got ${keyBytes.length}`);
|
|
347
|
+
}
|
|
348
|
+
return globalThis.crypto.subtle.importKey(
|
|
349
|
+
"raw",
|
|
350
|
+
keyBytes,
|
|
351
|
+
AES_GCM,
|
|
352
|
+
true,
|
|
353
|
+
["encrypt", "decrypt"]
|
|
354
|
+
);
|
|
355
|
+
},
|
|
356
|
+
///
|
|
357
|
+
// Encrypt a JavaScript value.
|
|
358
|
+
//
|
|
359
|
+
// @param value The value to encrypt (any JSON-serializable object).
|
|
360
|
+
// @param key A CryptoKey or a password string (password is derived via PBKDF2).
|
|
361
|
+
// @param keyId Optional label, stored in the envelope for key rotation.
|
|
362
|
+
// @returns An EncryptedEnvelope object.
|
|
363
|
+
///
|
|
364
|
+
async encrypt(value, key, keyId) {
|
|
365
|
+
const cryptoKey = typeof key === "string" ? await this.deriveKey(key, void 0, "AES-GCM") : key;
|
|
366
|
+
const data = new TextEncoder().encode(JSON.stringify(value));
|
|
367
|
+
const iv = new Uint8Array(12);
|
|
368
|
+
globalThis.crypto.getRandomValues(iv);
|
|
369
|
+
const ciphertext = await globalThis.crypto.subtle.encrypt(
|
|
370
|
+
{ name: "AES-GCM", iv },
|
|
371
|
+
cryptoKey,
|
|
372
|
+
data
|
|
373
|
+
);
|
|
374
|
+
const envelope = {
|
|
375
|
+
__memorio_encrypted: true,
|
|
376
|
+
v: 1,
|
|
377
|
+
alg: "AES-GCM",
|
|
378
|
+
iv: _b64encode(iv),
|
|
379
|
+
data: _b64encode(ciphertext)
|
|
380
|
+
};
|
|
381
|
+
if (keyId) envelope.keyId = keyId;
|
|
382
|
+
if (exports.DEV) message_default(`encryption: encrypted value (alg=${envelope.alg})`);
|
|
383
|
+
return envelope;
|
|
384
|
+
},
|
|
385
|
+
///
|
|
386
|
+
// Decrypt an EncryptedEnvelope.
|
|
387
|
+
//
|
|
388
|
+
// @param envelope The envelope object returned by encrypt().
|
|
389
|
+
// @param key A CryptoKey or a password string.
|
|
390
|
+
// @returns The original value (parsed from JSON).
|
|
391
|
+
///
|
|
392
|
+
async decrypt(envelope, key) {
|
|
393
|
+
if (!_isEncrypted(envelope)) {
|
|
394
|
+
throw new Error("memorio encryption: value is not a valid encrypted envelope");
|
|
395
|
+
}
|
|
396
|
+
const cryptoKey = typeof key === "string" ? await this.deriveKey(key, void 0, "AES-GCM") : key;
|
|
397
|
+
const iv = _b64decode(envelope.iv);
|
|
398
|
+
const data = _b64decode(envelope.data);
|
|
399
|
+
const decrypted = await globalThis.crypto.subtle.decrypt(
|
|
400
|
+
{ name: "AES-GCM", iv },
|
|
401
|
+
cryptoKey,
|
|
402
|
+
data
|
|
403
|
+
);
|
|
404
|
+
return JSON.parse(new TextDecoder().decode(new Uint8Array(decrypted)));
|
|
405
|
+
},
|
|
406
|
+
///
|
|
407
|
+
// Convenience: encrypt with a password (derives the key internally).
|
|
408
|
+
// Returns a JSON string you can store anywhere.
|
|
409
|
+
///
|
|
410
|
+
async encryptWithPassword(value, password, salt, keyId) {
|
|
411
|
+
const env = await this.encrypt(value, password, keyId);
|
|
412
|
+
return JSON.stringify(env);
|
|
413
|
+
},
|
|
414
|
+
///
|
|
415
|
+
// Convenience: decrypt a JSON envelope string with a password.
|
|
416
|
+
///
|
|
417
|
+
async decryptWithPassword(envelopeJson, password, _salt) {
|
|
418
|
+
const envelope = JSON.parse(envelopeJson);
|
|
419
|
+
return this.decrypt(envelope, password);
|
|
420
|
+
},
|
|
421
|
+
///
|
|
422
|
+
// Type guard: check whether a value is an encrypted envelope.
|
|
423
|
+
///
|
|
424
|
+
isEncrypted(value) {
|
|
425
|
+
return _isEncrypted(value);
|
|
426
|
+
},
|
|
427
|
+
///
|
|
428
|
+
// Configure a default encryption key for auto-encrypt mode.
|
|
429
|
+
// When set on `store` or `session`, all writes are encrypted and all
|
|
430
|
+
// reads attempt decryption automatically.
|
|
431
|
+
///
|
|
432
|
+
config(opts) {
|
|
433
|
+
if (opts.key !== void 0) this._defaultKey = opts.key;
|
|
434
|
+
if (opts.keyId !== void 0) this._defaultKeyId = opts.keyId;
|
|
435
|
+
return this;
|
|
436
|
+
},
|
|
437
|
+
///
|
|
438
|
+
// Internal: resolve the configured default key.
|
|
439
|
+
///
|
|
440
|
+
get _key() {
|
|
441
|
+
return this._defaultKey ?? null;
|
|
442
|
+
},
|
|
443
|
+
get _keyId() {
|
|
444
|
+
return this._defaultKeyId;
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
});
|
|
449
|
+
|
|
208
450
|
// core/platform.ts
|
|
209
451
|
function generateSessionId() {
|
|
210
452
|
const anyGlobal = globalThis;
|
|
@@ -219,6 +461,9 @@ function generateSessionId() {
|
|
|
219
461
|
return `session_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
|
|
220
462
|
}
|
|
221
463
|
function detectPlatform() {
|
|
464
|
+
if (_isBun()) {
|
|
465
|
+
return "bun";
|
|
466
|
+
}
|
|
222
467
|
const globalAny = globalThis;
|
|
223
468
|
if (globalAny.Deno && globalAny.Deno.version) {
|
|
224
469
|
return "deno";
|
|
@@ -234,6 +479,13 @@ function detectPlatform() {
|
|
|
234
479
|
}
|
|
235
480
|
return "unknown";
|
|
236
481
|
}
|
|
482
|
+
function _isBun() {
|
|
483
|
+
const globalAny = globalThis;
|
|
484
|
+
return typeof globalAny.Bun !== "undefined" && typeof globalAny.Bun.version === "string";
|
|
485
|
+
}
|
|
486
|
+
function isBun() {
|
|
487
|
+
return _isBun();
|
|
488
|
+
}
|
|
237
489
|
function isBrowser() {
|
|
238
490
|
const platform = detectPlatform();
|
|
239
491
|
return platform === "browser";
|
|
@@ -287,6 +539,9 @@ function hasSqlJs() {
|
|
|
287
539
|
}
|
|
288
540
|
return typeof anyGlobal.window !== "undefined";
|
|
289
541
|
}
|
|
542
|
+
function hasBunSqlite() {
|
|
543
|
+
return _isBun();
|
|
544
|
+
}
|
|
290
545
|
function hasDispatchEvent() {
|
|
291
546
|
return typeof globalThis.dispatchEvent === "function";
|
|
292
547
|
}
|
|
@@ -299,6 +554,7 @@ function getCapabilities() {
|
|
|
299
554
|
hasLocalStorage: getLocalStorage() !== null,
|
|
300
555
|
hasIndexedDB: hasIndexedDB(),
|
|
301
556
|
hasSqlJs: hasSqlJs(),
|
|
557
|
+
hasBunSqlite: hasBunSqlite(),
|
|
302
558
|
hasDispatchEvent: hasDispatchEvent(),
|
|
303
559
|
hasNavigator: typeof navigator !== "undefined",
|
|
304
560
|
hasProcess: typeof process !== "undefined",
|
|
@@ -358,8 +614,9 @@ function initializePlatform() {
|
|
|
358
614
|
};
|
|
359
615
|
}
|
|
360
616
|
}
|
|
361
|
-
function createContext(name) {
|
|
617
|
+
function createContext(name, opts) {
|
|
362
618
|
const contextId = name || `context_${generateSessionId()}`;
|
|
619
|
+
const encKey = opts?.encryptionKey;
|
|
363
620
|
setCurrentContext(contextId);
|
|
364
621
|
const contextStorage = {
|
|
365
622
|
state: {},
|
|
@@ -368,10 +625,31 @@ function createContext(name) {
|
|
|
368
625
|
cache: /* @__PURE__ */ new Map()
|
|
369
626
|
};
|
|
370
627
|
_contexts.set(contextId, contextStorage);
|
|
628
|
+
function _isEncrypted2(value) {
|
|
629
|
+
return exports.encryption.isEncrypted(value);
|
|
630
|
+
}
|
|
631
|
+
__name(_isEncrypted2, "_isEncrypted");
|
|
371
632
|
return {
|
|
372
633
|
id: contextId,
|
|
373
634
|
state: contextStorage.state,
|
|
374
|
-
store: {
|
|
635
|
+
store: encKey ? {
|
|
636
|
+
get: /* @__PURE__ */ __name(async (key) => {
|
|
637
|
+
const data = contextStorage.store.get(key);
|
|
638
|
+
if (!data) return null;
|
|
639
|
+
const parsed = JSON.parse(data);
|
|
640
|
+
if (_isEncrypted2(parsed)) return exports.encryption.decrypt(parsed, encKey);
|
|
641
|
+
return parsed;
|
|
642
|
+
}, "get"),
|
|
643
|
+
set: /* @__PURE__ */ __name(async (key, value) => {
|
|
644
|
+
const env = await exports.encryption.encrypt(value, encKey);
|
|
645
|
+
contextStorage.store.set(key, JSON.stringify(env));
|
|
646
|
+
}, "set"),
|
|
647
|
+
remove: /* @__PURE__ */ __name((key) => contextStorage.store.delete(key), "remove"),
|
|
648
|
+
removeAll: /* @__PURE__ */ __name(() => contextStorage.store.clear(), "removeAll"),
|
|
649
|
+
clearAll: /* @__PURE__ */ __name(() => contextStorage.store.clear(), "clearAll"),
|
|
650
|
+
size: /* @__PURE__ */ __name(() => contextStorage.store.size, "size"),
|
|
651
|
+
isPersistent: false
|
|
652
|
+
} : {
|
|
375
653
|
get: /* @__PURE__ */ __name((key) => {
|
|
376
654
|
const data = contextStorage.store.get(key);
|
|
377
655
|
return data ? JSON.parse(data) : null;
|
|
@@ -385,7 +663,24 @@ function createContext(name) {
|
|
|
385
663
|
size: /* @__PURE__ */ __name(() => contextStorage.store.size, "size"),
|
|
386
664
|
isPersistent: false
|
|
387
665
|
},
|
|
388
|
-
session: {
|
|
666
|
+
session: encKey ? {
|
|
667
|
+
get: /* @__PURE__ */ __name(async (key) => {
|
|
668
|
+
const data = contextStorage.session.get(key);
|
|
669
|
+
if (!data) return null;
|
|
670
|
+
const parsed = JSON.parse(data);
|
|
671
|
+
if (_isEncrypted2(parsed)) return exports.encryption.decrypt(parsed, encKey);
|
|
672
|
+
return parsed;
|
|
673
|
+
}, "get"),
|
|
674
|
+
set: /* @__PURE__ */ __name(async (key, value) => {
|
|
675
|
+
const env = await exports.encryption.encrypt(value, encKey);
|
|
676
|
+
contextStorage.session.set(key, JSON.stringify(env));
|
|
677
|
+
}, "set"),
|
|
678
|
+
remove: /* @__PURE__ */ __name((key) => contextStorage.session.delete(key), "remove"),
|
|
679
|
+
removeAll: /* @__PURE__ */ __name(() => contextStorage.session.clear(), "removeAll"),
|
|
680
|
+
clearAll: /* @__PURE__ */ __name(() => contextStorage.session.clear(), "clearAll"),
|
|
681
|
+
size: /* @__PURE__ */ __name(() => contextStorage.session.size, "size"),
|
|
682
|
+
isPersistent: false
|
|
683
|
+
} : {
|
|
389
684
|
get: /* @__PURE__ */ __name((key) => {
|
|
390
685
|
const data = contextStorage.session.get(key);
|
|
391
686
|
return data ? JSON.parse(data) : null;
|
|
@@ -405,7 +700,8 @@ function createContext(name) {
|
|
|
405
700
|
remove: /* @__PURE__ */ __name((key) => contextStorage.cache.delete(key), "remove"),
|
|
406
701
|
removeAll: /* @__PURE__ */ __name(() => contextStorage.cache.clear(), "removeAll"),
|
|
407
702
|
clear: /* @__PURE__ */ __name(() => contextStorage.cache.clear(), "clear")
|
|
408
|
-
}
|
|
703
|
+
},
|
|
704
|
+
encryptionKey: encKey
|
|
409
705
|
};
|
|
410
706
|
}
|
|
411
707
|
function listContexts() {
|
|
@@ -422,8 +718,11 @@ var init_platform = __esm({
|
|
|
422
718
|
"core/platform.ts"() {
|
|
423
719
|
init_cjs_shims();
|
|
424
720
|
init_internal();
|
|
721
|
+
init_encryption();
|
|
425
722
|
__name(generateSessionId, "generateSessionId");
|
|
426
723
|
__name(detectPlatform, "detectPlatform");
|
|
724
|
+
__name(_isBun, "_isBun");
|
|
725
|
+
__name(isBun, "isBun");
|
|
427
726
|
__name(isBrowser, "isBrowser");
|
|
428
727
|
__name(isNode, "isNode");
|
|
429
728
|
__name(isDeno, "isDeno");
|
|
@@ -432,6 +731,7 @@ var init_platform = __esm({
|
|
|
432
731
|
__name(getLocalStorage, "getLocalStorage");
|
|
433
732
|
__name(hasIndexedDB, "hasIndexedDB");
|
|
434
733
|
__name(hasSqlJs, "hasSqlJs");
|
|
734
|
+
__name(hasBunSqlite, "hasBunSqlite");
|
|
435
735
|
__name(hasDispatchEvent, "hasDispatchEvent");
|
|
436
736
|
__name(getCapabilities, "getCapabilities");
|
|
437
737
|
_eventListenerStorage = /* @__PURE__ */ new Map();
|
|
@@ -457,6 +757,9 @@ function _getFallbackStorage() {
|
|
|
457
757
|
}
|
|
458
758
|
return _fallbackStorageByContext.get(key);
|
|
459
759
|
}
|
|
760
|
+
function _isEncryptedEnvelope(value) {
|
|
761
|
+
return exports.encryption.isEncrypted(value);
|
|
762
|
+
}
|
|
460
763
|
function _getPrefix() {
|
|
461
764
|
const contextName = exports.internal.currentContext || "";
|
|
462
765
|
return contextName ? `${contextName}-` : `memorio_store_`;
|
|
@@ -493,17 +796,23 @@ function _remove(prefixedName) {
|
|
|
493
796
|
}
|
|
494
797
|
return false;
|
|
495
798
|
}
|
|
496
|
-
var _localStorage, _fallbackStorageByContext, _hasStorage, STORE_INSTANCE_KEY; exports.store = void 0;
|
|
799
|
+
var _localStorage, _fallbackStorageByContext, _hasStorage, _encryptionKey, _onError, _maxObjectSize, _maxTotalSize, STORE_INSTANCE_KEY; exports.store = void 0;
|
|
497
800
|
var init_store = __esm({
|
|
498
801
|
"functions/store/index.ts"() {
|
|
499
802
|
init_cjs_shims();
|
|
500
803
|
init_platform();
|
|
501
804
|
init_internal();
|
|
502
805
|
init_message();
|
|
806
|
+
init_encryption();
|
|
503
807
|
_localStorage = getLocalStorage();
|
|
504
808
|
_fallbackStorageByContext = /* @__PURE__ */ new Map();
|
|
505
809
|
__name(_getFallbackStorage, "_getFallbackStorage");
|
|
506
810
|
_hasStorage = _localStorage !== null;
|
|
811
|
+
_encryptionKey = null;
|
|
812
|
+
_onError = null;
|
|
813
|
+
_maxObjectSize = 0;
|
|
814
|
+
_maxTotalSize = 0;
|
|
815
|
+
__name(_isEncryptedEnvelope, "_isEncryptedEnvelope");
|
|
507
816
|
__name(_getPrefix, "_getPrefix");
|
|
508
817
|
__name(_prefixKey, "_prefixKey");
|
|
509
818
|
__name(_read, "_read");
|
|
@@ -520,16 +829,24 @@ var init_store = __esm({
|
|
|
520
829
|
/**
|
|
521
830
|
* Gets a value from storage.
|
|
522
831
|
* @param name The key to retrieve.
|
|
523
|
-
* @
|
|
832
|
+
* @param opts Optional { decrypt: key } to decrypt an encrypted envelope.
|
|
833
|
+
* When no key is passed, encrypted envelopes are returned as-is.
|
|
834
|
+
* If a default key was configured via store.config(), it is used automatically.
|
|
835
|
+
* @returns The parsed value, a Promise<parsed value> when decrypting, or null if not found.
|
|
524
836
|
*/
|
|
525
837
|
get: {
|
|
526
|
-
value: /* @__PURE__ */ __name((name) => {
|
|
838
|
+
value: /* @__PURE__ */ __name((name, opts) => {
|
|
527
839
|
if (!name) {
|
|
528
840
|
console.warn("[memorio store] store.get() called with empty or null key - returning null");
|
|
529
841
|
return null;
|
|
530
842
|
}
|
|
531
843
|
try {
|
|
532
|
-
|
|
844
|
+
const raw = _read(_prefixKey(name));
|
|
845
|
+
const key = opts?.decrypt ?? _encryptionKey;
|
|
846
|
+
if (key && _isEncryptedEnvelope(raw)) {
|
|
847
|
+
return exports.encryption.decrypt(raw, key);
|
|
848
|
+
}
|
|
849
|
+
return raw;
|
|
533
850
|
} catch (err) {
|
|
534
851
|
exports.message(`Error parsing store item '${name}': ${err}`);
|
|
535
852
|
}
|
|
@@ -554,10 +871,13 @@ var init_store = __esm({
|
|
|
554
871
|
* Sets a value in storage.
|
|
555
872
|
* @param name The key to set.
|
|
556
873
|
* @param value The value to store (objects, arrays, primitives).
|
|
557
|
-
* @
|
|
874
|
+
* @param opts Optional { encrypt: key } to encrypt the value before storage.
|
|
875
|
+
* If a default key was configured via store.config(), it is used automatically.
|
|
876
|
+
* When encryption is used, returns a Promise<boolean>.
|
|
877
|
+
* @returns true if written, false if rejected or error.
|
|
558
878
|
*/
|
|
559
879
|
set: {
|
|
560
|
-
value: /* @__PURE__ */ __name((name, value) => {
|
|
880
|
+
value: /* @__PURE__ */ __name((name, value, opts) => {
|
|
561
881
|
if (!name) {
|
|
562
882
|
console.warn("[memorio store] store.set() called with empty or null key - write aborted");
|
|
563
883
|
return false;
|
|
@@ -569,15 +889,66 @@ var init_store = __esm({
|
|
|
569
889
|
exports.message("Storing functions is not secure and is blocked for safety.");
|
|
570
890
|
return false;
|
|
571
891
|
}
|
|
892
|
+
if (_maxObjectSize > 0 || _maxTotalSize > 0) {
|
|
893
|
+
let serializedSize = 0;
|
|
894
|
+
try {
|
|
895
|
+
serializedSize = new TextEncoder().encode(JSON.stringify(value)).length;
|
|
896
|
+
} catch {
|
|
897
|
+
serializedSize = 0;
|
|
898
|
+
}
|
|
899
|
+
if (_maxObjectSize > 0 && serializedSize > _maxObjectSize) {
|
|
900
|
+
const err = new Error(`Object size (${serializedSize} bytes) exceeds maxObjectSize (${_maxObjectSize} bytes)`);
|
|
901
|
+
_onError?.(err, { operation: "set" });
|
|
902
|
+
return false;
|
|
903
|
+
}
|
|
904
|
+
if (_maxTotalSize > 0) {
|
|
905
|
+
const currentTotal = exports.store.size() * 1024;
|
|
906
|
+
const existingItemSize = _hasStorage ? _localStorage.getItem(prefixedName)?.length ?? 0 : _getFallbackStorage().get(prefixedName)?.length ?? 0;
|
|
907
|
+
const projected = currentTotal * 1024 - existingItemSize + serializedSize;
|
|
908
|
+
if (projected > _maxTotalSize) {
|
|
909
|
+
const err = new Error(`Total store size (${projected} bytes) exceeds maxTotalSize (${_maxTotalSize} bytes)`);
|
|
910
|
+
_onError?.(err, { operation: "set" });
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
const key = opts?.encrypt ?? _encryptionKey;
|
|
916
|
+
if (key) {
|
|
917
|
+
return exports.encryption.encrypt(value, key).then((env) => {
|
|
918
|
+
_write(prefixedName, env);
|
|
919
|
+
return true;
|
|
920
|
+
}).catch((err) => {
|
|
921
|
+
exports.message(`Error encrypting store item '${name}': ${err}`);
|
|
922
|
+
_onError?.(err, { operation: "set" });
|
|
923
|
+
return false;
|
|
924
|
+
});
|
|
925
|
+
}
|
|
572
926
|
try {
|
|
573
927
|
_write(prefixedName, value);
|
|
574
928
|
} catch (err) {
|
|
575
929
|
exports.message(`Error setting store item '${name}': ${err}`);
|
|
930
|
+
_onError?.(err, { operation: "set" });
|
|
576
931
|
return false;
|
|
577
932
|
}
|
|
578
933
|
return true;
|
|
579
934
|
}, "value")
|
|
580
935
|
},
|
|
936
|
+
/**
|
|
937
|
+
* Configure store-wide behavior.
|
|
938
|
+
* @param opts Optional { encryptionKey } to enable automatic encryption
|
|
939
|
+
* for all set/get operations. When set, values are encrypted
|
|
940
|
+
* on write and decrypted on read (if the value is an envelope).
|
|
941
|
+
* @returns The store instance for chaining.
|
|
942
|
+
*/
|
|
943
|
+
config: {
|
|
944
|
+
value: /* @__PURE__ */ __name((opts) => {
|
|
945
|
+
if (opts.encryptionKey !== void 0) _encryptionKey = opts.encryptionKey;
|
|
946
|
+
if (opts.onError !== void 0) _onError = opts.onError;
|
|
947
|
+
if (opts.maxObjectSize !== void 0) _maxObjectSize = opts.maxObjectSize;
|
|
948
|
+
if (opts.maxTotalSize !== void 0) _maxTotalSize = opts.maxTotalSize;
|
|
949
|
+
return exports.store;
|
|
950
|
+
}, "value")
|
|
951
|
+
},
|
|
581
952
|
/**
|
|
582
953
|
* Removes a value from storage.
|
|
583
954
|
* @param name The key to remove.
|
|
@@ -948,8 +1319,8 @@ var init_table_size = __esm({
|
|
|
948
1319
|
if (!db.objectStoreNames.contains(table)) return resolve(0);
|
|
949
1320
|
let size = 0;
|
|
950
1321
|
let count = 0;
|
|
951
|
-
const
|
|
952
|
-
const store2 =
|
|
1322
|
+
const transaction2 = db.transaction([table], "readonly");
|
|
1323
|
+
const store2 = transaction2.objectStore(table);
|
|
953
1324
|
const request = store2.openCursor();
|
|
954
1325
|
request.onsuccess = async (event) => {
|
|
955
1326
|
const cursor = event.target.result;
|
|
@@ -993,8 +1364,8 @@ var init_data_delete = __esm({
|
|
|
993
1364
|
db.close();
|
|
994
1365
|
return reject(new Error(`Table ${table} not found`));
|
|
995
1366
|
}
|
|
996
|
-
const
|
|
997
|
-
const objectStore =
|
|
1367
|
+
const transaction2 = db.transaction(table, "readwrite");
|
|
1368
|
+
const objectStore = transaction2.objectStore(table);
|
|
998
1369
|
const deleteRequest = objectStore.delete(key);
|
|
999
1370
|
deleteRequest.onsuccess = () => {
|
|
1000
1371
|
db.close();
|
|
@@ -1018,8 +1389,8 @@ var init_data_delete = __esm({
|
|
|
1018
1389
|
db.close();
|
|
1019
1390
|
return reject(new Error(`Table ${table} not found`));
|
|
1020
1391
|
}
|
|
1021
|
-
const
|
|
1022
|
-
const store2 =
|
|
1392
|
+
const transaction2 = db.transaction(table, "readwrite");
|
|
1393
|
+
const store2 = transaction2.objectStore(table);
|
|
1023
1394
|
const clearRequest = store2.clear();
|
|
1024
1395
|
clearRequest.onsuccess = () => {
|
|
1025
1396
|
db.close();
|
|
@@ -1053,8 +1424,8 @@ var init_data_set = __esm({
|
|
|
1053
1424
|
db.close();
|
|
1054
1425
|
return reject(new Error(`Table ${table} does not exist in ${storeName}`));
|
|
1055
1426
|
}
|
|
1056
|
-
const
|
|
1057
|
-
const objectStore =
|
|
1427
|
+
const transaction2 = db.transaction(table, "readwrite");
|
|
1428
|
+
const objectStore = transaction2.objectStore(table);
|
|
1058
1429
|
const putRequest = objectStore.put(value);
|
|
1059
1430
|
putRequest.onsuccess = () => {
|
|
1060
1431
|
db.close();
|
|
@@ -1090,8 +1461,8 @@ var init_data_get = __esm({
|
|
|
1090
1461
|
db.close();
|
|
1091
1462
|
return reject(new Error(`Table ${table} not found in ${storeName}`));
|
|
1092
1463
|
}
|
|
1093
|
-
const
|
|
1094
|
-
const store2 =
|
|
1464
|
+
const transaction2 = db.transaction(table, "readonly");
|
|
1465
|
+
const store2 = transaction2.objectStore(table);
|
|
1095
1466
|
const getRequest = store2.get(key);
|
|
1096
1467
|
getRequest.onsuccess = () => {
|
|
1097
1468
|
db.close();
|
|
@@ -1163,6 +1534,91 @@ var init_idb = __esm({
|
|
|
1163
1534
|
}
|
|
1164
1535
|
});
|
|
1165
1536
|
|
|
1537
|
+
// functions/sqlite/tools/bun-sqlite-adapter.ts
|
|
1538
|
+
var bun_sqlite_adapter_exports = {};
|
|
1539
|
+
__export(bun_sqlite_adapter_exports, {
|
|
1540
|
+
BunSqlJsDatabase: () => BunSqlJsDatabase,
|
|
1541
|
+
createBunSqlJs: () => createBunSqlJs
|
|
1542
|
+
});
|
|
1543
|
+
async function _loadDatabase() {
|
|
1544
|
+
if (!_DatabaseClass) {
|
|
1545
|
+
const mod = await import('bun:sqlite');
|
|
1546
|
+
_DatabaseClass = mod.Database;
|
|
1547
|
+
}
|
|
1548
|
+
return _DatabaseClass;
|
|
1549
|
+
}
|
|
1550
|
+
async function createBunSqlJs() {
|
|
1551
|
+
await _loadDatabase();
|
|
1552
|
+
return {
|
|
1553
|
+
Database: BunSqlJsDatabase,
|
|
1554
|
+
version: "bun:sqlite"
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
var _DatabaseClass, BunSqlJsDatabase;
|
|
1558
|
+
var init_bun_sqlite_adapter = __esm({
|
|
1559
|
+
"functions/sqlite/tools/bun-sqlite-adapter.ts"() {
|
|
1560
|
+
init_cjs_shims();
|
|
1561
|
+
_DatabaseClass = null;
|
|
1562
|
+
__name(_loadDatabase, "_loadDatabase");
|
|
1563
|
+
BunSqlJsDatabase = class {
|
|
1564
|
+
static {
|
|
1565
|
+
__name(this, "BunSqlJsDatabase");
|
|
1566
|
+
}
|
|
1567
|
+
_db;
|
|
1568
|
+
_lastRunChanges = 0;
|
|
1569
|
+
constructor(data) {
|
|
1570
|
+
this._lastRunChanges = 0;
|
|
1571
|
+
if (typeof data === "string") {
|
|
1572
|
+
this._db = new _DatabaseClass(data);
|
|
1573
|
+
} else {
|
|
1574
|
+
this._db = new _DatabaseClass(":memory:");
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
run(sql, params = []) {
|
|
1578
|
+
const info = this._db.run(sql, ...params);
|
|
1579
|
+
this._lastRunChanges = info?.changes ?? 0;
|
|
1580
|
+
return info;
|
|
1581
|
+
}
|
|
1582
|
+
getRowsModified() {
|
|
1583
|
+
return this._lastRunChanges;
|
|
1584
|
+
}
|
|
1585
|
+
prepare(sql, params = []) {
|
|
1586
|
+
const rows = params.length > 0 ? this._db.query(sql).all(...params) : this._db.query(sql).all();
|
|
1587
|
+
return {
|
|
1588
|
+
_rows: rows,
|
|
1589
|
+
_idx: -1,
|
|
1590
|
+
step() {
|
|
1591
|
+
this._idx++;
|
|
1592
|
+
return this._idx < this._rows.length;
|
|
1593
|
+
},
|
|
1594
|
+
getAsObject() {
|
|
1595
|
+
return this._rows[this._idx] || {};
|
|
1596
|
+
},
|
|
1597
|
+
get() {
|
|
1598
|
+
return this._rows[this._idx] ? Object.values(this._rows[this._idx]) : [];
|
|
1599
|
+
},
|
|
1600
|
+
free() {
|
|
1601
|
+
this._rows = null;
|
|
1602
|
+
}
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
export() {
|
|
1606
|
+
throw new Error("Bun:sqlite does not support in-memory export - use store/session for persistence, or use the sql.js backend for export/import operations");
|
|
1607
|
+
}
|
|
1608
|
+
close() {
|
|
1609
|
+
try {
|
|
1610
|
+
this._db.close();
|
|
1611
|
+
} catch {
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
get version() {
|
|
1615
|
+
return "bun:sqlite";
|
|
1616
|
+
}
|
|
1617
|
+
};
|
|
1618
|
+
__name(createBunSqlJs, "createBunSqlJs");
|
|
1619
|
+
}
|
|
1620
|
+
});
|
|
1621
|
+
|
|
1166
1622
|
// functions/sqlite/tools/db.support.ts
|
|
1167
1623
|
var db_support_exports2 = {};
|
|
1168
1624
|
function _inDocument() {
|
|
@@ -1223,11 +1679,18 @@ var init_db_support2 = __esm({
|
|
|
1223
1679
|
return g3.initSqlJs || g3;
|
|
1224
1680
|
}, "_loadSqlJsFromCdn");
|
|
1225
1681
|
exports.sqlite.db.support = () => {
|
|
1226
|
-
return hasSqlJs();
|
|
1682
|
+
return hasSqlJs() || hasBunSqlite();
|
|
1227
1683
|
};
|
|
1228
1684
|
exports.sqlite.db.getSQL = async () => {
|
|
1229
1685
|
if (_SQL) return _SQL;
|
|
1230
1686
|
if (_loading) return _loading;
|
|
1687
|
+
if (hasBunSqlite()) {
|
|
1688
|
+
const { createBunSqlJs: createBunSqlJs2 } = await Promise.resolve().then(() => (init_bun_sqlite_adapter(), bun_sqlite_adapter_exports));
|
|
1689
|
+
_SQL = await createBunSqlJs2();
|
|
1690
|
+
globalThis.sqliteVersion = _SQL.version;
|
|
1691
|
+
message_default("Memorio SQLite: bun:sqlite engine loaded");
|
|
1692
|
+
return _SQL;
|
|
1693
|
+
}
|
|
1231
1694
|
const g3 = globalThis;
|
|
1232
1695
|
const cfg = g3.sqliteConfig || {};
|
|
1233
1696
|
const p = (async () => {
|
|
@@ -1254,7 +1717,7 @@ var init_db_support2 = __esm({
|
|
|
1254
1717
|
} catch (_) {
|
|
1255
1718
|
}
|
|
1256
1719
|
try {
|
|
1257
|
-
exports.sqlite._warning = "Memorio SQLite: sql.js could not be loaded. Install sql.js (npm i sql.js) and pass a loader via sqlite.config({ loader: () => <your sql.js import>() }).";
|
|
1720
|
+
exports.sqlite._warning = "Memorio SQLite: sql.js could not be loaded. Install sql.js (npm i sql.js) and pass a loader via sqlite.config({ loader: () => import(<your sql.js import>()) }).";
|
|
1258
1721
|
} catch (_) {
|
|
1259
1722
|
}
|
|
1260
1723
|
console.warn("Memorio SQLite: failed to load sql.js", err);
|
|
@@ -1277,7 +1740,7 @@ function _ns() {
|
|
|
1277
1740
|
function _key(name) {
|
|
1278
1741
|
return `memorio:sqlite:db:${_ns()}:${name}`;
|
|
1279
1742
|
}
|
|
1280
|
-
function
|
|
1743
|
+
function _b64encode2(buf) {
|
|
1281
1744
|
const bytes = buf instanceof Uint8Array ? buf : new Uint8Array(buf);
|
|
1282
1745
|
let binary = "";
|
|
1283
1746
|
const len = bytes.byteLength;
|
|
@@ -1285,7 +1748,7 @@ function _b64encode(buf) {
|
|
|
1285
1748
|
if (typeof btoa === "function") return btoa(binary);
|
|
1286
1749
|
return typeof Buffer !== "undefined" ? Buffer.from(bytes).toString("base64") : "";
|
|
1287
1750
|
}
|
|
1288
|
-
function
|
|
1751
|
+
function _b64decode2(b64) {
|
|
1289
1752
|
if (typeof Buffer !== "undefined") {
|
|
1290
1753
|
return new Uint8Array(Buffer.from(b64, "base64"));
|
|
1291
1754
|
}
|
|
@@ -1307,7 +1770,7 @@ function saveSnapshot(name) {
|
|
|
1307
1770
|
}
|
|
1308
1771
|
try {
|
|
1309
1772
|
const blob = db.export();
|
|
1310
|
-
exports.store.set(_key(name),
|
|
1773
|
+
exports.store.set(_key(name), _b64encode2(blob));
|
|
1311
1774
|
message_default(`Memorio SQLite: persisted '${name}' to store`);
|
|
1312
1775
|
resolve(true);
|
|
1313
1776
|
} catch (err) {
|
|
@@ -1320,7 +1783,7 @@ function loadSnapshot(name) {
|
|
|
1320
1783
|
const b64 = exports.store.get(_key(name));
|
|
1321
1784
|
if (!b64) return null;
|
|
1322
1785
|
try {
|
|
1323
|
-
return
|
|
1786
|
+
return _b64decode2(b64);
|
|
1324
1787
|
} catch {
|
|
1325
1788
|
return null;
|
|
1326
1789
|
}
|
|
@@ -1355,8 +1818,8 @@ var init_persist = __esm({
|
|
|
1355
1818
|
_exportTimers = {};
|
|
1356
1819
|
__name(_ns, "_ns");
|
|
1357
1820
|
__name(_key, "_key");
|
|
1358
|
-
__name(
|
|
1359
|
-
__name(
|
|
1821
|
+
__name(_b64encode2, "_b64encode");
|
|
1822
|
+
__name(_b64decode2, "_b64decode");
|
|
1360
1823
|
__name(saveSnapshot, "saveSnapshot");
|
|
1361
1824
|
__name(loadSnapshot, "loadSnapshot");
|
|
1362
1825
|
__name(removeSnapshot, "removeSnapshot");
|
|
@@ -1561,7 +2024,14 @@ var init_db_export = __esm({
|
|
|
1561
2024
|
init_sqlite();
|
|
1562
2025
|
exports.sqlite.db.export = async (name = "memorio") => {
|
|
1563
2026
|
const db = exports.sqlite.db.get(name);
|
|
1564
|
-
|
|
2027
|
+
try {
|
|
2028
|
+
return db.export();
|
|
2029
|
+
} catch (err) {
|
|
2030
|
+
if (db && db.version === "bun:sqlite") {
|
|
2031
|
+
throw new Error(`memorio sqlite: export is not supported under Bun's native sqlite. Use \`store\` or \`session\` for persistence instead. If you need a binary dump, run this code under the browser/sql.js backend.`);
|
|
2032
|
+
}
|
|
2033
|
+
throw err;
|
|
2034
|
+
}
|
|
1565
2035
|
};
|
|
1566
2036
|
}
|
|
1567
2037
|
});
|
|
@@ -1645,13 +2115,14 @@ var init_data_get2 = __esm({
|
|
|
1645
2115
|
});
|
|
1646
2116
|
|
|
1647
2117
|
// functions/sqlite/index.ts
|
|
1648
|
-
var _hasSqlJs; exports.sqlite = void 0;
|
|
2118
|
+
var _hasSqlJs, _hasBunSqlite; exports.sqlite = void 0;
|
|
1649
2119
|
var init_sqlite = __esm({
|
|
1650
2120
|
"functions/sqlite/index.ts"() {
|
|
1651
2121
|
init_cjs_shims();
|
|
1652
2122
|
init_platform();
|
|
1653
2123
|
init_env();
|
|
1654
2124
|
_hasSqlJs = hasSqlJs();
|
|
2125
|
+
_hasBunSqlite = hasBunSqlite();
|
|
1655
2126
|
exports.sqlite = {
|
|
1656
2127
|
db: {},
|
|
1657
2128
|
query: {},
|
|
@@ -1678,7 +2149,7 @@ var init_sqlite = __esm({
|
|
|
1678
2149
|
return g3.sqliteReady;
|
|
1679
2150
|
}, "get")
|
|
1680
2151
|
});
|
|
1681
|
-
if (_hasSqlJs) {
|
|
2152
|
+
if (_hasSqlJs || _hasBunSqlite) {
|
|
1682
2153
|
(async () => {
|
|
1683
2154
|
Object.defineProperty(exports.sqlite, "db", { value: {}, writable: false, configurable: true, enumerable: true });
|
|
1684
2155
|
Object.defineProperty(exports.sqlite, "query", { value: {}, writable: false, configurable: true, enumerable: true });
|
|
@@ -1706,11 +2177,11 @@ var init_sqlite = __esm({
|
|
|
1706
2177
|
})();
|
|
1707
2178
|
} else {
|
|
1708
2179
|
exports.sqlite._disabled = true;
|
|
1709
|
-
exports.sqlite._warning = 'SQLite
|
|
2180
|
+
exports.sqlite._warning = 'SQLite is not available in this environment. It requires a browser with WebAssembly (sql.js) or the Bun runtime (bun:sqlite). Install the optional "sql.js" package to enable it in browsers.';
|
|
1710
2181
|
if (exports.DEV) {
|
|
1711
2182
|
globalThis.sqliteDisabled = true;
|
|
1712
2183
|
globalThis.sqliteWarning = exports.sqlite._warning;
|
|
1713
|
-
console.warn("Memorio SQLite:
|
|
2184
|
+
console.warn("Memorio SQLite: no engine available in this environment (requires browser + WebAssembly, or Bun runtime with bun:sqlite). Use store or session for persistence.");
|
|
1714
2185
|
}
|
|
1715
2186
|
}
|
|
1716
2187
|
}
|
|
@@ -1753,9 +2224,25 @@ var dispatch = {
|
|
|
1753
2224
|
const wrapped = /* @__PURE__ */ __name((e) => {
|
|
1754
2225
|
const target = e;
|
|
1755
2226
|
if (globalThis.queueMicrotask) {
|
|
1756
|
-
globalThis.queueMicrotask(() =>
|
|
2227
|
+
globalThis.queueMicrotask(() => {
|
|
2228
|
+
try {
|
|
2229
|
+
cb(target);
|
|
2230
|
+
} catch (err) {
|
|
2231
|
+
if (typeof console !== "undefined") {
|
|
2232
|
+
console.error("[memorio dispatch] observer error:", err);
|
|
2233
|
+
}
|
|
2234
|
+
}
|
|
2235
|
+
});
|
|
1757
2236
|
} else {
|
|
1758
|
-
Promise.resolve().then(() =>
|
|
2237
|
+
Promise.resolve().then(() => {
|
|
2238
|
+
try {
|
|
2239
|
+
cb(target);
|
|
2240
|
+
} catch (err) {
|
|
2241
|
+
if (typeof console !== "undefined") {
|
|
2242
|
+
console.error("[memorio dispatch] observer error:", err);
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
});
|
|
1759
2246
|
}
|
|
1760
2247
|
}, "wrapped");
|
|
1761
2248
|
globalThis.addEventListener(name, wrapped);
|
|
@@ -1891,101 +2378,589 @@ var schema = {
|
|
|
1891
2378
|
// functions/state/index.ts
|
|
1892
2379
|
init_store();
|
|
1893
2380
|
init_env();
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
2381
|
+
|
|
2382
|
+
// core/mutation/engine.ts
|
|
2383
|
+
init_cjs_shims();
|
|
2384
|
+
init_internal();
|
|
2385
|
+
|
|
2386
|
+
// core/hlc.ts
|
|
2387
|
+
init_cjs_shims();
|
|
2388
|
+
var NODE_ID_KEY = "__memorio_hlc_node";
|
|
2389
|
+
function getNodeId() {
|
|
2390
|
+
if (typeof globalThis === "undefined") return "node";
|
|
2391
|
+
try {
|
|
2392
|
+
if (typeof sessionStorage !== "undefined" && sessionStorage) {
|
|
2393
|
+
let id = sessionStorage.getItem(NODE_ID_KEY);
|
|
2394
|
+
if (!id) {
|
|
2395
|
+
id = generateNodeId();
|
|
2396
|
+
sessionStorage.setItem(NODE_ID_KEY, id);
|
|
2397
|
+
}
|
|
2398
|
+
return id;
|
|
2399
|
+
}
|
|
2400
|
+
} catch {
|
|
1902
2401
|
}
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
const copy = Array.isArray(val) ? [] : {};
|
|
1906
|
-
for (const k of Reflect.ownKeys(val)) {
|
|
1907
|
-
if (!Object.prototype.propertyIsEnumerable.call(val, k)) continue;
|
|
1908
|
-
copy[k] = deepRaw(val[k], seen);
|
|
2402
|
+
if (!globalThis.__memorioHlcNodeId) {
|
|
2403
|
+
globalThis.__memorioHlcNodeId = generateNodeId();
|
|
1909
2404
|
}
|
|
1910
|
-
return
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
2405
|
+
return globalThis.__memorioHlcNodeId;
|
|
2406
|
+
}
|
|
2407
|
+
__name(getNodeId, "getNodeId");
|
|
2408
|
+
function generateNodeId() {
|
|
2409
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
2410
|
+
return crypto.randomUUID().slice(0, 8);
|
|
2411
|
+
}
|
|
2412
|
+
return Math.random().toString(36).slice(2, 10);
|
|
2413
|
+
}
|
|
2414
|
+
__name(generateNodeId, "generateNodeId");
|
|
2415
|
+
var HLC_KEY = "__memorio_hlc_local";
|
|
2416
|
+
var local = globalThis[HLC_KEY] || {
|
|
2417
|
+
physical: 0,
|
|
2418
|
+
logical: 0,
|
|
2419
|
+
node: getNodeId()
|
|
2420
|
+
};
|
|
2421
|
+
if (!globalThis[HLC_KEY]) {
|
|
2422
|
+
globalThis[HLC_KEY] = local;
|
|
2423
|
+
}
|
|
2424
|
+
function tick(_incoming) {
|
|
2425
|
+
const now2 = Date.now();
|
|
2426
|
+
const base = local.physical;
|
|
2427
|
+
let physical;
|
|
2428
|
+
let logical;
|
|
2429
|
+
if (now2 > base) {
|
|
2430
|
+
physical = now2;
|
|
2431
|
+
logical = 0;
|
|
2432
|
+
} else if (now2 < base) {
|
|
2433
|
+
physical = base;
|
|
2434
|
+
logical = local.logical + 1;
|
|
2435
|
+
} else {
|
|
2436
|
+
physical = base;
|
|
2437
|
+
logical = local.logical + 1;
|
|
2438
|
+
}
|
|
2439
|
+
local.physical = physical;
|
|
2440
|
+
local.logical = logical;
|
|
2441
|
+
return { physical, logical, node: local.node };
|
|
2442
|
+
}
|
|
2443
|
+
__name(tick, "tick");
|
|
2444
|
+
function receive(remote) {
|
|
2445
|
+
const now2 = Date.now();
|
|
2446
|
+
if (remote.physical > local.physical) {
|
|
2447
|
+
local.physical = remote.physical > now2 ? remote.physical : now2;
|
|
2448
|
+
local.logical = 1;
|
|
2449
|
+
} else if (remote.physical === local.physical) {
|
|
2450
|
+
local.logical = Math.max(local.logical, remote.logical) + 1;
|
|
2451
|
+
}
|
|
2452
|
+
local.node = getNodeId();
|
|
2453
|
+
return { ...local };
|
|
2454
|
+
}
|
|
2455
|
+
__name(receive, "receive");
|
|
2456
|
+
function compare(a, b) {
|
|
2457
|
+
if (a.physical !== b.physical) {
|
|
2458
|
+
return a.physical < b.physical ? -1 : 1;
|
|
2459
|
+
}
|
|
2460
|
+
if (a.logical !== b.logical) {
|
|
2461
|
+
return a.logical < b.logical ? -1 : 1;
|
|
2462
|
+
}
|
|
2463
|
+
if (a.node !== b.node) {
|
|
2464
|
+
return a.node < b.node ? -1 : 1;
|
|
2465
|
+
}
|
|
2466
|
+
return 0;
|
|
2467
|
+
}
|
|
2468
|
+
__name(compare, "compare");
|
|
2469
|
+
function happenedBefore(a, b) {
|
|
2470
|
+
return compare(a, b) < 0;
|
|
2471
|
+
}
|
|
2472
|
+
__name(happenedBefore, "happenedBefore");
|
|
2473
|
+
function serialize(hlc2) {
|
|
2474
|
+
return `hlc:${hlc2.physical}:${hlc2.logical}:${hlc2.node}`;
|
|
2475
|
+
}
|
|
2476
|
+
__name(serialize, "serialize");
|
|
2477
|
+
function parse(serialized) {
|
|
2478
|
+
if (!serialized.startsWith("hlc:")) return null;
|
|
2479
|
+
const parts = serialized.split(":");
|
|
2480
|
+
if (parts.length !== 4) return null;
|
|
2481
|
+
const physical = parseInt(parts[1], 10);
|
|
2482
|
+
const logical = parseInt(parts[2], 10);
|
|
2483
|
+
const node = parts[3];
|
|
2484
|
+
if (isNaN(physical) || isNaN(logical)) return null;
|
|
2485
|
+
return { physical, logical, node };
|
|
2486
|
+
}
|
|
2487
|
+
__name(parse, "parse");
|
|
2488
|
+
var hlc = {
|
|
2489
|
+
tick,
|
|
2490
|
+
receive,
|
|
2491
|
+
compare,
|
|
2492
|
+
happenedBefore,
|
|
2493
|
+
serialize,
|
|
2494
|
+
parse,
|
|
2495
|
+
getNodeId
|
|
2496
|
+
};
|
|
2497
|
+
|
|
2498
|
+
// core/mutation/id.ts
|
|
2499
|
+
init_cjs_shims();
|
|
2500
|
+
function generateMutationId() {
|
|
2501
|
+
const now2 = hlc.tick();
|
|
2502
|
+
return "m_" + encodeHLC(now2);
|
|
2503
|
+
}
|
|
2504
|
+
__name(generateMutationId, "generateMutationId");
|
|
2505
|
+
function generateTransactionId() {
|
|
2506
|
+
const now2 = hlc.tick();
|
|
2507
|
+
return "tx_" + encodeHLC(now2);
|
|
2508
|
+
}
|
|
2509
|
+
__name(generateTransactionId, "generateTransactionId");
|
|
2510
|
+
function generateCommitId() {
|
|
2511
|
+
const now2 = hlc.tick();
|
|
2512
|
+
return "c_" + encodeHLC(now2);
|
|
2513
|
+
}
|
|
2514
|
+
__name(generateCommitId, "generateCommitId");
|
|
2515
|
+
function encodeHLC(hlcValue) {
|
|
2516
|
+
const timePart = hlcValue.physical.toString(36);
|
|
2517
|
+
const logicalPart = hlcValue.logical.toString(36).padStart(2, "0");
|
|
2518
|
+
const nodePart = hlcValue.node.slice(0, 4);
|
|
2519
|
+
return `${timePart}${logicalPart}${nodePart}`;
|
|
2520
|
+
}
|
|
2521
|
+
__name(encodeHLC, "encodeHLC");
|
|
2522
|
+
|
|
2523
|
+
// core/mutation/patch.ts
|
|
2524
|
+
init_cjs_shims();
|
|
2525
|
+
function mutationToPatch(mutation) {
|
|
2526
|
+
if (mutation.before === mutation.after) return null;
|
|
2527
|
+
const op = mutationToPatchOp(mutation.operation, mutation.before, mutation.after);
|
|
2528
|
+
if (!op) return null;
|
|
2529
|
+
const patch = { op, path: mutation.path };
|
|
2530
|
+
if (op === "add" || op === "replace") {
|
|
2531
|
+
patch.value = mutation.after;
|
|
2532
|
+
}
|
|
2533
|
+
if (op === "replace") {
|
|
2534
|
+
patch.oldValue = mutation.before;
|
|
2535
|
+
}
|
|
2536
|
+
if (op === "remove") {
|
|
2537
|
+
patch.oldValue = mutation.before;
|
|
2538
|
+
}
|
|
2539
|
+
return patch;
|
|
2540
|
+
}
|
|
2541
|
+
__name(mutationToPatch, "mutationToPatch");
|
|
2542
|
+
function mutationToPatchOp(operation, _before, _after) {
|
|
2543
|
+
switch (operation) {
|
|
2544
|
+
case "set":
|
|
2545
|
+
if (_before === void 0) return "add";
|
|
2546
|
+
return "replace";
|
|
2547
|
+
case "delete":
|
|
2548
|
+
return "remove";
|
|
2549
|
+
case "insert":
|
|
2550
|
+
return "add";
|
|
2551
|
+
case "remove":
|
|
2552
|
+
return "remove";
|
|
2553
|
+
case "replace":
|
|
2554
|
+
return "replace";
|
|
2555
|
+
case "length":
|
|
2556
|
+
return "replace";
|
|
2557
|
+
default:
|
|
2558
|
+
return null;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
__name(mutationToPatchOp, "mutationToPatchOp");
|
|
2562
|
+
function diffToPatch(path, before2, after2) {
|
|
2563
|
+
if (before2 === after2) return null;
|
|
2564
|
+
if (after2 === void 0) {
|
|
2565
|
+
return { op: "remove", path, oldValue: before2 };
|
|
2566
|
+
}
|
|
2567
|
+
if (before2 === void 0) {
|
|
2568
|
+
return { op: "add", path, value: after2 };
|
|
2569
|
+
}
|
|
2570
|
+
return { op: "replace", path, value: after2, oldValue: before2 };
|
|
2571
|
+
}
|
|
2572
|
+
__name(diffToPatch, "diffToPatch");
|
|
2573
|
+
function canMerge(patch1, patch2) {
|
|
2574
|
+
return patch1.path === patch2.path && patch1.op === patch2.op;
|
|
2575
|
+
}
|
|
2576
|
+
__name(canMerge, "canMerge");
|
|
2577
|
+
function mergePatches(patch1, patch2) {
|
|
2578
|
+
const op = patch1.op === "remove" && patch2.op === "remove" ? "remove" : "replace";
|
|
2579
|
+
return {
|
|
2580
|
+
op,
|
|
2581
|
+
path: patch1.path,
|
|
2582
|
+
value: patch2.value ?? patch1.value,
|
|
2583
|
+
oldValue: patch1.oldValue
|
|
2584
|
+
};
|
|
2585
|
+
}
|
|
2586
|
+
__name(mergePatches, "mergePatches");
|
|
2587
|
+
|
|
2588
|
+
// core/mutation/transaction.ts
|
|
2589
|
+
init_cjs_shims();
|
|
2590
|
+
init_internal();
|
|
2591
|
+
var TX_REGISTRY_KEY = "__memorio_transaction_registry__";
|
|
2592
|
+
var registry = globalThis[TX_REGISTRY_KEY] || /* @__PURE__ */ new Map();
|
|
2593
|
+
if (!globalThis[TX_REGISTRY_KEY]) {
|
|
2594
|
+
globalThis[TX_REGISTRY_KEY] = registry;
|
|
2595
|
+
}
|
|
2596
|
+
var TX_STACK_KEY = "__memorio_transaction_stack__";
|
|
2597
|
+
var txStack = globalThis[TX_STACK_KEY] || [];
|
|
2598
|
+
if (!globalThis[TX_STACK_KEY]) {
|
|
2599
|
+
globalThis[TX_STACK_KEY] = txStack;
|
|
2600
|
+
}
|
|
2601
|
+
function getActiveTxId() {
|
|
2602
|
+
return txStack.length > 0 ? txStack[txStack.length - 1] : null;
|
|
2603
|
+
}
|
|
2604
|
+
__name(getActiveTxId, "getActiveTxId");
|
|
2605
|
+
function setActiveTx(id) {
|
|
2606
|
+
if (id === null) {
|
|
2607
|
+
txStack.pop();
|
|
2608
|
+
} else {
|
|
2609
|
+
txStack.push(id);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
__name(setActiveTx, "setActiveTx");
|
|
2613
|
+
function beginTransaction(source, message2, metadata) {
|
|
2614
|
+
const id = generateTransactionId();
|
|
2615
|
+
const ctx = {
|
|
2616
|
+
id,
|
|
2617
|
+
startedAt: hlc.serialize(hlc.tick()),
|
|
2618
|
+
source,
|
|
2619
|
+
message: message2,
|
|
2620
|
+
metadata,
|
|
2621
|
+
mutations: [],
|
|
2622
|
+
active: true
|
|
2623
|
+
};
|
|
2624
|
+
registry.set(id, ctx);
|
|
2625
|
+
setActiveTx(id);
|
|
2626
|
+
return ctx;
|
|
2627
|
+
}
|
|
2628
|
+
__name(beginTransaction, "beginTransaction");
|
|
2629
|
+
function tagForTransaction() {
|
|
2630
|
+
const txId = getActiveTxId();
|
|
2631
|
+
if (!txId) return void 0;
|
|
2632
|
+
const ctx = registry.get(txId);
|
|
2633
|
+
if (ctx && ctx.active) {
|
|
2634
|
+
return txId;
|
|
2635
|
+
}
|
|
2636
|
+
return void 0;
|
|
2637
|
+
}
|
|
2638
|
+
__name(tagForTransaction, "tagForTransaction");
|
|
2639
|
+
function commitTransaction() {
|
|
2640
|
+
const txId = getActiveTxId();
|
|
2641
|
+
if (!txId) return null;
|
|
2642
|
+
const ctx = registry.get(txId);
|
|
2643
|
+
if (!ctx || !ctx.active) return null;
|
|
2644
|
+
ctx.active = false;
|
|
2645
|
+
ctx.committedAt = hlc.serialize(hlc.tick());
|
|
2646
|
+
const tx = {
|
|
2647
|
+
id: ctx.id,
|
|
2648
|
+
mutations: ctx.mutations,
|
|
2649
|
+
startedAt: ctx.startedAt,
|
|
2650
|
+
committedAt: ctx.committedAt,
|
|
2651
|
+
source: ctx.source,
|
|
2652
|
+
message: ctx.message,
|
|
2653
|
+
metadata: ctx.metadata
|
|
2654
|
+
};
|
|
2655
|
+
setActiveTx(null);
|
|
2656
|
+
return tx;
|
|
2657
|
+
}
|
|
2658
|
+
__name(commitTransaction, "commitTransaction");
|
|
2659
|
+
function _setPath(path, value) {
|
|
2660
|
+
const parts = path.replace(/^state\./, "").split(".");
|
|
2661
|
+
let current = globalThis.state;
|
|
2662
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2663
|
+
const part = parts[i];
|
|
2664
|
+
if (current[part] === void 0) {
|
|
2665
|
+
current[part] = {};
|
|
2666
|
+
}
|
|
2667
|
+
current = current[part];
|
|
2668
|
+
}
|
|
2669
|
+
current[parts[parts.length - 1]] = value;
|
|
2670
|
+
}
|
|
2671
|
+
__name(_setPath, "_setPath");
|
|
2672
|
+
function _deletePath(path) {
|
|
2673
|
+
const parts = path.replace(/^state\./, "").split(".");
|
|
2674
|
+
let current = globalThis.state;
|
|
2675
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2676
|
+
const part = parts[i];
|
|
2677
|
+
if (current[part] === void 0) return;
|
|
2678
|
+
current = current[part];
|
|
2679
|
+
}
|
|
2680
|
+
if (current.remove) {
|
|
2681
|
+
current.remove(parts[parts.length - 1]);
|
|
2682
|
+
} else {
|
|
2683
|
+
delete current[parts[parts.length - 1]];
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
__name(_deletePath, "_deletePath");
|
|
2687
|
+
function _applyInverse(record) {
|
|
2688
|
+
const wasEnabled = exports.internal.historyEnabled;
|
|
2689
|
+
const wasRecording = exports.internal._recording;
|
|
2690
|
+
exports.internal.historyEnabled = false;
|
|
2691
|
+
exports.internal._recording = false;
|
|
2692
|
+
try {
|
|
2693
|
+
if (record.action === "set" || record.operation === "set") {
|
|
2694
|
+
if (record.previousValue === void 0) {
|
|
2695
|
+
_deletePath(record.path);
|
|
2696
|
+
} else {
|
|
2697
|
+
_setPath(record.path, record.previousValue);
|
|
2698
|
+
}
|
|
2699
|
+
} else if (record.action === "delete" || record.operation === "delete") {
|
|
2700
|
+
if (record.previousValue !== void 0) {
|
|
2701
|
+
_setPath(record.path, record.previousValue);
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2704
|
+
} finally {
|
|
2705
|
+
exports.internal.historyEnabled = wasEnabled;
|
|
2706
|
+
exports.internal._recording = wasRecording;
|
|
2707
|
+
}
|
|
2708
|
+
}
|
|
2709
|
+
__name(_applyInverse, "_applyInverse");
|
|
2710
|
+
function abortTransaction() {
|
|
2711
|
+
const txId = getActiveTxId();
|
|
2712
|
+
if (!txId) return null;
|
|
2713
|
+
const ctx = registry.get(txId);
|
|
2714
|
+
if (!ctx || !ctx.active) return null;
|
|
2715
|
+
for (let i = ctx.mutations.length - 1; i >= 0; i--) {
|
|
2716
|
+
const undoStack = exports.internal.undoStack;
|
|
2717
|
+
const idx = undoStack.findIndex((r) => r.id === ctx.mutations[i]);
|
|
2718
|
+
if (idx >= 0) {
|
|
2719
|
+
const record = undoStack[idx];
|
|
2720
|
+
exports.internal.undoStack.splice(idx, 1);
|
|
2721
|
+
_applyInverse(record);
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
ctx.active = false;
|
|
2725
|
+
ctx.committedAt = hlc.serialize(hlc.tick());
|
|
2726
|
+
const tx = {
|
|
2727
|
+
id: ctx.id,
|
|
2728
|
+
mutations: ctx.mutations,
|
|
2729
|
+
startedAt: ctx.startedAt,
|
|
2730
|
+
committedAt: ctx.committedAt,
|
|
2731
|
+
source: ctx.source,
|
|
2732
|
+
message: ctx.message,
|
|
2733
|
+
metadata: ctx.metadata
|
|
2734
|
+
};
|
|
2735
|
+
registry.delete(txId);
|
|
2736
|
+
setActiveTx(null);
|
|
2737
|
+
return tx;
|
|
2738
|
+
}
|
|
2739
|
+
__name(abortTransaction, "abortTransaction");
|
|
2740
|
+
function listTransactions() {
|
|
2741
|
+
const result = [];
|
|
2742
|
+
for (const ctx of registry.values()) {
|
|
2743
|
+
result.push({
|
|
2744
|
+
id: ctx.id,
|
|
2745
|
+
mutations: ctx.mutations,
|
|
2746
|
+
startedAt: ctx.startedAt,
|
|
2747
|
+
committedAt: ctx.committedAt,
|
|
2748
|
+
source: ctx.source,
|
|
2749
|
+
message: ctx.message,
|
|
2750
|
+
metadata: ctx.metadata
|
|
2751
|
+
});
|
|
2752
|
+
}
|
|
2753
|
+
return result;
|
|
2754
|
+
}
|
|
2755
|
+
__name(listTransactions, "listTransactions");
|
|
2756
|
+
function currentTransaction() {
|
|
2757
|
+
const txId = getActiveTxId();
|
|
2758
|
+
if (!txId) return null;
|
|
2759
|
+
const ctx = registry.get(txId);
|
|
2760
|
+
if (!ctx || !ctx.active) return null;
|
|
2761
|
+
return {
|
|
2762
|
+
id: ctx.id,
|
|
2763
|
+
mutations: ctx.mutations,
|
|
2764
|
+
startedAt: ctx.startedAt,
|
|
2765
|
+
source: ctx.source,
|
|
2766
|
+
message: ctx.message,
|
|
2767
|
+
metadata: ctx.metadata
|
|
2768
|
+
};
|
|
2769
|
+
}
|
|
2770
|
+
__name(currentTransaction, "currentTransaction");
|
|
2771
|
+
function registerMutationInTransaction(mutationId) {
|
|
2772
|
+
const txId = getActiveTxId();
|
|
2773
|
+
if (!txId) return;
|
|
2774
|
+
const ctx = registry.get(txId);
|
|
2775
|
+
if (ctx && ctx.active) {
|
|
2776
|
+
ctx.mutations.push(mutationId);
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
__name(registerMutationInTransaction, "registerMutationInTransaction");
|
|
2780
|
+
|
|
2781
|
+
// core/mutation/engine.ts
|
|
2782
|
+
function currentTimestamp() {
|
|
2783
|
+
return hlc.serialize(hlc.tick());
|
|
2784
|
+
}
|
|
2785
|
+
__name(currentTimestamp, "currentTimestamp");
|
|
2786
|
+
function createMutation(path, operation, before2, after2, options) {
|
|
2787
|
+
const now2 = hlc.tick();
|
|
2788
|
+
const mutation = {
|
|
2789
|
+
id: generateMutationId(),
|
|
2790
|
+
path,
|
|
2791
|
+
operation,
|
|
2792
|
+
after: after2,
|
|
2793
|
+
before: before2,
|
|
2794
|
+
timestamp: now2.physical,
|
|
2795
|
+
hlc: hlc.serialize(now2),
|
|
2796
|
+
context: options?.context || exports.internal.currentContext || void 0,
|
|
2797
|
+
source: options?.source,
|
|
2798
|
+
transactionId: options?.transactionId || (operation !== "length" ? tagForTransaction() : void 0),
|
|
2799
|
+
// Legacy fields for backward compatibility
|
|
2800
|
+
action: operation === "set" ? "set" : "delete",
|
|
2801
|
+
newValue: after2,
|
|
2802
|
+
previousValue: before2
|
|
2803
|
+
};
|
|
2804
|
+
if (mutation.transactionId) {
|
|
2805
|
+
registerMutationInTransaction(mutation.id);
|
|
2806
|
+
}
|
|
2807
|
+
return mutation;
|
|
2808
|
+
}
|
|
2809
|
+
__name(createMutation, "createMutation");
|
|
2810
|
+
function recordMutation(mutation) {
|
|
2811
|
+
if (!exports.internal.historyEnabled) return;
|
|
2812
|
+
exports.internal.recordMutation(mutation);
|
|
2813
|
+
}
|
|
2814
|
+
__name(recordMutation, "recordMutation");
|
|
2815
|
+
function toPatch(mutation) {
|
|
2816
|
+
return mutationToPatch(mutation);
|
|
2817
|
+
}
|
|
2818
|
+
__name(toPatch, "toPatch");
|
|
2819
|
+
function mutate(path, value, options) {
|
|
2820
|
+
const normalizedPath = path.startsWith("state.") ? path : "state." + path;
|
|
2821
|
+
const keyPath = normalizedPath.replace(/^state\./, "");
|
|
2822
|
+
let current;
|
|
2823
|
+
try {
|
|
2824
|
+
const parts2 = keyPath.split(".");
|
|
2825
|
+
let obj = globalThis.state;
|
|
2826
|
+
for (const part of parts2) {
|
|
2827
|
+
obj = obj?.[part];
|
|
2828
|
+
}
|
|
2829
|
+
current = obj;
|
|
2830
|
+
} catch {
|
|
2831
|
+
current = void 0;
|
|
2832
|
+
}
|
|
2833
|
+
const operation = value === void 0 ? "delete" : "set";
|
|
2834
|
+
const mutation = createMutation(
|
|
2835
|
+
normalizedPath,
|
|
2836
|
+
operation,
|
|
2837
|
+
current,
|
|
2838
|
+
value === void 0 ? void 0 : value,
|
|
2839
|
+
options
|
|
2840
|
+
);
|
|
2841
|
+
const wasRecording = exports.internal._recording;
|
|
2842
|
+
exports.internal._recording = false;
|
|
2843
|
+
const parts = keyPath.split(".");
|
|
2844
|
+
let target = globalThis.state;
|
|
2845
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
2846
|
+
if (target[parts[i]] === void 0) {
|
|
2847
|
+
target[parts[i]] = {};
|
|
2848
|
+
}
|
|
2849
|
+
target = target[parts[i]];
|
|
2850
|
+
}
|
|
2851
|
+
if (operation === "delete") {
|
|
2852
|
+
delete target[parts[parts.length - 1]];
|
|
2853
|
+
} else {
|
|
2854
|
+
target[parts[parts.length - 1]] = value;
|
|
2855
|
+
}
|
|
2856
|
+
exports.internal._recording = wasRecording;
|
|
2857
|
+
recordMutation(mutation);
|
|
2858
|
+
return mutation;
|
|
2859
|
+
}
|
|
2860
|
+
__name(mutate, "mutate");
|
|
2861
|
+
function activeTransactionId() {
|
|
2862
|
+
return exports.internal.currentTransactionId || null;
|
|
2863
|
+
}
|
|
2864
|
+
__name(activeTransactionId, "activeTransactionId");
|
|
2865
|
+
|
|
2866
|
+
// functions/state/index.ts
|
|
2867
|
+
var TARGET = /* @__PURE__ */ Symbol("memorio.target");
|
|
2868
|
+
var wrapperCache = /* @__PURE__ */ new WeakMap();
|
|
2869
|
+
var arrayRootDedup = /* @__PURE__ */ new Set();
|
|
2870
|
+
var deepRaw = /* @__PURE__ */ __name((val, seen = null) => {
|
|
2871
|
+
if (val === null || typeof val !== "object") return val;
|
|
2872
|
+
if (!seen) seen = /* @__PURE__ */ new WeakSet();
|
|
2873
|
+
if (val[TARGET] !== void 0) return deepRaw(val[TARGET], seen);
|
|
2874
|
+
if (seen) {
|
|
2875
|
+
if (seen.has(val)) return val;
|
|
2876
|
+
seen.add(val);
|
|
2877
|
+
}
|
|
2878
|
+
const ctor = val.constructor?.name;
|
|
2879
|
+
if (ctor !== "Object" && ctor !== "Array") return val;
|
|
2880
|
+
const copy = Array.isArray(val) ? [] : {};
|
|
2881
|
+
for (const k of Reflect.ownKeys(val)) {
|
|
2882
|
+
if (!Object.prototype.propertyIsEnumerable.call(val, k)) continue;
|
|
2883
|
+
copy[k] = deepRaw(val[k], seen);
|
|
2884
|
+
}
|
|
2885
|
+
return copy;
|
|
2886
|
+
}, "deepRaw");
|
|
2887
|
+
var objPath = /* @__PURE__ */ __name((prop, object, separator = ".") => {
|
|
2888
|
+
return object.concat(prop).join(separator);
|
|
2889
|
+
}, "objPath");
|
|
2890
|
+
var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
|
|
2891
|
+
const event = /* @__PURE__ */ __name((name) => {
|
|
2892
|
+
try {
|
|
2893
|
+
dispatch.set(name, { detail: { name } });
|
|
2894
|
+
} catch (err) {
|
|
2895
|
+
if (exports.DEV) console.warn("[memorio state] event dispatch failed:", err);
|
|
2896
|
+
}
|
|
2897
|
+
return;
|
|
2898
|
+
}, "event");
|
|
2899
|
+
return new Proxy(
|
|
2900
|
+
obj,
|
|
2901
|
+
{
|
|
2902
|
+
get(target, prop) {
|
|
2903
|
+
if (prop === "__path") {
|
|
2904
|
+
return tree.length > 0 ? "state." + tree.join(".") : "state";
|
|
2905
|
+
}
|
|
2906
|
+
if (prop === TARGET) {
|
|
2907
|
+
return target;
|
|
2908
|
+
}
|
|
2909
|
+
if (target[TARGET] !== void 0) {
|
|
2910
|
+
return target;
|
|
2911
|
+
}
|
|
2912
|
+
if (prop === "list") {
|
|
2913
|
+
message_default('Some state could be hidden when you use "state.list". Use "state" to see the complete list ');
|
|
2914
|
+
return deepRaw(target, /* @__PURE__ */ new WeakSet());
|
|
2915
|
+
}
|
|
2916
|
+
if (typeof prop === "string") {
|
|
2917
|
+
const path = tree.length > 0 ? "state." + tree.concat(prop).join(".") : "state." + prop;
|
|
2918
|
+
exports.internal.lastAccessedPath = path;
|
|
2919
|
+
if (exports.internal.tracking) {
|
|
2920
|
+
exports.internal.trackedPaths.add(path);
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
if (prop === "_lastPath") {
|
|
2924
|
+
return exports.internal.lastAccessedPath;
|
|
2925
|
+
}
|
|
2926
|
+
if (prop === "remove") {
|
|
2927
|
+
return (key) => {
|
|
2928
|
+
delete target[key];
|
|
2929
|
+
return true;
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
if (prop === "removeAll") {
|
|
2933
|
+
return () => {
|
|
2934
|
+
try {
|
|
2935
|
+
for (const key of Reflect.ownKeys(target)) {
|
|
2936
|
+
if (typeof target[key] !== "function" && !["list", "remove", "removeAll", "lock", "unlock", "persist"].includes(key)) {
|
|
2937
|
+
delete target[key];
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
} catch (error) {
|
|
2941
|
+
console.error(error);
|
|
2942
|
+
}
|
|
2943
|
+
return;
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
if (Object.isFrozen(target[prop])) return target[prop];
|
|
2947
|
+
if (prop === "lock" || prop === "unlock") {
|
|
2948
|
+
const value = Reflect.get(target, prop);
|
|
2949
|
+
if (value) return value;
|
|
2950
|
+
}
|
|
2951
|
+
try {
|
|
2952
|
+
const value = Reflect.get(target, prop);
|
|
2953
|
+
if (value && typeof value === "object" && ["Array", "Object"].includes(value.constructor.name)) {
|
|
2954
|
+
let wrapper = wrapperCache.get(value);
|
|
2955
|
+
if (!wrapper) {
|
|
2956
|
+
wrapper = buildProxy(value, callback, tree.concat(prop));
|
|
2957
|
+
wrapperCache.set(value, wrapper);
|
|
2958
|
+
}
|
|
2959
|
+
return wrapper;
|
|
2960
|
+
}
|
|
2961
|
+
return value;
|
|
2962
|
+
} catch (error) {
|
|
2963
|
+
console.error("Error: ", error);
|
|
1989
2964
|
return void 0;
|
|
1990
2965
|
}
|
|
1991
2966
|
},
|
|
@@ -2032,6 +3007,16 @@ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
|
|
|
2032
3007
|
}
|
|
2033
3008
|
);
|
|
2034
3009
|
event("state." + path);
|
|
3010
|
+
if (Array.isArray(target) && tree.length > 0) {
|
|
3011
|
+
const rootName = "state." + tree.join(".");
|
|
3012
|
+
if (!arrayRootDedup.has(rootName)) {
|
|
3013
|
+
arrayRootDedup.add(rootName);
|
|
3014
|
+
event(rootName);
|
|
3015
|
+
if (typeof globalThis.queueMicrotask === "function") {
|
|
3016
|
+
globalThis.queueMicrotask(() => arrayRootDedup.clear());
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
2035
3020
|
Reflect.set(target, key, rawValue);
|
|
2036
3021
|
exports.internal.bumpStateVersion();
|
|
2037
3022
|
if (target[key] && typeof target[key] === "object") {
|
|
@@ -2088,6 +3073,17 @@ var buildProxy = /* @__PURE__ */ __name((obj, callback, tree = []) => {
|
|
|
2088
3073
|
const path = objPath(prop, tree);
|
|
2089
3074
|
const previousValue = Reflect.get(target, prop);
|
|
2090
3075
|
callback({ action: "delete", path, target, previousValue });
|
|
3076
|
+
event("state." + path);
|
|
3077
|
+
if (Array.isArray(target) && tree.length > 0) {
|
|
3078
|
+
const rootName = "state." + tree.join(".");
|
|
3079
|
+
if (!arrayRootDedup.has(rootName)) {
|
|
3080
|
+
arrayRootDedup.add(rootName);
|
|
3081
|
+
event(rootName);
|
|
3082
|
+
if (typeof globalThis.queueMicrotask === "function") {
|
|
3083
|
+
globalThis.queueMicrotask(() => arrayRootDedup.clear());
|
|
3084
|
+
}
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
2091
3087
|
return Reflect.deleteProperty(target, prop);
|
|
2092
3088
|
} catch (error) {
|
|
2093
3089
|
console.error("Error in deleteProperty trap:", error);
|
|
@@ -2109,57 +3105,83 @@ if (globalThis[STATE_INSTANCE_KEY]) {
|
|
|
2109
3105
|
exports.state = globalThis[STATE_INSTANCE_KEY];
|
|
2110
3106
|
} else {
|
|
2111
3107
|
exports.state = buildProxy({}, (mutation) => {
|
|
2112
|
-
if (exports.internal.historyEnabled) {
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
3108
|
+
if (exports.internal.historyEnabled && exports.internal._recording !== false) {
|
|
3109
|
+
const operation = mutation.action === "delete" ? "delete" : "set";
|
|
3110
|
+
const record = createMutation(
|
|
3111
|
+
mutation.path,
|
|
3112
|
+
operation,
|
|
3113
|
+
mutation.previousValue,
|
|
3114
|
+
mutation.newValue,
|
|
3115
|
+
{
|
|
3116
|
+
context: mutation.context,
|
|
3117
|
+
source: mutation.source
|
|
3118
|
+
}
|
|
3119
|
+
);
|
|
3120
|
+
exports.internal.recordMutation(record);
|
|
2120
3121
|
}
|
|
2121
3122
|
});
|
|
2122
|
-
exports.state
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
3123
|
+
const _rawTarget = exports.state[TARGET];
|
|
3124
|
+
try {
|
|
3125
|
+
Object.defineProperty(_rawTarget, "lock", {
|
|
3126
|
+
value: /* @__PURE__ */ __name(() => {
|
|
3127
|
+
exports.internal.locked = true;
|
|
3128
|
+
message_default("State is now locked. All modifications are blocked.");
|
|
3129
|
+
}, "value"),
|
|
3130
|
+
writable: true,
|
|
3131
|
+
configurable: true,
|
|
3132
|
+
enumerable: false
|
|
3133
|
+
});
|
|
3134
|
+
Object.defineProperty(_rawTarget, "unlock", {
|
|
3135
|
+
value: /* @__PURE__ */ __name(() => {
|
|
3136
|
+
exports.internal.locked = false;
|
|
3137
|
+
message_default("State is now unlocked. Modifications are allowed.");
|
|
3138
|
+
}, "value"),
|
|
3139
|
+
writable: true,
|
|
3140
|
+
configurable: true,
|
|
3141
|
+
enumerable: false
|
|
3142
|
+
});
|
|
3143
|
+
} catch (e) {
|
|
3144
|
+
if (exports.DEV) console.warn("[memorio state] lock/unlock defineProperty failed:", e);
|
|
3145
|
+
}
|
|
3146
|
+
try {
|
|
3147
|
+
Object.defineProperty(_rawTarget, "persist", {
|
|
3148
|
+
value: /* @__PURE__ */ __name((path) => {
|
|
3149
|
+
if (typeof path !== "string" || !path.length) {
|
|
3150
|
+
if (exports.DEV) console.warn('[memorio state] state.persist() requires a non-empty path string (e.g. "state.user")');
|
|
3151
|
+
return () => {
|
|
3152
|
+
};
|
|
2149
3153
|
}
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
3154
|
+
const normalized = path.startsWith("state.") ? path : "state." + path;
|
|
3155
|
+
const key = normalized.replace(/^state\./, "");
|
|
3156
|
+
const segments = key.split(".");
|
|
3157
|
+
const initial = exports.store.get(key);
|
|
3158
|
+
if (initial !== void 0 && initial !== null) {
|
|
3159
|
+
let acc = exports.state;
|
|
3160
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
3161
|
+
const seg = segments[i];
|
|
3162
|
+
if (acc[seg] === void 0 || acc[seg] === null) acc[seg] = {};
|
|
3163
|
+
acc = acc[seg];
|
|
3164
|
+
}
|
|
3165
|
+
if (acc) acc[segments[segments.length - 1]] = deepRaw(initial);
|
|
3166
|
+
}
|
|
3167
|
+
const handler = /* @__PURE__ */ __name(() => {
|
|
3168
|
+
let current = exports.state;
|
|
3169
|
+
for (const seg of segments) {
|
|
3170
|
+
current = current === void 0 || current === null ? void 0 : current[seg];
|
|
3171
|
+
}
|
|
3172
|
+
exports.store.set(key, deepRaw(current));
|
|
3173
|
+
}, "handler");
|
|
3174
|
+
const off = dispatch.listen(normalized, handler);
|
|
3175
|
+
return typeof off === "function" ? off : () => {
|
|
3176
|
+
};
|
|
3177
|
+
}, "value"),
|
|
3178
|
+
writable: true,
|
|
3179
|
+
configurable: true,
|
|
3180
|
+
enumerable: false
|
|
3181
|
+
});
|
|
3182
|
+
} catch (e) {
|
|
3183
|
+
if (exports.DEV) console.warn("[memorio state] persist defineProperty failed:", e);
|
|
3184
|
+
}
|
|
2163
3185
|
globalThis[STATE_INSTANCE_KEY] = exports.state;
|
|
2164
3186
|
}
|
|
2165
3187
|
|
|
@@ -2171,6 +3193,7 @@ init_cjs_shims();
|
|
|
2171
3193
|
init_platform();
|
|
2172
3194
|
init_internal();
|
|
2173
3195
|
init_message();
|
|
3196
|
+
init_encryption();
|
|
2174
3197
|
var _sessionStorage = getSessionStorage();
|
|
2175
3198
|
var _fallbackStorageByContext2 = /* @__PURE__ */ new Map();
|
|
2176
3199
|
function _getFallbackStorage2() {
|
|
@@ -2183,6 +3206,14 @@ function _getFallbackStorage2() {
|
|
|
2183
3206
|
}
|
|
2184
3207
|
__name(_getFallbackStorage2, "_getFallbackStorage");
|
|
2185
3208
|
var _hasStorage2 = _sessionStorage !== null;
|
|
3209
|
+
var _encryptionKey2 = null;
|
|
3210
|
+
var _onError2 = null;
|
|
3211
|
+
var _maxObjectSize2 = 0;
|
|
3212
|
+
var _maxTotalSize2 = 0;
|
|
3213
|
+
function _isEncryptedEnvelope2(value) {
|
|
3214
|
+
return exports.encryption.isEncrypted(value);
|
|
3215
|
+
}
|
|
3216
|
+
__name(_isEncryptedEnvelope2, "_isEncryptedEnvelope");
|
|
2186
3217
|
function _getPrefix2() {
|
|
2187
3218
|
const contextName = exports.internal.currentContext || "";
|
|
2188
3219
|
return contextName ? `${contextName}-` : `memorio_session_`;
|
|
@@ -2236,16 +3267,22 @@ if (globalThis[SESSION_INSTANCE_KEY]) {
|
|
|
2236
3267
|
/**
|
|
2237
3268
|
* Gets a value from storage.
|
|
2238
3269
|
* @param name The key to retrieve.
|
|
2239
|
-
* @
|
|
3270
|
+
* @param opts Optional { decrypt: key } to decrypt an encrypted envelope.
|
|
3271
|
+
* @returns The parsed value, a Promise when decrypting, or null if not found.
|
|
2240
3272
|
*/
|
|
2241
3273
|
get: {
|
|
2242
|
-
value: /* @__PURE__ */ __name((name) => {
|
|
3274
|
+
value: /* @__PURE__ */ __name((name, opts) => {
|
|
2243
3275
|
if (!name) {
|
|
2244
3276
|
console.warn("[memorio session] session.get() called with empty or null key - returning null");
|
|
2245
3277
|
return null;
|
|
2246
3278
|
}
|
|
2247
3279
|
try {
|
|
2248
|
-
|
|
3280
|
+
const raw = _read2(_prefixKey2(name));
|
|
3281
|
+
const key = opts?.decrypt ?? _encryptionKey2;
|
|
3282
|
+
if (key && _isEncryptedEnvelope2(raw)) {
|
|
3283
|
+
return exports.encryption.decrypt(raw, key);
|
|
3284
|
+
}
|
|
3285
|
+
return raw;
|
|
2249
3286
|
} catch (err) {
|
|
2250
3287
|
exports.message(`Error parsing session item '${name}':${err}`);
|
|
2251
3288
|
}
|
|
@@ -2256,10 +3293,11 @@ if (globalThis[SESSION_INSTANCE_KEY]) {
|
|
|
2256
3293
|
* Sets a value in storage.
|
|
2257
3294
|
* @param name The key to set.
|
|
2258
3295
|
* @param value The value to store.
|
|
2259
|
-
* @
|
|
3296
|
+
* @param opts Optional { encrypt: key } to encrypt before storage.
|
|
3297
|
+
* @returns true if written, false if rejected. Returns a Promise when encrypting.
|
|
2260
3298
|
*/
|
|
2261
3299
|
set: {
|
|
2262
|
-
value: /* @__PURE__ */ __name((name, value) => {
|
|
3300
|
+
value: /* @__PURE__ */ __name((name, value, opts) => {
|
|
2263
3301
|
if (!name) {
|
|
2264
3302
|
console.warn("[memorio session] session.set() called with empty or null key - write aborted");
|
|
2265
3303
|
return false;
|
|
@@ -2271,15 +3309,63 @@ if (globalThis[SESSION_INSTANCE_KEY]) {
|
|
|
2271
3309
|
exports.message("It's not secure to session functions.");
|
|
2272
3310
|
return false;
|
|
2273
3311
|
}
|
|
3312
|
+
if (_maxObjectSize2 > 0 || _maxTotalSize2 > 0) {
|
|
3313
|
+
let serializedSize = 0;
|
|
3314
|
+
try {
|
|
3315
|
+
serializedSize = new TextEncoder().encode(JSON.stringify(value)).length;
|
|
3316
|
+
} catch {
|
|
3317
|
+
serializedSize = 0;
|
|
3318
|
+
}
|
|
3319
|
+
if (_maxObjectSize2 > 0 && serializedSize > _maxObjectSize2) {
|
|
3320
|
+
const err = new Error(`Object size (${serializedSize} bytes) exceeds maxObjectSize (${_maxObjectSize2} bytes)`);
|
|
3321
|
+
_onError2?.(err, { operation: "set" });
|
|
3322
|
+
return false;
|
|
3323
|
+
}
|
|
3324
|
+
if (_maxTotalSize2 > 0) {
|
|
3325
|
+
const currentTotal = exports.session.size() * 1024;
|
|
3326
|
+
const existingItemSize = _sessionStorage ? _sessionStorage.getItem(prefixedName)?.length ?? 0 : _getFallbackStorage2().get(prefixedName)?.length ?? 0;
|
|
3327
|
+
const projected = currentTotal - existingItemSize + serializedSize;
|
|
3328
|
+
if (projected > _maxTotalSize2) {
|
|
3329
|
+
const err = new Error(`Total session size (${projected} bytes) exceeds maxTotalSize (${_maxTotalSize2} bytes)`);
|
|
3330
|
+
_onError2?.(err, { operation: "set" });
|
|
3331
|
+
return false;
|
|
3332
|
+
}
|
|
3333
|
+
}
|
|
3334
|
+
}
|
|
3335
|
+
const key = opts?.encrypt ?? _encryptionKey2;
|
|
3336
|
+
if (key) {
|
|
3337
|
+
return exports.encryption.encrypt(value, key).then((env) => {
|
|
3338
|
+
_write2(prefixedName, env);
|
|
3339
|
+
return true;
|
|
3340
|
+
}).catch((err) => {
|
|
3341
|
+
exports.message(`Error encrypting session item '${name}': ${err}`);
|
|
3342
|
+
_onError2?.(err, { operation: "set" });
|
|
3343
|
+
return false;
|
|
3344
|
+
});
|
|
3345
|
+
}
|
|
2274
3346
|
try {
|
|
2275
3347
|
_write2(prefixedName, value);
|
|
2276
3348
|
} catch (err) {
|
|
2277
3349
|
exports.message(`Error setting session item '${name}': ${err}`);
|
|
3350
|
+
_onError2?.(err, { operation: "set" });
|
|
2278
3351
|
return false;
|
|
2279
3352
|
}
|
|
2280
3353
|
return true;
|
|
2281
3354
|
}, "value")
|
|
2282
3355
|
},
|
|
3356
|
+
/**
|
|
3357
|
+
* Configure session-wide behavior.
|
|
3358
|
+
* @param opts { encryptionKey, onError, maxObjectSize, maxTotalSize }
|
|
3359
|
+
*/
|
|
3360
|
+
config: {
|
|
3361
|
+
value: /* @__PURE__ */ __name((opts) => {
|
|
3362
|
+
if (opts.encryptionKey !== void 0) _encryptionKey2 = opts.encryptionKey;
|
|
3363
|
+
if (opts.onError !== void 0) _onError2 = opts.onError;
|
|
3364
|
+
if (opts.maxObjectSize !== void 0) _maxObjectSize2 = opts.maxObjectSize;
|
|
3365
|
+
if (opts.maxTotalSize !== void 0) _maxTotalSize2 = opts.maxTotalSize;
|
|
3366
|
+
return exports.session;
|
|
3367
|
+
}, "value")
|
|
3368
|
+
},
|
|
2283
3369
|
/**
|
|
2284
3370
|
* Removes a value from storage.
|
|
2285
3371
|
* @param name The key to remove.
|
|
@@ -2511,12 +3597,17 @@ var observerFunction = /* @__PURE__ */ __name((s, cb = null, option = true) => {
|
|
|
2511
3597
|
const callbacks = Array.isArray(cb) ? cb : [cb];
|
|
2512
3598
|
const obs = globalThis.observer;
|
|
2513
3599
|
if (obs?.list?.[resolvedPath]) dispatch.remove(resolvedPath);
|
|
3600
|
+
const unsubs = [];
|
|
2514
3601
|
callbacks.forEach((callback) => {
|
|
2515
3602
|
if (typeof callback === "function") {
|
|
2516
|
-
dispatch.listen(resolvedPath, callback, option);
|
|
3603
|
+
const off = dispatch.listen(resolvedPath, callback, option);
|
|
3604
|
+
if (typeof off === "function") unsubs.push(off);
|
|
2517
3605
|
}
|
|
2518
3606
|
});
|
|
2519
|
-
return;
|
|
3607
|
+
if (unsubs.length === 1) return unsubs[0];
|
|
3608
|
+
if (unsubs.length > 1) return () => unsubs.forEach((u) => u());
|
|
3609
|
+
return () => {
|
|
3610
|
+
};
|
|
2520
3611
|
}
|
|
2521
3612
|
}, "observerFunction");
|
|
2522
3613
|
var observer = observerFunction;
|
|
@@ -2579,7 +3670,6 @@ Object.defineProperties(
|
|
|
2579
3670
|
init_cjs_shims();
|
|
2580
3671
|
init_message();
|
|
2581
3672
|
init_internal();
|
|
2582
|
-
init_env();
|
|
2583
3673
|
var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
2584
3674
|
if (!deps || typeof func !== "function") {
|
|
2585
3675
|
return () => {
|
|
@@ -2623,37 +3713,616 @@ var useObserver = /* @__PURE__ */ __name(((func, deps = []) => {
|
|
|
2623
3713
|
});
|
|
2624
3714
|
}
|
|
2625
3715
|
});
|
|
2626
|
-
if (handlers.length > 0) {
|
|
2627
|
-
message_default(`useObserver: Monitoring ${handlers.length} paths.`);
|
|
2628
|
-
} else {
|
|
2629
|
-
console.warn(`useObserver: No paths resolved for monitoring. Check your dependencies!`);
|
|
3716
|
+
if (handlers.length > 0) {
|
|
3717
|
+
message_default(`useObserver: Monitoring ${handlers.length} paths.`);
|
|
3718
|
+
} else {
|
|
3719
|
+
console.warn(`useObserver: No paths resolved for monitoring. Check your dependencies!`);
|
|
3720
|
+
}
|
|
3721
|
+
return () => {
|
|
3722
|
+
unsubs.forEach(({ path, off }) => {
|
|
3723
|
+
off();
|
|
3724
|
+
message_default(`useObserver: Stopped monitoring "${path}"`);
|
|
3725
|
+
});
|
|
3726
|
+
};
|
|
3727
|
+
} catch (err) {
|
|
3728
|
+
message_default(`useObserver Error: ${err}`);
|
|
3729
|
+
return () => {
|
|
3730
|
+
};
|
|
3731
|
+
}
|
|
3732
|
+
}), "useObserver");
|
|
3733
|
+
|
|
3734
|
+
// index.ts
|
|
3735
|
+
init_encryption();
|
|
3736
|
+
|
|
3737
|
+
// functions/computed/index.ts
|
|
3738
|
+
init_cjs_shims();
|
|
3739
|
+
init_env();
|
|
3740
|
+
init_message();
|
|
3741
|
+
var DEFAULT_EQUALITY = /* @__PURE__ */ __name((prev, next) => {
|
|
3742
|
+
if (prev === next) return true;
|
|
3743
|
+
if (prev == null || next == null) return false;
|
|
3744
|
+
if (typeof prev !== typeof next) return false;
|
|
3745
|
+
if (typeof prev !== "object") return false;
|
|
3746
|
+
try {
|
|
3747
|
+
return JSON.stringify(prev) === JSON.stringify(next);
|
|
3748
|
+
} catch {
|
|
3749
|
+
return false;
|
|
3750
|
+
}
|
|
3751
|
+
}, "DEFAULT_EQUALITY");
|
|
3752
|
+
var computedMap = /* @__PURE__ */ new Map();
|
|
3753
|
+
function _normalizeKey(key) {
|
|
3754
|
+
if (!key || typeof key !== "string") return "";
|
|
3755
|
+
const normalized = key.startsWith("state.") ? key : `state.${key}`;
|
|
3756
|
+
return normalized;
|
|
3757
|
+
}
|
|
3758
|
+
__name(_normalizeKey, "_normalizeKey");
|
|
3759
|
+
function _invalidate(key) {
|
|
3760
|
+
const entry = computedMap.get(key);
|
|
3761
|
+
if (!entry) return;
|
|
3762
|
+
const newValue = _recompute(entry);
|
|
3763
|
+
if (entry.equality(entry.lastValue, newValue)) {
|
|
3764
|
+
return;
|
|
3765
|
+
}
|
|
3766
|
+
entry.lastValue = newValue;
|
|
3767
|
+
for (const sub of entry.subscribers) {
|
|
3768
|
+
try {
|
|
3769
|
+
sub(newValue);
|
|
3770
|
+
} catch (err) {
|
|
3771
|
+
if (exports.DEV) console.error("[memorio computed] subscriber error:", err);
|
|
3772
|
+
}
|
|
3773
|
+
}
|
|
3774
|
+
dispatch.set("memorio:computed:" + key, { detail: { key, value: newValue } });
|
|
3775
|
+
}
|
|
3776
|
+
__name(_invalidate, "_invalidate");
|
|
3777
|
+
function _readStatePath(path) {
|
|
3778
|
+
const entry = computedMap.get(path);
|
|
3779
|
+
if (entry) {
|
|
3780
|
+
return entry.lastValue;
|
|
3781
|
+
}
|
|
3782
|
+
const normalized = path.startsWith("state.") ? path : `state.${path}`;
|
|
3783
|
+
const segments = normalized.replace(/^state\./, "").split(".");
|
|
3784
|
+
let current = globalThis.state;
|
|
3785
|
+
if (current) {
|
|
3786
|
+
for (const seg of segments) {
|
|
3787
|
+
if (current === null || current === void 0) break;
|
|
3788
|
+
try {
|
|
3789
|
+
current = current[seg];
|
|
3790
|
+
} catch {
|
|
3791
|
+
return void 0;
|
|
3792
|
+
}
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
return current === void 0 ? null : current;
|
|
3796
|
+
}
|
|
3797
|
+
__name(_readStatePath, "_readStatePath");
|
|
3798
|
+
function _recompute(entry) {
|
|
3799
|
+
const newDeps = /* @__PURE__ */ new Set();
|
|
3800
|
+
const trackerGet = /* @__PURE__ */ __name((path) => {
|
|
3801
|
+
if (!path || typeof path !== "string") return void 0;
|
|
3802
|
+
newDeps.add(path);
|
|
3803
|
+
return _readStatePath(path);
|
|
3804
|
+
}, "trackerGet");
|
|
3805
|
+
try {
|
|
3806
|
+
return entry.selector(trackerGet);
|
|
3807
|
+
} catch (err) {
|
|
3808
|
+
if (exports.DEV) console.error("[memorio computed] selector error:", err);
|
|
3809
|
+
message_default(`[memorio computed] selector error: ${err}`);
|
|
3810
|
+
return entry.lastValue;
|
|
3811
|
+
}
|
|
3812
|
+
}
|
|
3813
|
+
__name(_recompute, "_recompute");
|
|
3814
|
+
function _setupDeps(key, entry, deps) {
|
|
3815
|
+
for (const off of entry._dispatchUnsubscribers) off();
|
|
3816
|
+
entry._dispatchUnsubscribers = [];
|
|
3817
|
+
for (const dep of deps) {
|
|
3818
|
+
if (computedMap.has(dep)) {
|
|
3819
|
+
const computedEvent = "memorio:computed:" + dep;
|
|
3820
|
+
const off = dispatch.listen(computedEvent, () => _invalidate(key));
|
|
3821
|
+
if (off) entry._dispatchUnsubscribers.push(off);
|
|
3822
|
+
} else {
|
|
3823
|
+
const off = dispatch.listen(dep, () => _invalidate(key));
|
|
3824
|
+
if (off) entry._dispatchUnsubscribers.push(off);
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
entry.deps = deps;
|
|
3828
|
+
}
|
|
3829
|
+
__name(_setupDeps, "_setupDeps");
|
|
3830
|
+
function _compute(key, selector, opts) {
|
|
3831
|
+
const normalizedKey = _normalizeKey(key);
|
|
3832
|
+
const cacheKey = opts?.equalityKey ? `${opts.equalityKey}:${normalizedKey}` : normalizedKey;
|
|
3833
|
+
if (computedMap.has(cacheKey)) {
|
|
3834
|
+
const entry2 = computedMap.get(cacheKey);
|
|
3835
|
+
entry2.selector = selector;
|
|
3836
|
+
entry2.equality = opts?.equality || DEFAULT_EQUALITY;
|
|
3837
|
+
const newDeps2 = /* @__PURE__ */ new Set();
|
|
3838
|
+
const wrappedGet = /* @__PURE__ */ __name((path) => {
|
|
3839
|
+
newDeps2.add(path);
|
|
3840
|
+
return _readStatePath(path);
|
|
3841
|
+
}, "wrappedGet");
|
|
3842
|
+
let newValue;
|
|
3843
|
+
try {
|
|
3844
|
+
newValue = selector(wrappedGet);
|
|
3845
|
+
} catch (err) {
|
|
3846
|
+
if (exports.DEV) console.error("[memorio computed] selector error:", err);
|
|
3847
|
+
return entry2.lastValue;
|
|
3848
|
+
}
|
|
3849
|
+
if (entry2.equality(entry2.lastValue, newValue)) {
|
|
3850
|
+
return entry2.lastValue;
|
|
3851
|
+
}
|
|
3852
|
+
entry2.lastValue = newValue;
|
|
3853
|
+
_setupDeps(cacheKey, entry2, newDeps2);
|
|
3854
|
+
for (const sub of entry2.subscribers) {
|
|
3855
|
+
try {
|
|
3856
|
+
sub(newValue);
|
|
3857
|
+
} catch (err) {
|
|
3858
|
+
if (exports.DEV) console.error("[memorio computed] subscriber error:", err);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
return newValue;
|
|
3862
|
+
}
|
|
3863
|
+
const newDeps = /* @__PURE__ */ new Set();
|
|
3864
|
+
const get = /* @__PURE__ */ __name((path) => {
|
|
3865
|
+
newDeps.add(path);
|
|
3866
|
+
return _readStatePath(path);
|
|
3867
|
+
}, "get");
|
|
3868
|
+
let lastValue;
|
|
3869
|
+
try {
|
|
3870
|
+
lastValue = selector(get);
|
|
3871
|
+
} catch (err) {
|
|
3872
|
+
if (exports.DEV) console.error("[memorio computed] selector error:", err);
|
|
3873
|
+
message_default(`[memorio computed] selector error: ${err}`);
|
|
3874
|
+
lastValue = null;
|
|
3875
|
+
}
|
|
3876
|
+
const entry = {
|
|
3877
|
+
selector,
|
|
3878
|
+
lastValue,
|
|
3879
|
+
deps: newDeps,
|
|
3880
|
+
equality: opts?.equality || DEFAULT_EQUALITY,
|
|
3881
|
+
subscribers: /* @__PURE__ */ new Set(),
|
|
3882
|
+
_dispatchUnsubscribers: []
|
|
3883
|
+
};
|
|
3884
|
+
computedMap.set(cacheKey, entry);
|
|
3885
|
+
_setupDeps(cacheKey, entry, newDeps);
|
|
3886
|
+
return lastValue;
|
|
3887
|
+
}
|
|
3888
|
+
__name(_compute, "_compute");
|
|
3889
|
+
function _getValue(key) {
|
|
3890
|
+
const normalizedKey = _normalizeKey(key);
|
|
3891
|
+
const entry = computedMap.get(normalizedKey);
|
|
3892
|
+
if (!entry) return null;
|
|
3893
|
+
return entry.lastValue;
|
|
3894
|
+
}
|
|
3895
|
+
__name(_getValue, "_getValue");
|
|
3896
|
+
function _subscribe(key, cb) {
|
|
3897
|
+
const normalizedKey = _normalizeKey(key);
|
|
3898
|
+
const entry = computedMap.get(normalizedKey);
|
|
3899
|
+
if (!entry) {
|
|
3900
|
+
if (exports.DEV) console.warn(`[memorio computed] subscribe: no computed value registered for key '${key}'`);
|
|
3901
|
+
return () => {
|
|
3902
|
+
};
|
|
3903
|
+
}
|
|
3904
|
+
entry.subscribers.add(cb);
|
|
3905
|
+
return () => {
|
|
3906
|
+
entry.subscribers.delete(cb);
|
|
3907
|
+
};
|
|
3908
|
+
}
|
|
3909
|
+
__name(_subscribe, "_subscribe");
|
|
3910
|
+
function _remove3(key) {
|
|
3911
|
+
const normalizedKey = _normalizeKey(key);
|
|
3912
|
+
if (!computedMap.has(normalizedKey)) return false;
|
|
3913
|
+
const entry = computedMap.get(normalizedKey);
|
|
3914
|
+
for (const off of entry._dispatchUnsubscribers) off();
|
|
3915
|
+
computedMap.delete(normalizedKey);
|
|
3916
|
+
return true;
|
|
3917
|
+
}
|
|
3918
|
+
__name(_remove3, "_remove");
|
|
3919
|
+
function _list() {
|
|
3920
|
+
return Array.from(computedMap.keys());
|
|
3921
|
+
}
|
|
3922
|
+
__name(_list, "_list");
|
|
3923
|
+
function _clear() {
|
|
3924
|
+
for (const [, entry] of computedMap) {
|
|
3925
|
+
for (const off of entry._dispatchUnsubscribers) off();
|
|
3926
|
+
}
|
|
3927
|
+
computedMap.clear();
|
|
3928
|
+
}
|
|
3929
|
+
__name(_clear, "_clear");
|
|
3930
|
+
var computed = {
|
|
3931
|
+
compute: _compute,
|
|
3932
|
+
getValue: _getValue,
|
|
3933
|
+
subscribe: _subscribe,
|
|
3934
|
+
remove: _remove3,
|
|
3935
|
+
list: _list,
|
|
3936
|
+
clear: _clear
|
|
3937
|
+
};
|
|
3938
|
+
|
|
3939
|
+
// functions/broadcast/index.ts
|
|
3940
|
+
init_cjs_shims();
|
|
3941
|
+
init_env();
|
|
3942
|
+
init_message();
|
|
3943
|
+
var _channel = null;
|
|
3944
|
+
var _storageListener = null;
|
|
3945
|
+
var _originalDispatchSet = null;
|
|
3946
|
+
var _installed = false;
|
|
3947
|
+
var _targets = "all";
|
|
3948
|
+
var _isLocalChange = false;
|
|
3949
|
+
function _hasBroadcastChannel() {
|
|
3950
|
+
return typeof BroadcastChannel !== "undefined";
|
|
3951
|
+
}
|
|
3952
|
+
__name(_hasBroadcastChannel, "_hasBroadcastChannel");
|
|
3953
|
+
function _hasStorageEvents() {
|
|
3954
|
+
return typeof window !== "undefined" && "addEventListener" in window;
|
|
3955
|
+
}
|
|
3956
|
+
__name(_hasStorageEvents, "_hasStorageEvents");
|
|
3957
|
+
function _shouldSync(target) {
|
|
3958
|
+
if (_targets === "all") return true;
|
|
3959
|
+
return _targets === target;
|
|
3960
|
+
}
|
|
3961
|
+
__name(_shouldSync, "_shouldSync");
|
|
3962
|
+
function _onBroadcastMessage(event) {
|
|
3963
|
+
let msg;
|
|
3964
|
+
try {
|
|
3965
|
+
msg = event.data;
|
|
3966
|
+
} catch {
|
|
3967
|
+
return;
|
|
3968
|
+
}
|
|
3969
|
+
if (!msg || !msg.__memorio_sync) return;
|
|
3970
|
+
if (!_shouldSync(msg.target)) return;
|
|
3971
|
+
if (_isLocalChange) return;
|
|
3972
|
+
try {
|
|
3973
|
+
if (msg.target === "state" || msg.target === "all") {
|
|
3974
|
+
const s = globalThis.state;
|
|
3975
|
+
if (s) {
|
|
3976
|
+
_isLocalChange = true;
|
|
3977
|
+
try {
|
|
3978
|
+
const segments = msg.path.replace(/^state\./, "").split(".");
|
|
3979
|
+
let current = s;
|
|
3980
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
3981
|
+
const seg = segments[i];
|
|
3982
|
+
if (current[seg] === void 0 || current[seg] === null) {
|
|
3983
|
+
current[seg] = {};
|
|
3984
|
+
}
|
|
3985
|
+
current = current[seg];
|
|
3986
|
+
}
|
|
3987
|
+
const lastSeg = segments[segments.length - 1];
|
|
3988
|
+
if (msg.action === "set") {
|
|
3989
|
+
current[lastSeg] = msg.value;
|
|
3990
|
+
} else if (msg.action === "delete") {
|
|
3991
|
+
delete current[lastSeg];
|
|
3992
|
+
}
|
|
3993
|
+
} finally {
|
|
3994
|
+
queueMicrotask(() => {
|
|
3995
|
+
_isLocalChange = false;
|
|
3996
|
+
});
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
} catch (err) {
|
|
4001
|
+
if (exports.DEV) console.error("[memorio broadcast] apply state error:", err);
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
__name(_onBroadcastMessage, "_onBroadcastMessage");
|
|
4005
|
+
function _onStorageEvent(e) {
|
|
4006
|
+
if (!e.key) return;
|
|
4007
|
+
const prefixes = [
|
|
4008
|
+
["memorio_store_", "store"],
|
|
4009
|
+
["memorio_session_", "session"]
|
|
4010
|
+
];
|
|
4011
|
+
for (const [prefix, target] of prefixes) {
|
|
4012
|
+
if (e.key.startsWith(prefix)) {
|
|
4013
|
+
if (!_shouldSync(target)) continue;
|
|
4014
|
+
const cleanKey = e.key.slice(prefix.length);
|
|
4015
|
+
dispatch.set(`memorio:broadcast:${target}:${cleanKey}`, {
|
|
4016
|
+
detail: { key: cleanKey, oldValue: e.oldValue, newValue: e.newValue }
|
|
4017
|
+
});
|
|
4018
|
+
break;
|
|
4019
|
+
}
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
__name(_onStorageEvent, "_onStorageEvent");
|
|
4023
|
+
function _wrapDispatchSet() {
|
|
4024
|
+
if (_originalDispatchSet !== null) return;
|
|
4025
|
+
_originalDispatchSet = dispatch.set;
|
|
4026
|
+
const original = dispatch.set;
|
|
4027
|
+
dispatch.set = (name, value) => {
|
|
4028
|
+
original(name, value);
|
|
4029
|
+
if (name.startsWith("state.") && _shouldSync("state") && _channel) {
|
|
4030
|
+
_isLocalChange = true;
|
|
4031
|
+
try {
|
|
4032
|
+
_channel.postMessage({
|
|
4033
|
+
__memorio_sync: true,
|
|
4034
|
+
target: "state",
|
|
4035
|
+
action: "set",
|
|
4036
|
+
path: name,
|
|
4037
|
+
value: _extractStateValue(name),
|
|
4038
|
+
timestamp: Date.now()
|
|
4039
|
+
});
|
|
4040
|
+
} finally {
|
|
4041
|
+
queueMicrotask(() => {
|
|
4042
|
+
_isLocalChange = false;
|
|
4043
|
+
});
|
|
4044
|
+
}
|
|
4045
|
+
}
|
|
4046
|
+
};
|
|
4047
|
+
}
|
|
4048
|
+
__name(_wrapDispatchSet, "_wrapDispatchSet");
|
|
4049
|
+
function _restoreDispatchSet() {
|
|
4050
|
+
if (_originalDispatchSet !== null) {
|
|
4051
|
+
dispatch.set = _originalDispatchSet;
|
|
4052
|
+
_originalDispatchSet = null;
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
__name(_restoreDispatchSet, "_restoreDispatchSet");
|
|
4056
|
+
function _extractStateValue(path) {
|
|
4057
|
+
const s = globalThis.state;
|
|
4058
|
+
if (!s) return void 0;
|
|
4059
|
+
try {
|
|
4060
|
+
const segments = path.replace(/^state\./, "").split(".");
|
|
4061
|
+
let current = s;
|
|
4062
|
+
for (const seg of segments) {
|
|
4063
|
+
if (current === null || current === void 0) break;
|
|
4064
|
+
current = current[seg];
|
|
4065
|
+
}
|
|
4066
|
+
return current === void 0 ? null : current;
|
|
4067
|
+
} catch {
|
|
4068
|
+
return null;
|
|
4069
|
+
}
|
|
4070
|
+
}
|
|
4071
|
+
__name(_extractStateValue, "_extractStateValue");
|
|
4072
|
+
var broadcast = {
|
|
4073
|
+
install: /* @__PURE__ */ __name((channelName, opts) => {
|
|
4074
|
+
if (_installed) return;
|
|
4075
|
+
const name = channelName || opts?.channelName || "memorio_sync";
|
|
4076
|
+
_targets = opts?.targets || "all";
|
|
4077
|
+
if (_hasBroadcastChannel()) {
|
|
4078
|
+
_channel = new BroadcastChannel(name);
|
|
4079
|
+
_channel.addEventListener("message", _onBroadcastMessage);
|
|
4080
|
+
_installed = true;
|
|
4081
|
+
_wrapDispatchSet();
|
|
4082
|
+
if (exports.DEV) message_default(`memorio broadcast: installed (channel="${name}", targets="${_targets}")`);
|
|
4083
|
+
}
|
|
4084
|
+
if (_hasStorageEvents()) {
|
|
4085
|
+
_storageListener = _onStorageEvent;
|
|
4086
|
+
window.addEventListener("storage", _storageListener);
|
|
4087
|
+
_installed = true;
|
|
4088
|
+
if (!_hasBroadcastChannel() && exports.DEV) {
|
|
4089
|
+
message_default(`memorio broadcast: using storage event fallback (targets="${_targets}")`);
|
|
4090
|
+
}
|
|
4091
|
+
}
|
|
4092
|
+
if (!_installed) {
|
|
4093
|
+
console.warn("[memorio broadcast] Neither BroadcastChannel nor storage events are available in this environment.");
|
|
4094
|
+
}
|
|
4095
|
+
}, "install"),
|
|
4096
|
+
uninstall: /* @__PURE__ */ __name(() => {
|
|
4097
|
+
if (_channel) {
|
|
4098
|
+
_channel.removeEventListener("message", _onBroadcastMessage);
|
|
4099
|
+
_channel.close();
|
|
4100
|
+
_channel = null;
|
|
4101
|
+
}
|
|
4102
|
+
if (_storageListener && typeof window !== "undefined") {
|
|
4103
|
+
window.removeEventListener("storage", _storageListener);
|
|
4104
|
+
_storageListener = null;
|
|
4105
|
+
}
|
|
4106
|
+
_restoreDispatchSet();
|
|
4107
|
+
_installed = false;
|
|
4108
|
+
}, "uninstall"),
|
|
4109
|
+
isInstalled: /* @__PURE__ */ __name(() => _installed, "isInstalled"),
|
|
4110
|
+
broadcast: /* @__PURE__ */ __name((msg) => {
|
|
4111
|
+
if (!_channel) return;
|
|
4112
|
+
_channel.postMessage({ ...msg, timestamp: Date.now() });
|
|
4113
|
+
}, "broadcast")
|
|
4114
|
+
};
|
|
4115
|
+
|
|
4116
|
+
// functions/security/index.ts
|
|
4117
|
+
init_cjs_shims();
|
|
4118
|
+
init_env();
|
|
4119
|
+
function _safeRandomUUID() {
|
|
4120
|
+
const g3 = globalThis;
|
|
4121
|
+
if (typeof g3.crypto !== "undefined" && typeof g3.crypto.randomUUID === "function") {
|
|
4122
|
+
try {
|
|
4123
|
+
return g3.crypto.randomUUID();
|
|
4124
|
+
} catch {
|
|
4125
|
+
}
|
|
4126
|
+
}
|
|
4127
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
4128
|
+
}
|
|
4129
|
+
__name(_safeRandomUUID, "_safeRandomUUID");
|
|
4130
|
+
var REGEX_TIMEOUT_MS = 100;
|
|
4131
|
+
function _safeRegexTest(pattern, key) {
|
|
4132
|
+
if (/\(.*[+*?].*.*\)[+*?]/.test(pattern)) {
|
|
4133
|
+
if (exports.DEV) console.warn(`[memorio security] Potentially dangerous regex blocked: ${pattern}`);
|
|
4134
|
+
return false;
|
|
4135
|
+
}
|
|
4136
|
+
if (pattern.length > 500) {
|
|
4137
|
+
if (exports.DEV) console.warn("[memorio security] Regex pattern exceeds max length (500)");
|
|
4138
|
+
return false;
|
|
4139
|
+
}
|
|
4140
|
+
const startTime = Date.now();
|
|
4141
|
+
try {
|
|
4142
|
+
const regex = new RegExp(pattern);
|
|
4143
|
+
const result = regex.test(key);
|
|
4144
|
+
const elapsed = Date.now() - startTime;
|
|
4145
|
+
if (elapsed > REGEX_TIMEOUT_MS) {
|
|
4146
|
+
if (exports.DEV) console.warn(`[memorio security] Slow regex detected (${elapsed}ms): ${pattern}`);
|
|
4147
|
+
}
|
|
4148
|
+
return result;
|
|
4149
|
+
} catch {
|
|
4150
|
+
return false;
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4153
|
+
__name(_safeRegexTest, "_safeRegexTest");
|
|
4154
|
+
function addAccessRule(rules, pattern, perms) {
|
|
4155
|
+
const key = pattern instanceof RegExp ? pattern.source : pattern;
|
|
4156
|
+
rules.set(key, perms);
|
|
4157
|
+
return rules;
|
|
4158
|
+
}
|
|
4159
|
+
__name(addAccessRule, "addAccessRule");
|
|
4160
|
+
function hasPermission(rules, key, action, userId) {
|
|
4161
|
+
if (rules.size === 0) return true;
|
|
4162
|
+
for (const [pattern, perms] of rules) {
|
|
4163
|
+
let matches;
|
|
4164
|
+
if (typeof pattern === "function") {
|
|
4165
|
+
try {
|
|
4166
|
+
matches = pattern(key, userId);
|
|
4167
|
+
} catch {
|
|
4168
|
+
matches = false;
|
|
4169
|
+
}
|
|
4170
|
+
} else {
|
|
4171
|
+
matches = _safeRegexTest(pattern, key);
|
|
4172
|
+
}
|
|
4173
|
+
if (matches) {
|
|
4174
|
+
const allowed = perms.includes(action) || perms.includes("admin");
|
|
4175
|
+
if (!allowed) {
|
|
4176
|
+
logAudit({
|
|
4177
|
+
action,
|
|
4178
|
+
key,
|
|
4179
|
+
userId,
|
|
4180
|
+
success: false,
|
|
4181
|
+
error: "RBAC Denied: insufficient permissions"
|
|
4182
|
+
});
|
|
4183
|
+
}
|
|
4184
|
+
return allowed;
|
|
4185
|
+
}
|
|
4186
|
+
}
|
|
4187
|
+
logAudit({
|
|
4188
|
+
action: "permission_check",
|
|
4189
|
+
key,
|
|
4190
|
+
userId,
|
|
4191
|
+
success: false,
|
|
4192
|
+
error: "RBAC Denied: no matching rule"
|
|
4193
|
+
});
|
|
4194
|
+
return false;
|
|
4195
|
+
}
|
|
4196
|
+
__name(hasPermission, "hasPermission");
|
|
4197
|
+
var _auditLogger = null;
|
|
4198
|
+
function isAuditActive() {
|
|
4199
|
+
return _auditLogger !== null;
|
|
4200
|
+
}
|
|
4201
|
+
__name(isAuditActive, "isAuditActive");
|
|
4202
|
+
function setAuditLogger(logger3) {
|
|
4203
|
+
_auditLogger = logger3;
|
|
4204
|
+
}
|
|
4205
|
+
__name(setAuditLogger, "setAuditLogger");
|
|
4206
|
+
function logAudit(entry) {
|
|
4207
|
+
if (!_auditLogger) return;
|
|
4208
|
+
_auditLogger({
|
|
4209
|
+
timestamp: Date.now(),
|
|
4210
|
+
success: true,
|
|
4211
|
+
...entry
|
|
4212
|
+
});
|
|
4213
|
+
}
|
|
4214
|
+
__name(logAudit, "logAudit");
|
|
4215
|
+
function sanitizeValue(value) {
|
|
4216
|
+
if (typeof value === "string") {
|
|
4217
|
+
let decoded = value.replace(/&#[xX]?[0-9a-fA-F]+;?/g, (match) => {
|
|
4218
|
+
const hexMatch = match.match(/&#x([0-9a-fA-F]+);?/i);
|
|
4219
|
+
if (hexMatch && hexMatch[1]) {
|
|
4220
|
+
return String.fromCharCode(parseInt(hexMatch[1], 16));
|
|
4221
|
+
}
|
|
4222
|
+
const decMatch = match.match(/&#([0-9]+);?/);
|
|
4223
|
+
if (decMatch && decMatch[1]) {
|
|
4224
|
+
return String.fromCharCode(parseInt(decMatch[1], 10));
|
|
4225
|
+
}
|
|
4226
|
+
return match;
|
|
4227
|
+
});
|
|
4228
|
+
try {
|
|
4229
|
+
decoded = decodeURIComponent(decoded);
|
|
4230
|
+
} catch {
|
|
2630
4231
|
}
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
4232
|
+
decoded = decoded.replace(/(javascript|vbscript|data:text\/html|about:blank|chrome:)/gi, "[SEC-REMOVED]");
|
|
4233
|
+
return decoded.replace(/<script\b[^>]*>[\s\S]*?<\s*\/\s*script\b[^>]*>/gi, "[SEC-REMOVED]").replace(/on\w+\s*=/gi, "[SEC-REMOVED]=").replace(/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, "[SEC-REMOVED]").replace(/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi, "[SEC-REMOVED]").replace(/<embed\b[^>]*>/gi, "[SEC-REMOVED]").replace(/<svg\b[^<]*(?:(?!<\/svg>)<[^<]*)*<\/svg>/gi, "[SEC-REMOVED]").replace(/<form\b[^<]*(?:(?!<\/form>)<[^<]*)*<\/form>/gi, "[SEC-REMOVED]").replace(/<base\b[^<]*(?:(?!<\/base>)<[^<]*)*<\/base>/gi, "[SEC-REMOVED]").replace(/<link\b[^<]*(?:(?!<\/link>)<[^<]*)*<\/link>/gi, "[SEC-REMOVED]").replace(/<meta\b[^<]*(?:(?!<\/meta>)<[^<]*)*<\/meta>/gi, "[SEC-REMOVED]").replace(/<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, "[SEC-REMOVED]");
|
|
4234
|
+
}
|
|
4235
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
4236
|
+
const ctor = value.constructor?.name;
|
|
4237
|
+
if (ctor === "Object" || ctor === void 0) {
|
|
4238
|
+
const sanitized = {};
|
|
4239
|
+
for (const [k, v] of Object.entries(value)) {
|
|
4240
|
+
if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
|
|
4241
|
+
sanitized[k] = sanitizeValue(v);
|
|
4242
|
+
}
|
|
4243
|
+
return sanitized;
|
|
4244
|
+
}
|
|
4245
|
+
return value;
|
|
2641
4246
|
}
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
4247
|
+
if (Array.isArray(value)) {
|
|
4248
|
+
return value.map((v) => sanitizeValue(v));
|
|
4249
|
+
}
|
|
4250
|
+
return value;
|
|
4251
|
+
}
|
|
4252
|
+
__name(sanitizeValue, "sanitizeValue");
|
|
4253
|
+
function validateKey(key) {
|
|
4254
|
+
return /^[a-zA-Z0-9_.-]+$/.test(key) && key.length <= 256 && key.length > 0;
|
|
4255
|
+
}
|
|
4256
|
+
__name(validateKey, "validateKey");
|
|
4257
|
+
function recordConsent(consents, userId, purpose, granted) {
|
|
4258
|
+
const record = {
|
|
4259
|
+
id: _safeRandomUUID(),
|
|
4260
|
+
purpose,
|
|
4261
|
+
granted,
|
|
4262
|
+
timestamp: Date.now()
|
|
4263
|
+
};
|
|
4264
|
+
const user = consents.get(userId) || [];
|
|
4265
|
+
user.push(record);
|
|
4266
|
+
consents.set(userId, user);
|
|
4267
|
+
return record;
|
|
4268
|
+
}
|
|
4269
|
+
__name(recordConsent, "recordConsent");
|
|
4270
|
+
function hasConsent(consents, userId, purpose) {
|
|
4271
|
+
const userConsents = consents.get(userId);
|
|
4272
|
+
if (!userConsents) return false;
|
|
4273
|
+
for (let i = userConsents.length - 1; i >= 0; i--) {
|
|
4274
|
+
const record = userConsents[i];
|
|
4275
|
+
if (record && record.purpose === purpose) {
|
|
4276
|
+
return record.granted;
|
|
2653
4277
|
}
|
|
2654
|
-
|
|
2655
|
-
|
|
4278
|
+
}
|
|
4279
|
+
return false;
|
|
4280
|
+
}
|
|
4281
|
+
__name(hasConsent, "hasConsent");
|
|
4282
|
+
function revokeConsent(consents, userId, purpose) {
|
|
4283
|
+
return recordConsent(consents, userId, purpose, false);
|
|
4284
|
+
}
|
|
4285
|
+
__name(revokeConsent, "revokeConsent");
|
|
4286
|
+
function getConsents(consents, userId) {
|
|
4287
|
+
return consents.get(userId) || [];
|
|
4288
|
+
}
|
|
4289
|
+
__name(getConsents, "getConsents");
|
|
4290
|
+
function exportUserData(consents, userId) {
|
|
4291
|
+
return {
|
|
4292
|
+
userId,
|
|
4293
|
+
exportedAt: Date.now(),
|
|
4294
|
+
consents: consents.get(userId) || []
|
|
4295
|
+
};
|
|
2656
4296
|
}
|
|
4297
|
+
__name(exportUserData, "exportUserData");
|
|
4298
|
+
function deleteUserData(consents, userId) {
|
|
4299
|
+
const count = consents.get(userId)?.length || 0;
|
|
4300
|
+
consents.delete(userId);
|
|
4301
|
+
return { success: true, deletedConsents: count };
|
|
4302
|
+
}
|
|
4303
|
+
__name(deleteUserData, "deleteUserData");
|
|
4304
|
+
var security = {
|
|
4305
|
+
// Re-exports for convenience
|
|
4306
|
+
safeRandomUUID: _safeRandomUUID,
|
|
4307
|
+
safeRegexTest: _safeRegexTest,
|
|
4308
|
+
// RBAC
|
|
4309
|
+
addAccessRule,
|
|
4310
|
+
hasPermission,
|
|
4311
|
+
// Audit logging
|
|
4312
|
+
isAuditActive,
|
|
4313
|
+
setAuditLogger,
|
|
4314
|
+
logAudit,
|
|
4315
|
+
// Input sanitization
|
|
4316
|
+
sanitizeValue,
|
|
4317
|
+
validateKey,
|
|
4318
|
+
// Consent management
|
|
4319
|
+
recordConsent,
|
|
4320
|
+
hasConsent,
|
|
4321
|
+
revokeConsent,
|
|
4322
|
+
getConsents,
|
|
4323
|
+
exportUserData,
|
|
4324
|
+
deleteUserData
|
|
4325
|
+
};
|
|
2657
4326
|
|
|
2658
4327
|
// index.ts
|
|
2659
4328
|
init_message();
|
|
@@ -2711,439 +4380,67 @@ var log = /* @__PURE__ */ __name((module, action, path, value, previousValue) =>
|
|
|
2711
4380
|
);
|
|
2712
4381
|
if (value !== void 0) {
|
|
2713
4382
|
message_default(` \u2192 value:${value}`);
|
|
2714
|
-
}
|
|
2715
|
-
if (previousValue !== void 0) {
|
|
2716
|
-
message_default(` \u2190 previous:${previousValue}`);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
if (config.customHandler) {
|
|
2720
|
-
config.customHandler(entry);
|
|
2721
|
-
}
|
|
2722
|
-
}, "log");
|
|
2723
|
-
var getModuleColor = /* @__PURE__ */ __name((module) => {
|
|
2724
|
-
const colors = {
|
|
2725
|
-
state: "#4CAF50",
|
|
2726
|
-
store: "#2196F3",
|
|
2727
|
-
session: "#FF9800",
|
|
2728
|
-
cache: "#9C27B0",
|
|
2729
|
-
idb: "#F44336"
|
|
2730
|
-
};
|
|
2731
|
-
return colors[module] || "#888888";
|
|
2732
|
-
}, "getModuleColor");
|
|
2733
|
-
var getHistory = /* @__PURE__ */ __name(() => {
|
|
2734
|
-
return [...logHistory];
|
|
2735
|
-
}, "getHistory");
|
|
2736
|
-
var clearHistory = /* @__PURE__ */ __name(() => {
|
|
2737
|
-
logHistory.length = 0;
|
|
2738
|
-
}, "clearHistory");
|
|
2739
|
-
var getStats = /* @__PURE__ */ __name(() => {
|
|
2740
|
-
const stats2 = {
|
|
2741
|
-
total: logHistory.length,
|
|
2742
|
-
state: 0,
|
|
2743
|
-
store: 0,
|
|
2744
|
-
session: 0,
|
|
2745
|
-
cache: 0,
|
|
2746
|
-
idb: 0,
|
|
2747
|
-
set: 0,
|
|
2748
|
-
get: 0,
|
|
2749
|
-
delete: 0,
|
|
2750
|
-
clear: 0
|
|
2751
|
-
};
|
|
2752
|
-
for (const entry of logHistory) {
|
|
2753
|
-
if (entry) {
|
|
2754
|
-
const module = entry.module;
|
|
2755
|
-
const action = entry.action;
|
|
2756
|
-
if (module && typeof stats2[module] === "number") stats2[module]++;
|
|
2757
|
-
if (action && typeof stats2[action] === "number") stats2[action]++;
|
|
2758
|
-
}
|
|
2759
|
-
}
|
|
2760
|
-
return stats2;
|
|
2761
|
-
}, "getStats");
|
|
2762
|
-
var exportLogs = /* @__PURE__ */ __name(() => {
|
|
2763
|
-
return JSON.stringify(logHistory, null, 2);
|
|
2764
|
-
}, "exportLogs");
|
|
2765
|
-
var logger = {
|
|
2766
|
-
configure,
|
|
2767
|
-
enable,
|
|
2768
|
-
disable,
|
|
2769
|
-
isEnabled,
|
|
2770
|
-
log,
|
|
2771
|
-
getHistory,
|
|
2772
|
-
clearHistory,
|
|
2773
|
-
getStats,
|
|
2774
|
-
exportLogs
|
|
2775
|
-
};
|
|
2776
|
-
|
|
2777
|
-
// functions/devtools/index.ts
|
|
2778
|
-
init_cjs_shims();
|
|
2779
|
-
init_internal();
|
|
2780
|
-
init_env();
|
|
2781
|
-
var _state = globalThis.__memorio_state_instance__;
|
|
2782
|
-
var _store = globalThis.__memorio_store_instance__;
|
|
2783
|
-
var _session = globalThis.__memorio_session_instance__;
|
|
2784
|
-
var _cache = globalThis.__memorio_cache_instance__;
|
|
2785
|
-
function isDebugEnabled2() {
|
|
2786
|
-
return exports.DEV && exports.internal.debug === true;
|
|
2787
|
-
}
|
|
2788
|
-
__name(isDebugEnabled2, "isDebugEnabled");
|
|
2789
|
-
function extractStoreData() {
|
|
2790
|
-
if (!_store) return {};
|
|
2791
|
-
const result = {};
|
|
2792
|
-
const store2 = _store;
|
|
2793
|
-
if (typeof store2.list === "function") {
|
|
2794
|
-
try {
|
|
2795
|
-
return store2.list();
|
|
2796
|
-
} catch {
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
if (typeof store2.get === "function") {
|
|
2800
|
-
for (const key of Object.keys(store2)) {
|
|
2801
|
-
if (!["get", "set", "remove", "delete", "removeAll", "clearAll", "size", "isPersistent", "list"].includes(key)) {
|
|
2802
|
-
try {
|
|
2803
|
-
const val = store2.get(key);
|
|
2804
|
-
if (val !== null && val !== void 0) {
|
|
2805
|
-
result[key] = val;
|
|
2806
|
-
}
|
|
2807
|
-
} catch {
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
}
|
|
2811
|
-
}
|
|
2812
|
-
return result;
|
|
2813
|
-
}
|
|
2814
|
-
__name(extractStoreData, "extractStoreData");
|
|
2815
|
-
function extractSessionData() {
|
|
2816
|
-
if (!_session) return {};
|
|
2817
|
-
const result = {};
|
|
2818
|
-
const session2 = _session;
|
|
2819
|
-
if (typeof session2.list === "function") {
|
|
2820
|
-
try {
|
|
2821
|
-
return session2.list();
|
|
2822
|
-
} catch {
|
|
2823
|
-
}
|
|
2824
|
-
}
|
|
2825
|
-
if (typeof session2.get === "function") {
|
|
2826
|
-
for (const key of Object.keys(session2)) {
|
|
2827
|
-
if (!["get", "set", "remove", "delete", "removeAll", "clearAll", "size", "isPersistent", "list"].includes(key)) {
|
|
2828
|
-
try {
|
|
2829
|
-
const val = session2.get(key);
|
|
2830
|
-
if (val !== null && val !== void 0) {
|
|
2831
|
-
result[key] = val;
|
|
2832
|
-
}
|
|
2833
|
-
} catch {
|
|
2834
|
-
}
|
|
2835
|
-
}
|
|
2836
|
-
}
|
|
2837
|
-
}
|
|
2838
|
-
return result;
|
|
2839
|
-
}
|
|
2840
|
-
__name(extractSessionData, "extractSessionData");
|
|
2841
|
-
var inspect = /* @__PURE__ */ __name(() => {
|
|
2842
|
-
if (!isDebugEnabled2()) return;
|
|
2843
|
-
if (_state) {
|
|
2844
|
-
const stateList = _state.list;
|
|
2845
|
-
let stateData;
|
|
2846
|
-
if (typeof stateList === "function") {
|
|
2847
|
-
stateData = stateList();
|
|
2848
|
-
} else if (typeof stateList === "object" && stateList !== null) {
|
|
2849
|
-
stateData = stateList;
|
|
2850
|
-
} else {
|
|
2851
|
-
stateData = _state;
|
|
2852
|
-
}
|
|
2853
|
-
console.table(stateData);
|
|
2854
|
-
}
|
|
2855
|
-
if (_store) {
|
|
2856
|
-
console.table(extractStoreData());
|
|
2857
|
-
}
|
|
2858
|
-
if (_session) {
|
|
2859
|
-
console.table(extractSessionData());
|
|
2860
|
-
}
|
|
2861
|
-
if (_cache) {
|
|
2862
|
-
const cacheList = _cache.list;
|
|
2863
|
-
let cacheData2;
|
|
2864
|
-
if (typeof cacheList === "function") {
|
|
2865
|
-
cacheData2 = cacheList();
|
|
2866
|
-
} else if (typeof cacheList === "object" && cacheList !== null) {
|
|
2867
|
-
cacheData2 = cacheList;
|
|
2868
|
-
} else {
|
|
2869
|
-
cacheData2 = _cache;
|
|
2870
|
-
}
|
|
2871
|
-
console.table(cacheData2);
|
|
2872
|
-
}
|
|
2873
|
-
}, "inspect");
|
|
2874
|
-
var stats = /* @__PURE__ */ __name(() => {
|
|
2875
|
-
const getKeys = /* @__PURE__ */ __name((obj) => {
|
|
2876
|
-
if (!obj) return 0;
|
|
2877
|
-
if (typeof obj.list === "function") {
|
|
2878
|
-
try {
|
|
2879
|
-
const list = obj.list();
|
|
2880
|
-
return Object.keys(list).length;
|
|
2881
|
-
} catch {
|
|
2882
|
-
}
|
|
2883
|
-
}
|
|
2884
|
-
return Object.keys(obj).length;
|
|
2885
|
-
}, "getKeys");
|
|
2886
|
-
return {
|
|
2887
|
-
stateKeys: getKeys(_state),
|
|
2888
|
-
storeKeys: getKeys(_store),
|
|
2889
|
-
sessionKeys: getKeys(_session),
|
|
2890
|
-
cacheKeys: getKeys(_cache),
|
|
2891
|
-
idbDatabases: 0,
|
|
2892
|
-
sqliteDbCount: 0,
|
|
2893
|
-
lastUpdate: (/* @__PURE__ */ new Date()).toISOString()
|
|
2894
|
-
};
|
|
2895
|
-
}, "stats");
|
|
2896
|
-
var clear = /* @__PURE__ */ __name((moduleName) => {
|
|
2897
|
-
const targets = { state: _state, store: _store, session: _session, cache: _cache };
|
|
2898
|
-
const target = targets[moduleName];
|
|
2899
|
-
if (target && typeof target.clear === "function") {
|
|
2900
|
-
target.clear();
|
|
2901
|
-
} else if (target && typeof target.removeAll === "function") {
|
|
2902
|
-
target.removeAll();
|
|
2903
|
-
} else {
|
|
2904
|
-
console.debug(`Module ${moduleName} not found or does not support clear()/removeAll()`);
|
|
2905
|
-
}
|
|
2906
|
-
}, "clear");
|
|
2907
|
-
var clearAll = /* @__PURE__ */ __name(() => {
|
|
2908
|
-
clear("state");
|
|
2909
|
-
clear("store");
|
|
2910
|
-
clear("session");
|
|
2911
|
-
clear("cache");
|
|
2912
|
-
}, "clearAll");
|
|
2913
|
-
var exportData = /* @__PURE__ */ __name(() => {
|
|
2914
|
-
const getStateData = /* @__PURE__ */ __name(() => {
|
|
2915
|
-
if (!_state) return void 0;
|
|
2916
|
-
try {
|
|
2917
|
-
if (typeof _state.list === "function") {
|
|
2918
|
-
return _state.list();
|
|
2919
|
-
}
|
|
2920
|
-
return _state;
|
|
2921
|
-
} catch {
|
|
2922
|
-
return void 0;
|
|
2923
|
-
}
|
|
2924
|
-
}, "getStateData");
|
|
2925
|
-
const getStoreData = /* @__PURE__ */ __name(() => {
|
|
2926
|
-
return extractStoreData();
|
|
2927
|
-
}, "getStoreData");
|
|
2928
|
-
const getSessionData = /* @__PURE__ */ __name(() => {
|
|
2929
|
-
return extractSessionData();
|
|
2930
|
-
}, "getSessionData");
|
|
2931
|
-
const getCacheData = /* @__PURE__ */ __name(() => {
|
|
2932
|
-
if (!_cache) return void 0;
|
|
2933
|
-
try {
|
|
2934
|
-
if (typeof _cache.list === "function") {
|
|
2935
|
-
return _cache.list();
|
|
2936
|
-
}
|
|
2937
|
-
return _cache;
|
|
2938
|
-
} catch {
|
|
2939
|
-
return void 0;
|
|
2940
|
-
}
|
|
2941
|
-
}, "getCacheData");
|
|
2942
|
-
const data = {
|
|
2943
|
-
state: getStateData(),
|
|
2944
|
-
store: getStoreData(),
|
|
2945
|
-
session: getSessionData(),
|
|
2946
|
-
cache: getCacheData(),
|
|
2947
|
-
exportedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
2948
|
-
};
|
|
2949
|
-
return JSON.stringify(data, null, 2);
|
|
2950
|
-
}, "exportData");
|
|
2951
|
-
var importData = /* @__PURE__ */ __name((jsonString) => {
|
|
2952
|
-
try {
|
|
2953
|
-
const data = JSON.parse(jsonString);
|
|
2954
|
-
if (data.state) {
|
|
2955
|
-
Object.entries(data.state).forEach(([key, value]) => {
|
|
2956
|
-
if (_state && key !== "list" && key !== "remove" && key !== "removeAll") {
|
|
2957
|
-
;
|
|
2958
|
-
_state[key] = value;
|
|
2959
|
-
}
|
|
2960
|
-
});
|
|
2961
|
-
}
|
|
2962
|
-
if (data.store && _store && typeof _store.set === "function") {
|
|
2963
|
-
Object.entries(data.store).forEach(([key, value]) => {
|
|
2964
|
-
;
|
|
2965
|
-
_store.set(key, value);
|
|
2966
|
-
});
|
|
2967
|
-
}
|
|
2968
|
-
if (data.session && _session && typeof _session.set === "function") {
|
|
2969
|
-
Object.entries(data.session).forEach(([key, value]) => {
|
|
2970
|
-
;
|
|
2971
|
-
_session.set(key, value);
|
|
2972
|
-
});
|
|
2973
|
-
}
|
|
2974
|
-
if (data.cache && _cache) {
|
|
2975
|
-
Object.entries(data.cache).forEach(([key, value]) => {
|
|
2976
|
-
if (_cache && key !== "get" && key !== "set" && key !== "remove" && key !== "clear") {
|
|
2977
|
-
;
|
|
2978
|
-
_cache[key] = value;
|
|
2979
|
-
}
|
|
2980
|
-
});
|
|
2981
|
-
}
|
|
2982
|
-
} catch (error) {
|
|
2983
|
-
console.debug("Import failed:", error);
|
|
2984
|
-
}
|
|
2985
|
-
}, "importData");
|
|
2986
|
-
var watch = /* @__PURE__ */ __name((moduleName, path) => {
|
|
2987
|
-
const targets = { state: _state, store: _store, session: _session, cache: _cache };
|
|
2988
|
-
const target = targets[moduleName];
|
|
2989
|
-
if (!target) {
|
|
2990
|
-
console.debug(`Module ${moduleName} not found`);
|
|
2991
|
-
return;
|
|
2992
|
-
}
|
|
2993
|
-
const initialValue = target[path];
|
|
2994
|
-
console.debug(`Watching ${moduleName}.${path} (initial: ${JSON.stringify(initialValue)})`);
|
|
2995
|
-
if (moduleName === "state" && globalThis.memorio?.dispatch) {
|
|
2996
|
-
const handler = /* @__PURE__ */ __name((e) => {
|
|
2997
|
-
const detail = e.detail;
|
|
2998
|
-
if (detail?.name?.includes(path)) {
|
|
2999
|
-
console.debug(`Change: ${moduleName}.${path} =`, e.detail.value);
|
|
3000
|
-
}
|
|
3001
|
-
}, "handler");
|
|
3002
|
-
target.addEventListener?.("memorio-change", handler);
|
|
3003
|
-
}
|
|
3004
|
-
}, "watch");
|
|
3005
|
-
var help = /* @__PURE__ */ __name(() => {
|
|
3006
|
-
console.debug(`
|
|
3007
|
-
Memorio DevTools Help
|
|
3008
|
-
|
|
3009
|
-
Available commands:
|
|
3010
|
-
memorio.devtools.inspect() - Inspect all state modules
|
|
3011
|
-
memorio.devtools.stats() - Show statistics
|
|
3012
|
-
memorio.devtools.clear('module') - Clear specific module
|
|
3013
|
-
memorio.devtools.clearAll() - Clear all modules
|
|
3014
|
-
memorio.devtools.exportData() - Export all data as JSON
|
|
3015
|
-
memorio.devtools.importData(json) - Import data from JSON
|
|
3016
|
-
memorio.devtools.watch(module, path) - Watch a path for changes
|
|
3017
|
-
memorio.devtools.help() - Show this help
|
|
3018
|
-
|
|
3019
|
-
Shortcuts (dev only):
|
|
3020
|
-
state - global state proxy
|
|
3021
|
-
store - localStorage wrapper
|
|
3022
|
-
session - sessionStorage wrapper
|
|
3023
|
-
cache - in-memory cache
|
|
3024
|
-
`);
|
|
3025
|
-
}, "help");
|
|
3026
|
-
var devtools = {
|
|
3027
|
-
inspect,
|
|
3028
|
-
stats,
|
|
3029
|
-
clear,
|
|
3030
|
-
clearAll,
|
|
3031
|
-
exportData,
|
|
3032
|
-
importData,
|
|
3033
|
-
watch,
|
|
3034
|
-
help
|
|
3035
|
-
};
|
|
3036
|
-
|
|
3037
|
-
// core/hlc.ts
|
|
3038
|
-
init_cjs_shims();
|
|
3039
|
-
var NODE_ID_KEY = "__memorio_hlc_node";
|
|
3040
|
-
function getNodeId() {
|
|
3041
|
-
if (typeof globalThis === "undefined") return "node";
|
|
3042
|
-
try {
|
|
3043
|
-
if (typeof sessionStorage !== "undefined" && sessionStorage) {
|
|
3044
|
-
let id = sessionStorage.getItem(NODE_ID_KEY);
|
|
3045
|
-
if (!id) {
|
|
3046
|
-
id = generateNodeId();
|
|
3047
|
-
sessionStorage.setItem(NODE_ID_KEY, id);
|
|
3048
|
-
}
|
|
3049
|
-
return id;
|
|
3050
|
-
}
|
|
3051
|
-
} catch {
|
|
3052
|
-
}
|
|
3053
|
-
if (!globalThis.__memorioHlcNodeId) {
|
|
3054
|
-
globalThis.__memorioHlcNodeId = generateNodeId();
|
|
3055
|
-
}
|
|
3056
|
-
return globalThis.__memorioHlcNodeId;
|
|
3057
|
-
}
|
|
3058
|
-
__name(getNodeId, "getNodeId");
|
|
3059
|
-
function generateNodeId() {
|
|
3060
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
3061
|
-
return crypto.randomUUID().slice(0, 8);
|
|
3062
|
-
}
|
|
3063
|
-
return Math.random().toString(36).slice(2, 10);
|
|
3064
|
-
}
|
|
3065
|
-
__name(generateNodeId, "generateNodeId");
|
|
3066
|
-
var HLC_KEY = "__memorio_hlc_local";
|
|
3067
|
-
var local = globalThis[HLC_KEY] || {
|
|
3068
|
-
physical: 0,
|
|
3069
|
-
logical: 0,
|
|
3070
|
-
node: getNodeId()
|
|
3071
|
-
};
|
|
3072
|
-
if (!globalThis[HLC_KEY]) {
|
|
3073
|
-
globalThis[HLC_KEY] = local;
|
|
3074
|
-
}
|
|
3075
|
-
function tick(_incoming) {
|
|
3076
|
-
const now2 = Date.now();
|
|
3077
|
-
const base = local.physical;
|
|
3078
|
-
let physical;
|
|
3079
|
-
let logical;
|
|
3080
|
-
if (now2 > base) {
|
|
3081
|
-
physical = now2;
|
|
3082
|
-
logical = 0;
|
|
3083
|
-
} else if (now2 < base) {
|
|
3084
|
-
physical = base;
|
|
3085
|
-
logical = local.logical + 1;
|
|
3086
|
-
} else {
|
|
3087
|
-
physical = base;
|
|
3088
|
-
logical = local.logical + 1;
|
|
3089
|
-
}
|
|
3090
|
-
local.physical = physical;
|
|
3091
|
-
local.logical = logical;
|
|
3092
|
-
return { physical, logical, node: local.node };
|
|
3093
|
-
}
|
|
3094
|
-
__name(tick, "tick");
|
|
3095
|
-
function receive(remote) {
|
|
3096
|
-
const now2 = Date.now();
|
|
3097
|
-
if (remote.physical > local.physical) {
|
|
3098
|
-
local.physical = remote.physical > now2 ? remote.physical : now2;
|
|
3099
|
-
local.logical = 1;
|
|
3100
|
-
} else if (remote.physical === local.physical) {
|
|
3101
|
-
local.logical = Math.max(local.logical, remote.logical) + 1;
|
|
3102
|
-
}
|
|
3103
|
-
local.node = getNodeId();
|
|
3104
|
-
return { ...local };
|
|
3105
|
-
}
|
|
3106
|
-
__name(receive, "receive");
|
|
3107
|
-
function compare(a, b) {
|
|
3108
|
-
if (a.physical !== b.physical) {
|
|
3109
|
-
return a.physical < b.physical ? -1 : 1;
|
|
4383
|
+
}
|
|
4384
|
+
if (previousValue !== void 0) {
|
|
4385
|
+
message_default(` \u2190 previous:${previousValue}`);
|
|
4386
|
+
}
|
|
3110
4387
|
}
|
|
3111
|
-
if (
|
|
3112
|
-
|
|
4388
|
+
if (config.customHandler) {
|
|
4389
|
+
config.customHandler(entry);
|
|
3113
4390
|
}
|
|
3114
|
-
|
|
3115
|
-
|
|
4391
|
+
}, "log");
|
|
4392
|
+
var getModuleColor = /* @__PURE__ */ __name((module) => {
|
|
4393
|
+
const colors = {
|
|
4394
|
+
state: "#4CAF50",
|
|
4395
|
+
store: "#2196F3",
|
|
4396
|
+
session: "#FF9800",
|
|
4397
|
+
cache: "#9C27B0",
|
|
4398
|
+
idb: "#F44336"
|
|
4399
|
+
};
|
|
4400
|
+
return colors[module] || "#888888";
|
|
4401
|
+
}, "getModuleColor");
|
|
4402
|
+
var getHistory = /* @__PURE__ */ __name(() => {
|
|
4403
|
+
return [...logHistory];
|
|
4404
|
+
}, "getHistory");
|
|
4405
|
+
var clearHistory = /* @__PURE__ */ __name(() => {
|
|
4406
|
+
logHistory.length = 0;
|
|
4407
|
+
}, "clearHistory");
|
|
4408
|
+
var getStats = /* @__PURE__ */ __name(() => {
|
|
4409
|
+
const stats = {
|
|
4410
|
+
total: logHistory.length,
|
|
4411
|
+
state: 0,
|
|
4412
|
+
store: 0,
|
|
4413
|
+
session: 0,
|
|
4414
|
+
cache: 0,
|
|
4415
|
+
idb: 0,
|
|
4416
|
+
set: 0,
|
|
4417
|
+
get: 0,
|
|
4418
|
+
delete: 0,
|
|
4419
|
+
clear: 0
|
|
4420
|
+
};
|
|
4421
|
+
for (const entry of logHistory) {
|
|
4422
|
+
if (entry) {
|
|
4423
|
+
const module = entry.module;
|
|
4424
|
+
const action = entry.action;
|
|
4425
|
+
if (module && typeof stats[module] === "number") stats[module]++;
|
|
4426
|
+
if (action && typeof stats[action] === "number") stats[action]++;
|
|
4427
|
+
}
|
|
3116
4428
|
}
|
|
3117
|
-
return
|
|
3118
|
-
}
|
|
3119
|
-
__name(
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
const physical = parseInt(parts[1], 10);
|
|
3133
|
-
const logical = parseInt(parts[2], 10);
|
|
3134
|
-
const node = parts[3];
|
|
3135
|
-
if (isNaN(physical) || isNaN(logical)) return null;
|
|
3136
|
-
return { physical, logical, node };
|
|
3137
|
-
}
|
|
3138
|
-
__name(parse, "parse");
|
|
3139
|
-
var hlc = {
|
|
3140
|
-
tick,
|
|
3141
|
-
receive,
|
|
3142
|
-
compare,
|
|
3143
|
-
happenedBefore,
|
|
3144
|
-
serialize,
|
|
3145
|
-
parse,
|
|
3146
|
-
getNodeId
|
|
4429
|
+
return stats;
|
|
4430
|
+
}, "getStats");
|
|
4431
|
+
var exportLogs = /* @__PURE__ */ __name(() => {
|
|
4432
|
+
return JSON.stringify(logHistory, null, 2);
|
|
4433
|
+
}, "exportLogs");
|
|
4434
|
+
var logger = {
|
|
4435
|
+
configure,
|
|
4436
|
+
enable,
|
|
4437
|
+
disable,
|
|
4438
|
+
isEnabled,
|
|
4439
|
+
log,
|
|
4440
|
+
getHistory,
|
|
4441
|
+
clearHistory,
|
|
4442
|
+
getStats,
|
|
4443
|
+
exportLogs
|
|
3147
4444
|
};
|
|
3148
4445
|
|
|
3149
4446
|
// core/fractional.ts
|
|
@@ -3307,214 +4604,53 @@ function reindex(items) {
|
|
|
3307
4604
|
if (prev === null) {
|
|
3308
4605
|
newItem.key = before(items[0].key);
|
|
3309
4606
|
} else if (next === null) {
|
|
3310
|
-
newItem.key = after(prev);
|
|
3311
|
-
} else {
|
|
3312
|
-
newItem.key = between(prev, next);
|
|
3313
|
-
}
|
|
3314
|
-
result.push(newItem);
|
|
3315
|
-
prev = newItem.key;
|
|
3316
|
-
}
|
|
3317
|
-
return result;
|
|
3318
|
-
}
|
|
3319
|
-
__name(reindex, "reindex");
|
|
3320
|
-
var fractional = {
|
|
3321
|
-
generateBetween,
|
|
3322
|
-
firstKey,
|
|
3323
|
-
after,
|
|
3324
|
-
before,
|
|
3325
|
-
between,
|
|
3326
|
-
reorder,
|
|
3327
|
-
reindex
|
|
3328
|
-
};
|
|
3329
|
-
|
|
3330
|
-
// index.ts
|
|
3331
|
-
init_internal();
|
|
3332
|
-
init_platform();
|
|
3333
|
-
|
|
3334
|
-
// core/global.ts
|
|
3335
|
-
init_cjs_shims();
|
|
3336
|
-
init_platform();
|
|
3337
|
-
init_internal();
|
|
3338
|
-
|
|
3339
|
-
// package.json
|
|
3340
|
-
var package_default = {
|
|
3341
|
-
version: "4.9.35"};
|
|
3342
|
-
|
|
3343
|
-
// core/global.ts
|
|
3344
|
-
init_env();
|
|
3345
|
-
init_store();
|
|
3346
|
-
init_idb();
|
|
3347
|
-
init_sqlite();
|
|
3348
|
-
init_message();
|
|
3349
|
-
|
|
3350
|
-
// functions/typed/index.ts
|
|
3351
|
-
init_cjs_shims();
|
|
3352
|
-
function typed() {
|
|
3353
|
-
return exports.state;
|
|
3354
|
-
}
|
|
3355
|
-
__name(typed, "typed");
|
|
3356
|
-
|
|
3357
|
-
// functions/history/index.ts
|
|
3358
|
-
init_cjs_shims();
|
|
3359
|
-
init_internal();
|
|
3360
|
-
init_env();
|
|
3361
|
-
init_message();
|
|
3362
|
-
function _clone(value) {
|
|
3363
|
-
if (value === null || typeof value !== "object") return value;
|
|
3364
|
-
try {
|
|
3365
|
-
return deepRaw(value, /* @__PURE__ */ new WeakSet());
|
|
3366
|
-
} catch (err) {
|
|
3367
|
-
if (exports.DEV) console.warn("[memorio history] deep clone failed:", err);
|
|
3368
|
-
return value;
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
__name(_clone, "_clone");
|
|
3372
|
-
var snapshot = /* @__PURE__ */ __name(() => {
|
|
3373
|
-
return deepRaw(exports.state, /* @__PURE__ */ new WeakSet());
|
|
3374
|
-
}, "snapshot");
|
|
3375
|
-
var diff = /* @__PURE__ */ __name((snap) => {
|
|
3376
|
-
const changes = [];
|
|
3377
|
-
const _walk = /* @__PURE__ */ __name((oldObj, newObj, prefix) => {
|
|
3378
|
-
const oldKeys = oldObj ? Object.keys(oldObj) : [];
|
|
3379
|
-
const newKeys = newObj ? Object.keys(newObj) : [];
|
|
3380
|
-
for (const key of newKeys) {
|
|
3381
|
-
const newPath = prefix ? `${prefix}.${key}` : key;
|
|
3382
|
-
const oldVal = oldObj ? oldObj[key] : void 0;
|
|
3383
|
-
const newVal = newObj[key];
|
|
3384
|
-
if (oldVal !== newVal) {
|
|
3385
|
-
const oldType = typeof oldVal;
|
|
3386
|
-
const newType = typeof newVal;
|
|
3387
|
-
if (oldType !== newType || oldVal === void 0) {
|
|
3388
|
-
changes.push({ path: newPath, oldValue: oldVal, newValue: newVal });
|
|
3389
|
-
} else if (oldVal && typeof oldVal === "object") {
|
|
3390
|
-
_walk(oldVal, newVal, newPath);
|
|
3391
|
-
} else if (oldVal !== newVal) {
|
|
3392
|
-
changes.push({ path: newPath, oldValue: oldVal, newValue: newVal });
|
|
3393
|
-
}
|
|
3394
|
-
}
|
|
3395
|
-
}
|
|
3396
|
-
for (const key of oldKeys) {
|
|
3397
|
-
if (!(key in (newObj || {}))) {
|
|
3398
|
-
const newPath = prefix ? `${prefix}.${key}` : key;
|
|
3399
|
-
changes.push({ path: newPath, oldValue: oldObj[key], newValue: void 0 });
|
|
3400
|
-
}
|
|
3401
|
-
}
|
|
3402
|
-
}, "_walk");
|
|
3403
|
-
_walk(snap, deepRaw(exports.state), "");
|
|
3404
|
-
return changes;
|
|
3405
|
-
}, "diff");
|
|
3406
|
-
var enableHistory = /* @__PURE__ */ __name((enabled = true) => {
|
|
3407
|
-
exports.internal.historyEnabled = enabled;
|
|
3408
|
-
message_default(`[memorio history] Tracking ${enabled ? "enabled" : "disabled"}`);
|
|
3409
|
-
}, "enableHistory");
|
|
3410
|
-
var trace = /* @__PURE__ */ __name(() => {
|
|
3411
|
-
return [...exports.internal.mutations];
|
|
3412
|
-
}, "trace");
|
|
3413
|
-
var canUndo = /* @__PURE__ */ __name(() => {
|
|
3414
|
-
return exports.internal.canUndo();
|
|
3415
|
-
}, "canUndo");
|
|
3416
|
-
var canRedo = /* @__PURE__ */ __name(() => {
|
|
3417
|
-
return exports.internal.canRedo();
|
|
3418
|
-
}, "canRedo");
|
|
3419
|
-
var undo = /* @__PURE__ */ __name(() => {
|
|
3420
|
-
if (!exports.internal.historyEnabled) {
|
|
3421
|
-
message_default("[memorio history] History is not enabled");
|
|
3422
|
-
return void 0;
|
|
3423
|
-
}
|
|
3424
|
-
const record = exports.internal.popUndo();
|
|
3425
|
-
if (!record) return void 0;
|
|
3426
|
-
_applyInverse(record);
|
|
3427
|
-
message_default(`[memorio history] Undid: ${record.action} ${record.path}`);
|
|
3428
|
-
return record;
|
|
3429
|
-
}, "undo");
|
|
3430
|
-
var redo = /* @__PURE__ */ __name(() => {
|
|
3431
|
-
if (!exports.internal.historyEnabled) {
|
|
3432
|
-
message_default("[memorio history] History is not enabled");
|
|
3433
|
-
return void 0;
|
|
3434
|
-
}
|
|
3435
|
-
const record = exports.internal.popRedo();
|
|
3436
|
-
if (!record) return void 0;
|
|
3437
|
-
_applyForward(record);
|
|
3438
|
-
message_default(`[memorio history] Redid: ${record.action} ${record.path}`);
|
|
3439
|
-
return record;
|
|
3440
|
-
}, "redo");
|
|
3441
|
-
function _applyInverse(record) {
|
|
3442
|
-
const wasEnabled = exports.internal.historyEnabled;
|
|
3443
|
-
exports.internal.historyEnabled = false;
|
|
3444
|
-
try {
|
|
3445
|
-
if (record.action === "set") {
|
|
3446
|
-
if (record.previousValue === void 0) {
|
|
3447
|
-
_deletePath(record.path);
|
|
3448
|
-
} else {
|
|
3449
|
-
_setPath(record.path, record.previousValue);
|
|
3450
|
-
}
|
|
3451
|
-
} else if (record.action === "delete") {
|
|
3452
|
-
if (record.previousValue !== void 0) {
|
|
3453
|
-
_setPath(record.path, record.previousValue);
|
|
3454
|
-
}
|
|
3455
|
-
}
|
|
3456
|
-
} finally {
|
|
3457
|
-
exports.internal.historyEnabled = wasEnabled;
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
__name(_applyInverse, "_applyInverse");
|
|
3461
|
-
function _applyForward(record) {
|
|
3462
|
-
const wasEnabled = exports.internal.historyEnabled;
|
|
3463
|
-
exports.internal.historyEnabled = false;
|
|
3464
|
-
try {
|
|
3465
|
-
if (record.action === "set") {
|
|
3466
|
-
_setPath(record.path, record.newValue);
|
|
3467
|
-
} else if (record.action === "delete") {
|
|
3468
|
-
_deletePath(record.path);
|
|
3469
|
-
}
|
|
3470
|
-
} finally {
|
|
3471
|
-
exports.internal.historyEnabled = wasEnabled;
|
|
3472
|
-
}
|
|
3473
|
-
}
|
|
3474
|
-
__name(_applyForward, "_applyForward");
|
|
3475
|
-
function _setPath(path, value) {
|
|
3476
|
-
const parts = path.split(".");
|
|
3477
|
-
let current = exports.state;
|
|
3478
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3479
|
-
const part = parts[i];
|
|
3480
|
-
if (current[part] === void 0) {
|
|
3481
|
-
current[part] = {};
|
|
4607
|
+
newItem.key = after(prev);
|
|
4608
|
+
} else {
|
|
4609
|
+
newItem.key = between(prev, next);
|
|
3482
4610
|
}
|
|
3483
|
-
|
|
4611
|
+
result.push(newItem);
|
|
4612
|
+
prev = newItem.key;
|
|
3484
4613
|
}
|
|
3485
|
-
|
|
4614
|
+
return result;
|
|
3486
4615
|
}
|
|
3487
|
-
__name(
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
4616
|
+
__name(reindex, "reindex");
|
|
4617
|
+
var fractional = {
|
|
4618
|
+
generateBetween,
|
|
4619
|
+
firstKey,
|
|
4620
|
+
after,
|
|
4621
|
+
before,
|
|
4622
|
+
between,
|
|
4623
|
+
reorder,
|
|
4624
|
+
reindex
|
|
4625
|
+
};
|
|
4626
|
+
|
|
4627
|
+
// index.ts
|
|
4628
|
+
init_internal();
|
|
4629
|
+
init_platform();
|
|
4630
|
+
|
|
4631
|
+
// core/global.ts
|
|
4632
|
+
init_cjs_shims();
|
|
4633
|
+
init_platform();
|
|
4634
|
+
init_internal();
|
|
4635
|
+
|
|
4636
|
+
// package.json
|
|
4637
|
+
var package_default = {
|
|
4638
|
+
version: "5.1.0"};
|
|
4639
|
+
|
|
4640
|
+
// core/global.ts
|
|
4641
|
+
init_env();
|
|
4642
|
+
init_store();
|
|
4643
|
+
init_idb();
|
|
4644
|
+
init_sqlite();
|
|
4645
|
+
init_encryption();
|
|
4646
|
+
init_message();
|
|
4647
|
+
|
|
4648
|
+
// functions/typed/index.ts
|
|
4649
|
+
init_cjs_shims();
|
|
4650
|
+
function typed() {
|
|
4651
|
+
return exports.state;
|
|
3501
4652
|
}
|
|
3502
|
-
__name(
|
|
3503
|
-
var rollback = /* @__PURE__ */ __name((snap) => {
|
|
3504
|
-
exports.state.removeAll();
|
|
3505
|
-
for (const key of Object.keys(snap)) {
|
|
3506
|
-
exports.state[key] = _clone(snap[key]);
|
|
3507
|
-
}
|
|
3508
|
-
exports.internal.clearHistory();
|
|
3509
|
-
message_default("[memorio history] State rolled back to snapshot");
|
|
3510
|
-
}, "rollback");
|
|
3511
|
-
var clearHistory2 = /* @__PURE__ */ __name(() => {
|
|
3512
|
-
exports.internal.clearHistory();
|
|
3513
|
-
message_default("[memorio history] History cleared");
|
|
3514
|
-
}, "clearHistory");
|
|
3515
|
-
var clearRedo = /* @__PURE__ */ __name(() => {
|
|
3516
|
-
exports.internal.clearRedo();
|
|
3517
|
-
}, "clearRedo");
|
|
4653
|
+
__name(typed, "typed");
|
|
3518
4654
|
|
|
3519
4655
|
// functions/memory/index.ts
|
|
3520
4656
|
init_cjs_shims();
|
|
@@ -4207,83 +5343,167 @@ var memory = {
|
|
|
4207
5343
|
}
|
|
4208
5344
|
};
|
|
4209
5345
|
|
|
4210
|
-
// functions/
|
|
5346
|
+
// functions/history/index.ts
|
|
4211
5347
|
init_cjs_shims();
|
|
5348
|
+
init_internal();
|
|
4212
5349
|
init_env();
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
}
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
const parts = path.replace(/^state\./, "").split(".");
|
|
4222
|
-
let current = exports.state;
|
|
4223
|
-
for (const part of parts) {
|
|
4224
|
-
if (current === null || current === void 0) {
|
|
4225
|
-
return false;
|
|
4226
|
-
}
|
|
4227
|
-
current = current[part];
|
|
5350
|
+
init_message();
|
|
5351
|
+
function _clone(value) {
|
|
5352
|
+
if (value === null || typeof value !== "object") return value;
|
|
5353
|
+
try {
|
|
5354
|
+
return deepRaw(value, /* @__PURE__ */ new WeakSet());
|
|
5355
|
+
} catch (err) {
|
|
5356
|
+
if (exports.DEV) console.warn("[memorio history] deep clone failed:", err);
|
|
5357
|
+
return value;
|
|
4228
5358
|
}
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
var
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
}, "stateGet");
|
|
4241
|
-
var stateSchema = /* @__PURE__ */ __name(() => {
|
|
4242
|
-
const result = [];
|
|
4243
|
-
const _walk = /* @__PURE__ */ __name((obj, prefix) => {
|
|
4244
|
-
if (obj === null || typeof obj !== "object" || Array.isArray(obj)) {
|
|
4245
|
-
return;
|
|
4246
|
-
}
|
|
4247
|
-
const keys = Object.keys(obj).filter(
|
|
4248
|
-
(k) => !["list", "remove", "removeAll", "lock", "unlock"].includes(k)
|
|
4249
|
-
);
|
|
4250
|
-
for (const key of keys) {
|
|
5359
|
+
}
|
|
5360
|
+
__name(_clone, "_clone");
|
|
5361
|
+
var snapshot = /* @__PURE__ */ __name(() => {
|
|
5362
|
+
return deepRaw(exports.state, /* @__PURE__ */ new WeakSet());
|
|
5363
|
+
}, "snapshot");
|
|
5364
|
+
var diff = /* @__PURE__ */ __name((snap) => {
|
|
5365
|
+
const changes = [];
|
|
5366
|
+
const _walk = /* @__PURE__ */ __name((oldObj, newObj, prefix) => {
|
|
5367
|
+
const oldKeys = oldObj ? Object.keys(oldObj) : [];
|
|
5368
|
+
const newKeys = newObj ? Object.keys(newObj) : [];
|
|
5369
|
+
for (const key of newKeys) {
|
|
4251
5370
|
const newPath = prefix ? `${prefix}.${key}` : key;
|
|
4252
|
-
const
|
|
4253
|
-
const
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
5371
|
+
const oldVal = oldObj ? oldObj[key] : void 0;
|
|
5372
|
+
const newVal = newObj[key];
|
|
5373
|
+
if (oldVal !== newVal) {
|
|
5374
|
+
const oldType = typeof oldVal;
|
|
5375
|
+
const newType = typeof newVal;
|
|
5376
|
+
if (oldType !== newType || oldVal === void 0) {
|
|
5377
|
+
changes.push({ path: newPath, oldValue: oldVal, newValue: newVal });
|
|
5378
|
+
} else if (oldVal && typeof oldVal === "object") {
|
|
5379
|
+
_walk(oldVal, newVal, newPath);
|
|
5380
|
+
} else if (oldVal !== newVal) {
|
|
5381
|
+
changes.push({ path: newPath, oldValue: oldVal, newValue: newVal });
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
}
|
|
5385
|
+
for (const key of oldKeys) {
|
|
5386
|
+
if (!(key in (newObj || {}))) {
|
|
5387
|
+
const newPath = prefix ? `${prefix}.${key}` : key;
|
|
5388
|
+
changes.push({ path: newPath, oldValue: oldObj[key], newValue: void 0 });
|
|
4258
5389
|
}
|
|
4259
5390
|
}
|
|
4260
5391
|
}, "_walk");
|
|
4261
|
-
_walk(deepRaw(exports.state), "");
|
|
4262
|
-
return
|
|
4263
|
-
}, "
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
5392
|
+
_walk(snap, deepRaw(exports.state), "");
|
|
5393
|
+
return changes;
|
|
5394
|
+
}, "diff");
|
|
5395
|
+
var enableHistory = /* @__PURE__ */ __name((enabled = true) => {
|
|
5396
|
+
exports.internal.historyEnabled = enabled;
|
|
5397
|
+
message_default(`[memorio history] Tracking ${enabled ? "enabled" : "disabled"}`);
|
|
5398
|
+
}, "enableHistory");
|
|
5399
|
+
var trace = /* @__PURE__ */ __name(() => {
|
|
5400
|
+
return [...exports.internal.mutations];
|
|
5401
|
+
}, "trace");
|
|
5402
|
+
var canUndo = /* @__PURE__ */ __name(() => {
|
|
5403
|
+
return exports.internal.canUndo();
|
|
5404
|
+
}, "canUndo");
|
|
5405
|
+
var canRedo = /* @__PURE__ */ __name(() => {
|
|
5406
|
+
return exports.internal.canRedo();
|
|
5407
|
+
}, "canRedo");
|
|
5408
|
+
var undo = /* @__PURE__ */ __name(() => {
|
|
5409
|
+
if (!exports.internal.historyEnabled) {
|
|
5410
|
+
message_default("[memorio history] History is not enabled");
|
|
5411
|
+
return void 0;
|
|
5412
|
+
}
|
|
5413
|
+
const record = exports.internal.popUndo();
|
|
5414
|
+
if (!record) return void 0;
|
|
5415
|
+
_applyInverse2(record);
|
|
5416
|
+
message_default(`[memorio history] Undid: ${record.action} ${record.path}`);
|
|
5417
|
+
return record;
|
|
5418
|
+
}, "undo");
|
|
5419
|
+
var redo = /* @__PURE__ */ __name(() => {
|
|
5420
|
+
if (!exports.internal.historyEnabled) {
|
|
5421
|
+
message_default("[memorio history] History is not enabled");
|
|
5422
|
+
return void 0;
|
|
5423
|
+
}
|
|
5424
|
+
const record = exports.internal.popRedo();
|
|
5425
|
+
if (!record) return void 0;
|
|
5426
|
+
_applyForward(record);
|
|
5427
|
+
message_default(`[memorio history] Redid: ${record.action} ${record.path}`);
|
|
5428
|
+
return record;
|
|
5429
|
+
}, "redo");
|
|
5430
|
+
function _applyInverse2(record) {
|
|
5431
|
+
const wasEnabled = exports.internal.historyEnabled;
|
|
5432
|
+
exports.internal.historyEnabled = false;
|
|
5433
|
+
try {
|
|
5434
|
+
if (record.action === "set") {
|
|
5435
|
+
if (record.previousValue === void 0) {
|
|
5436
|
+
_deletePath2(record.path);
|
|
5437
|
+
} else {
|
|
5438
|
+
_setPath2(record.path, record.previousValue);
|
|
5439
|
+
}
|
|
5440
|
+
} else if (record.action === "delete") {
|
|
5441
|
+
if (record.previousValue !== void 0) {
|
|
5442
|
+
_setPath2(record.path, record.previousValue);
|
|
5443
|
+
}
|
|
5444
|
+
}
|
|
5445
|
+
} finally {
|
|
5446
|
+
exports.internal.historyEnabled = wasEnabled;
|
|
5447
|
+
}
|
|
5448
|
+
}
|
|
5449
|
+
__name(_applyInverse2, "_applyInverse");
|
|
5450
|
+
function _applyForward(record) {
|
|
5451
|
+
const wasEnabled = exports.internal.historyEnabled;
|
|
5452
|
+
exports.internal.historyEnabled = false;
|
|
5453
|
+
try {
|
|
5454
|
+
if (record.action === "set") {
|
|
5455
|
+
_setPath2(record.path, record.newValue);
|
|
5456
|
+
} else if (record.action === "delete") {
|
|
5457
|
+
_deletePath2(record.path);
|
|
5458
|
+
}
|
|
5459
|
+
} finally {
|
|
5460
|
+
exports.internal.historyEnabled = wasEnabled;
|
|
5461
|
+
}
|
|
5462
|
+
}
|
|
5463
|
+
__name(_applyForward, "_applyForward");
|
|
5464
|
+
function _setPath2(path, value) {
|
|
5465
|
+
const parts = path.split(".");
|
|
4267
5466
|
let current = exports.state;
|
|
4268
|
-
for (
|
|
4269
|
-
|
|
4270
|
-
|
|
5467
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
5468
|
+
const part = parts[i];
|
|
5469
|
+
if (current[part] === void 0) {
|
|
5470
|
+
current[part] = {};
|
|
4271
5471
|
}
|
|
4272
5472
|
current = current[part];
|
|
4273
5473
|
}
|
|
4274
|
-
|
|
5474
|
+
current[parts[parts.length - 1]] = value;
|
|
4275
5475
|
}
|
|
4276
|
-
__name(
|
|
4277
|
-
function
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
5476
|
+
__name(_setPath2, "_setPath");
|
|
5477
|
+
function _deletePath2(path) {
|
|
5478
|
+
const parts = path.split(".");
|
|
5479
|
+
if (parts.length === 1) {
|
|
5480
|
+
exports.state.remove(parts[0]);
|
|
5481
|
+
return;
|
|
5482
|
+
}
|
|
5483
|
+
let current = exports.state;
|
|
5484
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
5485
|
+
const part = parts[i];
|
|
5486
|
+
if (current[part] === void 0) return;
|
|
5487
|
+
current = current[part];
|
|
4284
5488
|
}
|
|
5489
|
+
delete current[parts[parts.length - 1]];
|
|
4285
5490
|
}
|
|
4286
|
-
__name(
|
|
5491
|
+
__name(_deletePath2, "_deletePath");
|
|
5492
|
+
var rollback = /* @__PURE__ */ __name((snap) => {
|
|
5493
|
+
exports.state.removeAll();
|
|
5494
|
+
for (const key of Object.keys(snap)) {
|
|
5495
|
+
exports.state[key] = _clone(snap[key]);
|
|
5496
|
+
}
|
|
5497
|
+
exports.internal.clearHistory();
|
|
5498
|
+
message_default("[memorio history] State rolled back to snapshot");
|
|
5499
|
+
}, "rollback");
|
|
5500
|
+
var clearHistory2 = /* @__PURE__ */ __name(() => {
|
|
5501
|
+
exports.internal.clearHistory();
|
|
5502
|
+
message_default("[memorio history] History cleared");
|
|
5503
|
+
}, "clearHistory");
|
|
5504
|
+
var clearRedo = /* @__PURE__ */ __name(() => {
|
|
5505
|
+
exports.internal.clearRedo();
|
|
5506
|
+
}, "clearRedo");
|
|
4287
5507
|
|
|
4288
5508
|
// core/global.ts
|
|
4289
5509
|
if (!("memorio" in globalThis)) {
|
|
@@ -4318,6 +5538,26 @@ if (!("memorio" in globalThis)) {
|
|
|
4318
5538
|
}
|
|
4319
5539
|
);
|
|
4320
5540
|
}
|
|
5541
|
+
if (typeof globalThis.addEventListener !== "function") {
|
|
5542
|
+
const listeners = {};
|
|
5543
|
+
globalThis.addEventListener = (name, cb) => {
|
|
5544
|
+
(listeners[name] = listeners[name] ?? []).push(cb);
|
|
5545
|
+
};
|
|
5546
|
+
globalThis.removeEventListener = (name, cb) => {
|
|
5547
|
+
const arr = listeners[name];
|
|
5548
|
+
if (arr) {
|
|
5549
|
+
const idx = arr.indexOf(cb);
|
|
5550
|
+
if (idx > -1) arr.splice(idx, 1);
|
|
5551
|
+
}
|
|
5552
|
+
};
|
|
5553
|
+
globalThis.dispatchEvent = (e) => {
|
|
5554
|
+
const type = (e && typeof e === "object" ? e.type : null) || String(e);
|
|
5555
|
+
const arr = listeners[type];
|
|
5556
|
+
if (arr) {
|
|
5557
|
+
arr.slice().forEach((cb) => cb(e));
|
|
5558
|
+
}
|
|
5559
|
+
};
|
|
5560
|
+
}
|
|
4321
5561
|
if (typeof globalThis.addEventListener === "function") {
|
|
4322
5562
|
dispatch.listen("memorio:memory:cleanup", async () => memory.forgetExpired?.());
|
|
4323
5563
|
}
|
|
@@ -4331,16 +5571,18 @@ if (!("memorio" in globalThis)) {
|
|
|
4331
5571
|
}
|
|
4332
5572
|
);
|
|
4333
5573
|
memorio.memory = memory;
|
|
5574
|
+
memorio.encryption = exports.encryption;
|
|
4334
5575
|
initializePlatform();
|
|
4335
5576
|
memorio.isBrowser = isBrowser;
|
|
4336
5577
|
memorio.isNode = isNode;
|
|
4337
5578
|
memorio.isDeno = isDeno;
|
|
5579
|
+
memorio.isBun = isBun;
|
|
4338
5580
|
memorio.isEdge = isEdge;
|
|
4339
5581
|
memorio.getCapabilities = getCapabilities;
|
|
4340
5582
|
memorio.createContext = createContext;
|
|
4341
5583
|
memorio.listContexts = listContexts;
|
|
4342
5584
|
memorio.deleteContext = deleteContext;
|
|
4343
|
-
memorio.isolate = (name) => createContext(name);
|
|
5585
|
+
memorio.isolate = (name, opts) => createContext(name, opts);
|
|
4344
5586
|
Object.defineProperty(memorio, "setContext", { writable: false, enumerable: false, value: /* @__PURE__ */ __name((id) => setCurrentContext(id), "value") });
|
|
4345
5587
|
Object.defineProperty(memorio, "getContext", { writable: false, enumerable: false, value: /* @__PURE__ */ __name(() => exports.internal.currentContext, "value") });
|
|
4346
5588
|
memorio.registerSchema = schema.register;
|
|
@@ -4348,6 +5590,9 @@ if (!("memorio" in globalThis)) {
|
|
|
4348
5590
|
memorio.unregisterSchema = schema.unregister;
|
|
4349
5591
|
memorio.listSchemas = schema.list;
|
|
4350
5592
|
memorio.typed = typed;
|
|
5593
|
+
memorio.computed = computed;
|
|
5594
|
+
memorio.broadcast = broadcast;
|
|
5595
|
+
memorio.security = security;
|
|
4351
5596
|
memorio.snapshot = snapshot;
|
|
4352
5597
|
memorio.diff = diff;
|
|
4353
5598
|
memorio.undo = undo;
|
|
@@ -4359,10 +5604,17 @@ if (!("memorio" in globalThis)) {
|
|
|
4359
5604
|
memorio.enableHistory = enableHistory;
|
|
4360
5605
|
memorio.clearHistory = clearHistory2;
|
|
4361
5606
|
memorio.clearRedo = clearRedo;
|
|
5607
|
+
memorio.mutate = mutate;
|
|
5608
|
+
memorio.createMutation = createMutation;
|
|
5609
|
+
memorio.recordMutation = recordMutation;
|
|
5610
|
+
memorio.toPatch = toPatch;
|
|
5611
|
+
memorio.transaction = beginTransaction;
|
|
5612
|
+
memorio.commitTransaction = commitTransaction;
|
|
5613
|
+
memorio.abortTransaction = abortTransaction;
|
|
5614
|
+
memorio.currentTransaction = currentTransaction;
|
|
4362
5615
|
Object.defineProperty(memorio, "dispatch", { value: dispatch, writable: true, enumerable: false, configurable: true });
|
|
4363
|
-
const isDev = exports.DEV;
|
|
4364
5616
|
memorio.env = {
|
|
4365
|
-
isDev,
|
|
5617
|
+
isDev: exports.DEV,
|
|
4366
5618
|
isProd: exports.PROD
|
|
4367
5619
|
};
|
|
4368
5620
|
memorio.global = function() {
|
|
@@ -4374,189 +5626,98 @@ if (!("memorio" in globalThis)) {
|
|
|
4374
5626
|
idb: exports.idb,
|
|
4375
5627
|
sqlite: exports.sqlite,
|
|
4376
5628
|
observer,
|
|
4377
|
-
useObserver
|
|
5629
|
+
useObserver,
|
|
5630
|
+
encryption: exports.encryption,
|
|
5631
|
+
computed,
|
|
5632
|
+
broadcast,
|
|
5633
|
+
security
|
|
4378
5634
|
};
|
|
4379
5635
|
for (const key of Object.keys(globalDefinitions)) {
|
|
4380
5636
|
if (!(key in globalThis)) {
|
|
4381
5637
|
Object.defineProperty(globalThis, key, {
|
|
4382
5638
|
value: globalDefinitions[key],
|
|
4383
5639
|
writable: true,
|
|
4384
|
-
|
|
4385
|
-
|
|
5640
|
+
configurable: true,
|
|
5641
|
+
enumerable: false
|
|
4386
5642
|
});
|
|
4387
5643
|
}
|
|
4388
5644
|
}
|
|
5645
|
+
if (typeof globalThis.useObserver === "function") {
|
|
5646
|
+
Object.freeze(globalThis.useObserver);
|
|
5647
|
+
}
|
|
4389
5648
|
};
|
|
4390
|
-
if (isDev) {
|
|
4391
|
-
memorio.global();
|
|
4392
|
-
}
|
|
4393
|
-
if (exports.DEV) {
|
|
4394
|
-
Object.defineProperty(
|
|
4395
|
-
memorio,
|
|
4396
|
-
"debug",
|
|
4397
|
-
{
|
|
4398
|
-
get: /* @__PURE__ */ __name(() => exports.internal.debug, "get"),
|
|
4399
|
-
set: /* @__PURE__ */ __name((v) => {
|
|
4400
|
-
exports.internal.debug = v;
|
|
4401
|
-
}, "set"),
|
|
4402
|
-
enumerable: false
|
|
4403
|
-
}
|
|
4404
|
-
);
|
|
4405
|
-
const caps = getCapabilities();
|
|
4406
|
-
Object.defineProperty(memorio, "_platform", { writable: false, enumerable: false, value: caps.platform });
|
|
4407
|
-
Object.defineProperty(memorio, "_capabilities", { writable: false, enumerable: false, value: caps });
|
|
4408
|
-
Object.defineProperty(memorio, "_sessionId", { writable: false, enumerable: false, value: generateSessionId() });
|
|
4409
|
-
memorio.logger = logger;
|
|
4410
|
-
if (!("$state" in globalThis)) Object.defineProperty(globalThis, "$state", { get: /* @__PURE__ */ __name(() => globalThis.state, "get"), configurable: true });
|
|
4411
|
-
if (!("$store" in globalThis)) Object.defineProperty(globalThis, "$store", { get: /* @__PURE__ */ __name(() => globalThis.store, "get"), configurable: true });
|
|
4412
|
-
if (!("$session" in globalThis)) Object.defineProperty(globalThis, "$session", { get: /* @__PURE__ */ __name(() => globalThis.session, "get"), configurable: true });
|
|
4413
|
-
if (!("$cache" in globalThis)) Object.defineProperty(globalThis, "$cache", { get: /* @__PURE__ */ __name(() => globalThis.cache, "get"), configurable: true });
|
|
4414
|
-
memorio.devtools = devtools;
|
|
4415
|
-
memorio.inspect = stateKeys;
|
|
4416
|
-
memorio.stateKeys = stateKeys;
|
|
4417
|
-
memorio.pathExists = pathExists;
|
|
4418
|
-
memorio.stateType = stateType;
|
|
4419
|
-
memorio.stateGet = stateGet;
|
|
4420
|
-
memorio.stateSchema = stateSchema;
|
|
4421
|
-
memorio.help = function() {
|
|
4422
|
-
console.debug(`
|
|
4423
|
-
\u{1F9E0} Memorio ${package_default.version} - Help
|
|
4424
|
-
|
|
4425
|
-
Core Modules (runtime):
|
|
4426
|
-
state - Reactive state management (DEV global)
|
|
4427
|
-
store - Persistent storage (localStorage/Map)
|
|
4428
|
-
session - Session storage (sessionStorage/Map)
|
|
4429
|
-
cache - In-memory cache
|
|
4430
|
-
idb - IndexedDB (browser only)
|
|
4431
|
-
sqlite - SQLite in browser (sql.js, optional)
|
|
4432
|
-
|
|
4433
|
-
Platform Detection:
|
|
4434
|
-
memorio.isBrowser() - Browser environment
|
|
4435
|
-
memorio.isNode() - Node.js environment
|
|
4436
|
-
memorio.isDeno() - Deno environment
|
|
4437
|
-
memorio.isEdge() - Edge/Worker environment
|
|
4438
|
-
memorio.getCapabilities() - Full capabilities object
|
|
4439
|
-
|
|
4440
|
-
Context Management:
|
|
4441
|
-
memorio.isolate(name) - Create isolated context
|
|
4442
|
-
memorio.listContexts() - List all contexts
|
|
4443
|
-
memorio.deleteContext(id) - Delete a context
|
|
4444
|
-
|
|
4445
|
-
Schema Validation (runtime):
|
|
4446
|
-
memorio.registerSchema() - Register a validator for a state path
|
|
4447
|
-
memorio.validate() - Manually validate a value
|
|
4448
|
-
memorio.unregisterSchema() - Remove a registered schema
|
|
4449
|
-
memorio.listSchemas() - List all registered schema paths
|
|
4450
|
-
memorio.typed<T>() - Type-safe view of global state (compile-time only)
|
|
4451
|
-
|
|
4452
|
-
History & Time Travel (runtime):
|
|
4453
|
-
memorio.snapshot() - Capture a deep snapshot of state
|
|
4454
|
-
memorio.diff(snap) - Diff snapshot against current state
|
|
4455
|
-
memorio.undo() / redo() - Undo / redo the last mutation
|
|
4456
|
-
memorio.canUndo() / canRedo() - Check availability
|
|
4457
|
-
memorio.rollback(snap) - Restore state from a snapshot
|
|
4458
|
-
memorio.trace() - List all recorded mutations
|
|
4459
|
-
memorio.enableHistory() - Enable/disable mutation tracking
|
|
4460
|
-
memorio.clearHistory() - Clear undo/redo stacks and trace log
|
|
4461
|
-
|
|
4462
|
-
DevTools (development-only):
|
|
4463
|
-
memorio.devtools.inspect() - Inspect all modules
|
|
4464
|
-
memorio.devtools.stats() - Show statistics
|
|
4465
|
-
memorio.devtools.watch() - Watch a path
|
|
4466
|
-
memorio.devtools.exportData() - Export as JSON
|
|
4467
|
-
memorio.devtools.importData() - Import from JSON
|
|
4468
|
-
memorio.devtools.clear() - Clear specific module
|
|
4469
|
-
memorio.devtools.clearAll() - Clear all modules
|
|
4470
|
-
|
|
4471
|
-
Introspection (development-only):
|
|
4472
|
-
memorio.stateKeys() - List top-level state keys
|
|
4473
|
-
memorio.pathExists(path) - Check if a state path exists
|
|
4474
|
-
memorio.stateType(path) - Get runtime type of a state value
|
|
4475
|
-
memorio.stateGet(path) - Get a deep-cloned value at a path
|
|
4476
|
-
memorio.stateSchema() - Get a schema report of all state paths
|
|
4477
|
-
|
|
4478
|
-
Debug:
|
|
4479
|
-
memorio.debug = true - Enable debug output (DEV only)
|
|
4480
|
-
|
|
4481
|
-
Memory System (runtime):
|
|
4482
|
-
memorio.memory.remember(key, value, opts) - Store a memory with type, confidence, scope, TTL, tags
|
|
4483
|
-
memorio.memory.recall(key, opts) - Retrieve a memory with filtering
|
|
4484
|
-
memorio.memory.update(key, value, opts) - Update an existing memory
|
|
4485
|
-
memorio.memory.forget(key) - Delete a specific memory
|
|
4486
|
-
memorio.memory.context(opts) - Get ranked relevant memories (semantic context for AI)
|
|
4487
|
-
memorio.memory.stats() - Memory usage statistics
|
|
4488
|
-
memorio.memory.forgetExpired() - Remove all expired entries
|
|
4489
|
-
memorio.memory.clear() - Wipe all memories
|
|
4490
|
-
memorio.memory.configure({ sync }) - Optional cloud-sync provider + namespace
|
|
4491
|
-
memorio.memory.journal.pending() - Local op journal (SQLite/store)
|
|
4492
|
-
|
|
4493
|
-
Scopes:
|
|
4494
|
-
hot - In-memory reactive state (volatile, fastest)
|
|
4495
|
-
session - sessionStorage (persists across page reloads, cleared on tab close)
|
|
4496
|
-
local - localStorage (persistent, survives browser restart)
|
|
4497
|
-
durable - IndexedDB (large datasets, async)
|
|
4498
|
-
sql - SQLite / sql.js (browser, optional, full SQL)
|
|
4499
|
-
|
|
4500
|
-
TTL options:
|
|
4501
|
-
ttl: number (milliseconds) or null (never expires)
|
|
4502
|
-
|
|
4503
|
-
Memory types:
|
|
4504
|
-
fact, preference, decision, task, context
|
|
4505
|
-
|
|
4506
|
-
Console shortcuts (DEV only):
|
|
4507
|
-
state, store, session, cache, idb, sqlite - direct access to modules
|
|
4508
|
-
$state, $store, $session, $cache - aliases for the above
|
|
4509
|
-
`);
|
|
4510
|
-
};
|
|
4511
|
-
}
|
|
4512
5649
|
}
|
|
4513
5650
|
|
|
4514
5651
|
// index.ts
|
|
4515
|
-
var
|
|
5652
|
+
var transaction = beginTransaction;
|
|
5653
|
+
var devtools = void 0;
|
|
4516
5654
|
var memorio2 = globalThis.memorio;
|
|
4517
5655
|
var events = globalThis.events;
|
|
4518
5656
|
var isolate = /* @__PURE__ */ __name((name) => createContext(name), "isolate");
|
|
4519
|
-
var
|
|
5657
|
+
var help = globalThis.memorio?.help;
|
|
4520
5658
|
var setContext = /* @__PURE__ */ __name((id) => exports.internal.currentContext = id, "setContext");
|
|
4521
5659
|
var getContext = /* @__PURE__ */ __name(() => exports.internal.currentContext, "getContext");
|
|
4522
5660
|
var index_default = memorio2;
|
|
4523
5661
|
|
|
5662
|
+
exports.abortTransaction = abortTransaction;
|
|
5663
|
+
exports.activeTransactionId = activeTransactionId;
|
|
5664
|
+
exports.beginTransaction = beginTransaction;
|
|
5665
|
+
exports.broadcast = broadcast;
|
|
4524
5666
|
exports.cache = cache;
|
|
5667
|
+
exports.canMerge = canMerge;
|
|
4525
5668
|
exports.canRedo = canRedo;
|
|
4526
5669
|
exports.canUndo = canUndo;
|
|
4527
5670
|
exports.clearHistory = clearHistory2;
|
|
4528
5671
|
exports.clearRedo = clearRedo;
|
|
5672
|
+
exports.commitTransaction = commitTransaction;
|
|
5673
|
+
exports.computed = computed;
|
|
4529
5674
|
exports.createContext = createContext;
|
|
5675
|
+
exports.createMutation = createMutation;
|
|
5676
|
+
exports.currentTimestamp = currentTimestamp;
|
|
5677
|
+
exports.currentTransaction = currentTransaction;
|
|
4530
5678
|
exports.default = index_default;
|
|
4531
5679
|
exports.deleteContext = deleteContext;
|
|
4532
|
-
exports.devtools =
|
|
5680
|
+
exports.devtools = devtools;
|
|
4533
5681
|
exports.diff = diff;
|
|
5682
|
+
exports.diffToPatch = diffToPatch;
|
|
4534
5683
|
exports.dispatch = dispatch;
|
|
4535
5684
|
exports.enableHistory = enableHistory;
|
|
4536
5685
|
exports.events = events;
|
|
4537
5686
|
exports.fractional = fractional;
|
|
5687
|
+
exports.generateCommitId = generateCommitId;
|
|
5688
|
+
exports.generateMutationId = generateMutationId;
|
|
5689
|
+
exports.generateTransactionId = generateTransactionId;
|
|
4538
5690
|
exports.getCapabilities = getCapabilities;
|
|
4539
5691
|
exports.getContext = getContext;
|
|
4540
|
-
exports.help =
|
|
5692
|
+
exports.help = help;
|
|
4541
5693
|
exports.hlc = hlc;
|
|
4542
5694
|
exports.isBrowser = isBrowser;
|
|
5695
|
+
exports.isBun = isBun;
|
|
4543
5696
|
exports.isDeno = isDeno;
|
|
4544
5697
|
exports.isEdge = isEdge;
|
|
4545
5698
|
exports.isNode = isNode;
|
|
4546
5699
|
exports.isolate = isolate;
|
|
4547
5700
|
exports.listContexts = listContexts;
|
|
4548
5701
|
exports.listSchemas = listSchemas;
|
|
5702
|
+
exports.listTransactions = listTransactions;
|
|
4549
5703
|
exports.logger = logger;
|
|
4550
5704
|
exports.memorio = memorio2;
|
|
4551
5705
|
exports.memory = memory;
|
|
5706
|
+
exports.mergePatches = mergePatches;
|
|
5707
|
+
exports.mutate = mutate;
|
|
5708
|
+
exports.mutationToPatch = mutationToPatch;
|
|
4552
5709
|
exports.observer = observer;
|
|
5710
|
+
exports.recordMutation = recordMutation;
|
|
4553
5711
|
exports.redo = redo;
|
|
4554
5712
|
exports.registerSchema = registerSchema;
|
|
4555
5713
|
exports.rollback = rollback;
|
|
4556
5714
|
exports.schema = schema;
|
|
5715
|
+
exports.security = security;
|
|
4557
5716
|
exports.setContext = setContext;
|
|
4558
5717
|
exports.snapshot = snapshot;
|
|
5718
|
+
exports.toPatch = toPatch;
|
|
4559
5719
|
exports.trace = trace;
|
|
5720
|
+
exports.transaction = transaction;
|
|
4560
5721
|
exports.typed = typed;
|
|
4561
5722
|
exports.undo = undo;
|
|
4562
5723
|
exports.unregisterSchema = unregisterSchema;
|