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.
Files changed (82) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +95 -516
  3. package/SECURITY.md +159 -33
  4. package/SUMMARY.md +59 -45
  5. package/adr/001-state-proxy-model.md +95 -0
  6. package/adr/002-observer-semantics.md +179 -0
  7. package/adr/003-deep-mutation-semantics.md +128 -0
  8. package/adr/004-array-mutation-semantics.md +127 -0
  9. package/adr/005-scheduler-contract.md +148 -0
  10. package/adr/006-context-isolation.md +91 -0
  11. package/adr/007-mutation-records.md +117 -0
  12. package/adr/008-transactions.md +105 -0
  13. package/adr/009-history-model.md +109 -0
  14. package/adr/README.md +46 -0
  15. package/adr/template.md +48 -0
  16. package/bin/cli.js +68 -0
  17. package/examples/basic.ts +115 -115
  18. package/examples/browser-vanilla.html +358 -358
  19. package/examples/cache.ts +72 -72
  20. package/examples/cross-platform-guards.ts +57 -57
  21. package/examples/history.ts +104 -0
  22. package/examples/idb.ts +109 -109
  23. package/examples/multi-tenant-context.ts +44 -44
  24. package/examples/node-server.ts +308 -308
  25. package/examples/observer.ts +60 -60
  26. package/examples/platform.ts +115 -115
  27. package/examples/react-app.tsx +362 -362
  28. package/examples/react-observer.tsx +63 -63
  29. package/examples/semantic-memory.ts +60 -60
  30. package/examples/session-advanced.ts +91 -91
  31. package/examples/sqlite-batched-writes.ts +57 -57
  32. package/examples/state-advanced.ts +89 -89
  33. package/examples/store-advanced.ts +117 -117
  34. package/examples/sync.ts +90 -0
  35. package/examples/typed-and-schema.ts +102 -100
  36. package/examples/useObserver.tsx +140 -141
  37. package/global.cjs +5733 -0
  38. package/global.d.ts +8 -0
  39. package/global.js +5667 -0
  40. package/index.cjs +2202 -1041
  41. package/index.d.ts +2 -0
  42. package/index.js +2178 -1040
  43. package/llms.txt +113 -8
  44. package/markdown/AUDIT-REPORT.md +134 -0
  45. package/markdown/CACHE.md +191 -0
  46. package/markdown/DEVTOOLS.md +128 -0
  47. package/markdown/DISPATCH.md +176 -0
  48. package/markdown/HISTORY.md +198 -0
  49. package/markdown/IDB.md +177 -0
  50. package/markdown/IMPORT.md +152 -0
  51. package/markdown/INSPECT.md +122 -0
  52. package/markdown/LOGGER.md +153 -0
  53. package/markdown/MEMORY-ATTACHMENT.md +95 -0
  54. package/markdown/MEMORY.md +161 -0
  55. package/markdown/OBSERVER.md +208 -0
  56. package/markdown/PLATFORM.md +277 -0
  57. package/markdown/REDUX.md +54 -0
  58. package/markdown/SCHEMA.md +175 -0
  59. package/markdown/SESSION.md +164 -0
  60. package/markdown/SQLITE.md +189 -0
  61. package/markdown/STATE.md +159 -0
  62. package/markdown/STORE.md +170 -0
  63. package/markdown/SYNC.md +318 -0
  64. package/markdown/TYPED.md +164 -0
  65. package/markdown/USEOBSERVER.md +256 -0
  66. package/modules/redux.cjs +701 -177
  67. package/modules/redux.cjs.map +1 -1
  68. package/modules/redux.js +701 -177
  69. package/modules/redux.js.map +1 -1
  70. package/package.json +26 -4
  71. package/types/broadcast.d.ts +61 -0
  72. package/types/computed.d.ts +96 -0
  73. package/types/encryption.d.ts +129 -0
  74. package/types/env.d.ts +19 -9
  75. package/types/exports.d.ts +29 -0
  76. package/types/history.d.ts +13 -1
  77. package/types/memorio.d.ts +25 -6
  78. package/types/mutation.d.ts +75 -0
  79. package/types/security.d.ts +67 -0
  80. package/types/session.d.ts +23 -5
  81. package/types/store.d.ts +19 -3
  82. package/vsix/memorio.vsix +0 -0
