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