@@ -0,0 +1,105 @@
1
+ # ADR-008: Transactions
2
+
3
+ > **Status:** Accepted
4
+ > **Date:** 2026-09-12
5
+
6
+ ## Context
7
+
8
+ Section 11 of the Memorio 5.x plan requires transactions to group
9
+ multiple mutations into one logical operation. The 5.0 codebase
10
+ implements `beginTransaction`, `commitTransaction`,
11
+ `abortTransaction`, `listTransactions`, `currentTransaction` in
12
+ `core/mutation/transaction.ts`. This ADR formalizes the semantics.
13
+
14
+ ## Assumptions
15
+
16
+ - Mutations inside a transaction are tagged with the transaction ID
17
+ via `createMutation()` → `tagForTransaction()`.
18
+ - The transaction registry lives on `globalThis`
19
+ (`__memorio_transaction_registry__`) to survive module duplication.
20
+ - `internal.currentTransactionId` tracks the active transaction.
21
+ - `memorio.transaction(fn, opts)` is a convenience alias for
22
+ `beginTransaction`.
23
+
24
+ ## Decision
25
+
26
+ ### Transaction lifecycle
27
+
28
+ ```
29
+ beginTransaction(source, message, metadata)
30
+ → creates TransactionContext { id, startedAt, active: true }
31
+ → sets internal.currentTransactionId = id
32
+ → mutations tagged with id
33
+
34
+ commitTransaction()
35
+ → marks context active: false, sets committedAt
36
+ → clears internal.currentTransactionId
37
+ → returns { id, mutations[], startedAt, committedAt, source, message, metadata }
38
+
39
+ abortTransaction()
40
+ → rolls back all tagged mutations (applies inverse)
41
+ → removes mutation IDs from undoStack (no redo push)
42
+ → deletes from registry, clears currentTransactionId
43
+ → returns the Transaction record
44
+ ```
45
+
46
+ ### Transaction ID generation
47
+
48
+ - Generated via `generateTransactionId()` → `tx_<encoded-hlc>`.
49
+ - Monotonically ordered within a node via HLC.
50
+
51
+ ### Nested transactions
52
+
53
+ `beginTransaction` called while a transaction is already active
54
+ creates a **new** transaction context (with a new ID). The previous
55
+ transaction remains active in the registry - it is **not** suspended
56
+ or paused. `commitTransaction()` only commits the **most recently
57
+ started** active transaction.
58
+
59
+ This is a **flat namespace** model: transactions are independent, not
60
+ hierarchical. A mutation made after the inner `beginTransaction` is
61
+ tagged with the inner transaction's ID, not the outer.
62
+
63
+ > **Future:** A hierarchical model (with parentId) may be introduced.
64
+ > This ADR documents the current flat behavior.
65
+
66
+ ### Rollback on abort
67
+
68
+ `abortTransaction` finds each tagged mutation in `undoStack` by its
69
+ record ID, removes it from the stack (without pushing to redo), and
70
+ applies the inverse (`_applyInverse`). The inverse writes go through
71
+ the Proxy with `historyEnabled = false` and `_recording = false`, so
72
+ they are not recorded.
73
+
74
+ ### Transaction record immutability
75
+
76
+ Once committed or aborted, a transaction's `mutations` list is frozen
77
+ (immutable). The registry retains the context for
78
+ `listTransactions()` inspection, but `active` is `false`.
79
+
80
+ ### Mutate inside a transaction
81
+
82
+ `memorio.mutate(path, value, { source })` inside a transaction:
83
+ 1. Calls `createMutation(...)` which auto-tags with the active
84
+ transaction ID via `tagForTransaction()`.
85
+ 2. Writes to state with `_recording = false` (no double recording).
86
+ 3. Calls `recordMutation(mutation)` - the mutation is recorded in the
87
+ trace log AND tagged in the transaction.
88
+
89
+ ## Consequences
90
+
91
+ - **Positive:** Mutations are grouped and attributable to a logical
92
+ operation - essential for explain() and impact() in Phase 4.
93
+ - **Positive:** `abortTransaction` provides atomic rollback - all
94
+ mutations are undone.
95
+ - **Positive:** Registry on `globalThis` survives module duplication.
96
+ - **Negative:** Nested transactions are flat (not hierarchical) -
97
+ the outer transaction is not aborted if the inner is aborted.
98
+ - **Negative:** Rollback via inverse application requires all
99
+ `before` values to be present in the MutationRecord - for
100
+ very large objects this is memory-intensive.
101
+
102
+ ## Compliance tests
103
+
104
+ - `tests/vitest/tests/contracts/adr-008-transactions.test.ts`
105
+ - `tests/vitest/tests/mutation-engine.test.ts` (existing, §06-07)
@@ -0,0 +1,109 @@
1
+ # ADR-009: History Model (Snapshot / Delta)
2
+
3
+ > **Status:** Proposed
4
+ > **Date:** 2026-09-12
5
+
6
+ ## Context
7
+
8
+ Section 12 and Section 13 of the Memorio 5.x plan require an immutable,
9
+ Git-inspired history model with commits, snapshots, deltas, and undo/redo
10
+ as distinct concepts. The 4.7.3 baseline implements undo/redo on a
11
+ linear mutation stack (in `core/internal.ts` and
12
+ `functions/history/index.ts`). This ADR defines the upgrade path to
13
+ the full Commit → Snapshot → Delta model.
14
+
15
+ ## Assumptions
16
+
17
+ - The current undo/redo stack stores flat `MutationRecord` entries.
18
+ - `enableHistory(true)` activates recording.
19
+ - `memorio.snapshot()` captures a deep clone of state.
20
+ - `memorio.trace()` returns the flat mutation log.
21
+
22
+ ## Decision
23
+
24
+ ### Current state (4.7.3 baseline)
25
+
26
+ - Mutations are stored as `MutationRecord[]` in `undoStack` and
27
+ `redoStack` on the singleton `internal` object.
28
+ - `undo()` pops from `undoStack`, pushes to `redoStack`, applies the
29
+ inverse to state.
30
+ - `redo()` pops from `redoStack`, pushes to `undoStack`, re-applies.
31
+ - `trace()` returns the full `mutations` log (trimmed to
32
+ `maxHistory`).
33
+ - No commit concept exists - every mutation is an individual entry.
34
+
35
+ ### Target state (Memorio 5.0)
36
+
37
+ ```
38
+ Commit (immutable, append-only)
39
+ ├── parent: CommitId | null
40
+ ├── patches: Patch[] (RFC 6902: add | remove | replace)
41
+ ├── metadata: { source?, message?, actor?, timestamp, hlc }
42
+ └── snapshot?: SnapshotRef (materialized every N commits)
43
+ ```
44
+
45
+ - **Commits** are the unit of history. `memorio.commit(message, fn)`
46
+ groups all mutations in `fn` into one commit.
47
+ - **Snapshots** are deep clones of state, materialized every
48
+ `snapshotInterval` commits (default: 100) to bound replay cost.
49
+ - **Deltas** are the `Patch[]` that transform a snapshot to the next
50
+ state. Only patches are stored between snapshots - never full
51
+ state copies.
52
+ - **Undo/Redo** operate at the commit level, not the individual
53
+ mutation level. Undoing a commit applies the inverse of every patch
54
+ in the commit.
55
+
56
+ ### Migration path
57
+
58
+ 1. **Phase 1 (this sprint):** Keep the existing flat mutation stack.
59
+ Document that `undo()`/`redo()` operate per-mutation, not per-commit.
60
+ Add `memorio.commit()` as a grouping mechanism without changing the
61
+ underlying stack.
62
+ 2. **Phase 3:** Replace the flat stack with the Commit → Snapshot →
63
+ Delta model. `undo()`/`redo()` will operate per-commit.
64
+
65
+ ### Undo vs. Revert (explicit distinction)
66
+
67
+ - **Undo** (`memorio.undo()`): Moves the current position backward in
68
+ the undo stack. The mutation is preserved on the redo stack.
69
+ - **Revert** (`memorio.history.revert(commitId)`): Creates a **new**
70
+ mutation that reverses a historical commit. The original commit
71
+ remains in history (immutable). This is a future Phase 3 feature.
72
+
73
+ ### maxCommits and maxHistory
74
+
75
+ - `maxCommits` (default: 10,000): Maximum number of commit entries
76
+ retained. Older commits are trimmed (FIFO).
77
+ - `maxHistory` (default: 100): Maximum mutations per undo/redo stack
78
+ (legacy, applies to the current flat model).
79
+
80
+ ### Replay safety
81
+
82
+ - Replay must be deterministic. Patches are pure (no closures, no
83
+ functions). `state.path = value` is the inverse of `delete
84
+ state.path` in a patch-based replay.
85
+ - External dependencies (Date.now, Math.random, crypto) must be
86
+ injected via a replay context to maintain determinism.
87
+
88
+ ## Consequences
89
+
90
+ - **Positive:** Commits group mutations logically - essential for
91
+ explain(), business history, and audit trails.
92
+ - **Positive:** Snapshot/delta model bounds memory and replay cost.
93
+ - **Positive:** Undo and Revert are distinct operations - no
94
+ conflation.
95
+ - **Negative:** The current flat stack must be replaced in Phase 3,
96
+ which is a breaking change to `undo()`/`redo()` semantics
97
+ (per-mutation → per-commit).
98
+ - **Negative:** Snapshot materialization at intervals is a trade-off
99
+ between memory and CPU - defaults must be benchmark-driven.
100
+
101
+ ## Compliance tests
102
+
103
+ - `tests/vitest/tests/contracts/adr-009-history.test.ts`
104
+ - `tests/vitest/tests/mutation-engine.test.ts` (existing, §04-07)
105
+
106
+ ## Benchmarks
107
+
108
+ - `experimental/benchmarks/replay.bench.ts` - measures replay cost
109
+ with and without interval snapshots.
package/adr/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # Architecture Decision Records (ADRs)
2
+
3
+ This directory contains Architecture Decision Records (ADRs) for the
4
+ **Memorio 5.x** "Application State Intelligence Runtime" initiative.
5
+
6
+ ## Format
7
+
8
+ ADRs follow the [MADR](https://adr.github.io/) (Markdown Architectural
9
+ Decision Records) format. Each decision record answers four questions:
10
+
11
+ 1. **Context** - What is the issue that we were dealing with when we
12
+ started thinking about it?
13
+ 2. **Decision** - What is the change that we will make (that resolves
14
+ the issue)?
15
+ 3. **Consequences** - What becomes easier or more difficult to do
16
+ because of this change?
17
+
18
+ ## Numbering
19
+
20
+ | ADR | Title | Status |
21
+ |-----|-------|--------|
22
+ | [001](001-state-proxy-model.md) | State Proxy Model | Accepted |
23
+ | [002](002-observer-semantics.md) | Observer Semantics | Proposed |
24
+ | [003](003-deep-mutation-semantics.md) | Deep Mutation Semantics | Proposed |
25
+ | [004](004-array-mutation-semantics.md) | Array Mutation Semantics | Proposed |
26
+ | [005](005-scheduler-contract.md) | Scheduler Contract | Proposed |
27
+ | [006](006-context-isolation.md) | Context Isolation Model | Accepted |
28
+ | [007](007-mutation-records.md) | Mutation Records | Accepted |
29
+ | [008](008-transactions.md) | Transactions | Accepted |
30
+ | [009](009-history-model.md) | History Model (Snapshot/Delta) | Proposed |
31
+
32
+ ## Lifecycle
33
+
34
+ New ADRs start as **Proposed**, move to **Accepted** when the decision
35
+ is implemented and tests pass, and become **Superseded** when a later
36
+ ADR supersedes them. A **Deprecated** status marks decisions that are no
37
+ longer relevant but kept for historical context.
38
+
39
+ ## Compliance
40
+
41
+ Every ADR that defines a behavioral contract must have a corresponding
42
+ compliance test suite under `tests/vitest/tests/contracts/`. The test
43
+ file name mirrors the ADR number (e.g. `adr-004-arrays.test.ts`).
44
+
45
+ A release must not be published if any **Accepted** ADR has failing
46
+ compliance tests.
@@ -0,0 +1,48 @@
1
+ # ADR Template - MADR format
2
+
3
+ > **Status:** `{Proposed | Accepted | Superseded by [ADR-XXX](adr-XXX.md) | Deprecated}`
4
+ > **Date:** YYYY-MM-DD
5
+
6
+ ## Context
7
+
8
+ > What is the issue that we were dealing with when we started thinking
9
+ > about it? What are the forces at play? Consider the unique constraints
10
+ > of this project - the need for deterministic, explainable state that
11
+ > remembers, understands, replays, and simulates application state.
12
+
13
+ ## Assumptions
14
+
15
+ > List any assumptions the decision relies on (e.g. "state mutations are
16
+ > synchronous," "the Proxy target is always a plain object or array").
17
+
18
+ ## Decision
19
+
20
+ > What is the change that we will make? Describe the chosen approach in
21
+ > detail. This section must be precise enough to serve as an implementation
22
+ > contract. Include:
23
+ >
24
+ > - The precise semantics (what happens, what does not happen)
25
+ > - Edge cases and error behavior
26
+ > - Performance characteristics
27
+ > - Backward-compatibility implications
28
+
29
+ ## Consequences
30
+
31
+ > What becomes easier or more difficult to do because of this change?
32
+ > Consider:
33
+ >
34
+ > - **Positive** - benefits gained (e.g. improved developer experience,
35
+ > better performance, deterministic behavior)
36
+ > - **Negative** - trade-offs and drawbacks (e.g. loss of flexibility,
37
+ > migration complexity, runtime overhead)
38
+ > - **Testability** - how this decision is covered by compliance tests
39
+
40
+ ## Compliance tests
41
+
42
+ > Reference the test file(s) that verify this contract. Every Accepted
43
+ > ADR must list at least one compliance test file path relative to the
44
+ > repository root.
45
+
46
+ ```
47
+
48
+ File: _ADR_TITLE_PLACEHOLDER.md
package/bin/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import path from 'node:path';
4
+ import fs from 'node:fs';
5
+ import os from 'node:os';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ const args = process.argv.slice(2);
11
+ const command = args[0];
12
+
13
+ if (command === 'install-extension') {
14
+ installExtension();
15
+ } else {
16
+ console.log('Usage: npx memorio install-extension');
17
+ process.exit(command ? 1 : 0);
18
+ }
19
+
20
+ function installExtension() {
21
+ const vsixPath = path.join(__dirname, '..', 'vsix', 'memorio.vsix');
22
+
23
+ if (!fs.existsSync(vsixPath)) {
24
+ console.error(`VSIX file not found at ${vsixPath}.`);
25
+ console.error('The npm package may be corrupted, or the build did not copy the .vsix into vsix/.');
26
+ process.exit(1);
27
+ }
28
+
29
+ const candidates = candidateBinaries();
30
+ const found = candidates.find((bin) => isAvailable(bin));
31
+
32
+ if (!found) {
33
+ console.error('No compatible editor found in PATH (tried: ' + candidates.join(', ') + ').');
34
+ console.error('Manual installation:');
35
+ console.error(' 1. Open your editor (VSCodium/VSCode)');
36
+ console.error(' 2. Command Palette -> "Extensions: Install from VSIX..."');
37
+ console.error(` 3. Select: ${vsixPath}`);
38
+ process.exit(1);
39
+ }
40
+
41
+ console.log(`Editor detected: ${found}. Installing memorio extension...`);
42
+ const result = spawnSync(found, ['--install-extension', vsixPath], {
43
+ stdio: 'inherit',
44
+ shell: os.platform() === 'win32',
45
+ });
46
+
47
+ if (result.status !== 0) {
48
+ console.error('Installation failed. Try manually:');
49
+ console.error(` ${found} --install-extension "${vsixPath}"`);
50
+ process.exit(result.status || 1);
51
+ }
52
+
53
+ console.log('Memorio extension installed successfully.');
54
+ }
55
+
56
+ function candidateBinaries() {
57
+ const names = ['codium', 'vscodium', 'code', 'code-insiders'];
58
+ if (os.platform() === 'win32') {
59
+ return names.map((n) => `${n}.cmd`);
60
+ }
61
+ return names;
62
+ }
63
+
64
+ function isAvailable(bin) {
65
+ const checkCmd = os.platform() === 'win32' ? 'where' : 'which';
66
+ const result = spawnSync(checkCmd, [bin], { stdio: 'ignore', shell: true });
67
+ return result.status === 0;
68
+ }
package/examples/basic.ts CHANGED
@@ -1,115 +1,115 @@
1
- /**
2
- * Memorio Basic Example
3
- *
4
- * This example shows the fundamental features of Memorio:
5
- * - State management
6
- * - Store (localStorage)
7
- * - Session storage
8
- * - Platform detection
9
- *
10
- * Run: npx ts-node examples/basic.ts
11
- */
12
-
13
- import 'memorio'
14
-
15
- // ============================================
16
- // PLATFORM DETECTION
17
- // ============================================
18
-
19
- console.debug('=== Platform Detection ===')
20
- console.debug('Memorio version:', memorio.version)
21
-
22
- // Check platform
23
- if (memorio.isBrowser()) {
24
- console.debug('Platform: Browser')
25
- } else if (memorio.isNode()) {
26
- console.debug('Platform: Node.js')
27
- } else if (memorio.isDeno()) {
28
- console.debug('Platform: Deno')
29
- } else if (memorio.isEdge()) {
30
- console.debug('Platform: Edge Worker')
31
- }
32
-
33
- // Get capabilities
34
- const caps = memorio.getCapabilities()
35
- console.debug('Capabilities:', {
36
- platform: caps.platform,
37
- hasLocalStorage: caps.hasLocalStorage,
38
- hasSessionStorage: caps.hasSessionStorage,
39
- hasIndexedDB: caps.hasIndexedDB
40
- })
41
-
42
- // ============================================
43
- // STATE - In-memory reactive state
44
- // ============================================
45
-
46
- console.debug('\n=== State Management ===')
47
-
48
- // Set some state values
49
- state.name = 'Mario'
50
- state.age = 30
51
- state.isActive = true
52
- state.profile = {
53
- email: 'mario@example.com',
54
- avatar: 'https://example.com/mario.png'
55
- }
56
-
57
- // Get state values
58
- console.debug('Name:', state.name)
59
- console.debug('Age:', state.age)
60
- console.debug('Profile:', state.profile)
61
-
62
- // List all states
63
- console.debug('All states:', state.list)
64
-
65
- // ============================================
66
- // STORE - Persistent localStorage
67
- // ============================================
68
-
69
- console.debug('\n=== Store (Persistent Storage) ===')
70
-
71
- // Check persistence
72
- console.debug('Is persistent:', store.isPersistent) // true in browser, false in Node.js/Deno
73
-
74
- // Save to localStorage
75
- store.set('username', 'mario')
76
- store.set('preferences', { theme: 'dark', language: 'en' })
77
- store.set('lastLogin', Date.now())
78
-
79
- // Read from localStorage
80
- console.debug('Username:', store.get('username'))
81
- console.debug('Preferences:', store.get('preferences'))
82
-
83
- // Get storage size
84
- console.debug('Storage size:', store.size(), 'kilobytes')
85
-
86
- // ============================================
87
- // SESSION - Temporary session storage
88
- // ============================================
89
-
90
- console.debug('\n=== Session (Temporary Storage) ===')
91
-
92
- // Check persistence
93
- console.debug('Is persistent:', session.isPersistent) // true in browser, false in Node.js/Deno
94
-
95
- // Save session data (cleared when tab closes)
96
- session.set('token', 'abc123xyz')
97
- session.set('userId', 42)
98
-
99
- // Read session data
100
- console.debug('Token:', session.get('token'))
101
- console.debug('User ID:', session.get('userId'))
102
-
103
- // ============================================
104
- // CLEANUP
105
- // ============================================
106
-
107
- // Clear specific items
108
- store.remove('username')
109
- session.remove('token')
110
-
111
- // Clear all
112
- store.removeAll()
113
- session.removeAll()
114
-
115
- console.debug('\nExample complete!')
1
+ /**
2
+ * Memorio Basic Example
3
+ *
4
+ * This example shows the fundamental features of Memorio:
5
+ * - State management
6
+ * - Store (localStorage)
7
+ * - Session storage
8
+ * - Platform detection
9
+ *
10
+ * Run: npx ts-node examples/basic.ts
11
+ */
12
+
13
+ import { memorio, state, store, session } from 'memorio'
14
+
15
+ // ============================================
16
+ // PLATFORM DETECTION
17
+ // ============================================
18
+
19
+ console.debug('=== Platform Detection ===')
20
+ console.debug('Memorio version:', memorio.version)
21
+
22
+ // Check platform
23
+ if (memorio.isBrowser()) {
24
+ console.debug('Platform: Browser')
25
+ } else if (memorio.isNode()) {
26
+ console.debug('Platform: Node.js')
27
+ } else if (memorio.isDeno()) {
28
+ console.debug('Platform: Deno')
29
+ } else if (memorio.isEdge()) {
30
+ console.debug('Platform: Edge Worker')
31
+ }
32
+
33
+ // Get capabilities
34
+ const caps = memorio.getCapabilities()
35
+ console.debug('Capabilities:', {
36
+ platform: caps.platform,
37
+ hasLocalStorage: caps.hasLocalStorage,
38
+ hasSessionStorage: caps.hasSessionStorage,
39
+ hasIndexedDB: caps.hasIndexedDB
40
+ })
41
+
42
+ // ============================================
43
+ // STATE - In-memory reactive state
44
+ // ============================================
45
+
46
+ console.debug('\n=== State Management ===')
47
+
48
+ // Set some state values
49
+ state.name = 'Mario'
50
+ state.age = 30
51
+ state.isActive = true
52
+ state.profile = {
53
+ email: 'mario@example.com',
54
+ avatar: 'https://example.com/mario.png'
55
+ }
56
+
57
+ // Get state values
58
+ console.debug('Name:', state.name)
59
+ console.debug('Age:', state.age)
60
+ console.debug('Profile:', state.profile)
61
+
62
+ // List all states
63
+ console.debug('All states:', state.list)
64
+
65
+ // ============================================
66
+ // STORE - Persistent localStorage
67
+ // ============================================
68
+
69
+ console.debug('\n=== Store (Persistent Storage) ===')
70
+
71
+ // Check persistence
72
+ console.debug('Is persistent:', store.isPersistent) // true in browser, false in Node.js/Deno
73
+
74
+ // Save to localStorage
75
+ store.set('username', 'mario')
76
+ store.set('preferences', { theme: 'dark', language: 'en' })
77
+ store.set('lastLogin', Date.now())
78
+
79
+ // Read from localStorage
80
+ console.debug('Username:', store.get('username'))
81
+ console.debug('Preferences:', store.get('preferences'))
82
+
83
+ // Get storage size
84
+ console.debug('Storage size:', store.size(), 'kilobytes')
85
+
86
+ // ============================================
87
+ // SESSION - Temporary session storage
88
+ // ============================================
89
+
90
+ console.debug('\n=== Session (Temporary Storage) ===')
91
+
92
+ // Check persistence
93
+ console.debug('Is persistent:', session.isPersistent) // true in browser, false in Node.js/Deno
94
+
95
+ // Save session data (cleared when tab closes)
96
+ session.set('token', 'abc123xyz')
97
+ session.set('userId', 42)
98
+
99
+ // Read session data
100
+ console.debug('Token:', session.get('token'))
101
+ console.debug('User ID:', session.get('userId'))
102
+
103
+ // ============================================
104
+ // CLEANUP
105
+ // ============================================
106
+
107
+ // Clear specific items
108
+ store.remove('username')
109
+ session.remove('token')
110
+
111
+ // Clear all
112
+ store.removeAll()
113
+ session.removeAll()
114
+
115
+ console.debug('\nExample complete!')