memorio 4.7.1 → 4.7.3

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.
@@ -0,0 +1,158 @@
1
+ # Typed Stores - Memorio
2
+
3
+ > ✅ **Universal**: Works in Browser, Node.js, Deno, and Edge Workers
4
+
5
+ `memorio.typed<T>()` returns the global `state` proxy cast to a TypeScript type `T`, giving you **compile-time** type safety on every access and mutation.
6
+
7
+ It's a **zero-runtime-cost** wrapper: the returned object is the *exact same* Proxy as `globalThis.state`, just with TypeScript types applied via a generic.
8
+
9
+ ---
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import 'memorio'
15
+
16
+ interface AppState {
17
+ user: { name: string; age: number; email: string }
18
+ theme: 'light' | 'dark'
19
+ items: string[]
20
+ }
21
+
22
+ const app = memorio.typed<AppState>()
23
+
24
+ // Type-checked at compile time:
25
+ app.user = { name: 'Sara', age: 30, email: 'sara@test.com' }
26
+ app.theme = 'dark'
27
+
28
+ // TypeScript errors:
29
+ // app.user = { name: 42 } // age missing, name wrong type
30
+ // app.theme = 'purple' // not a valid literal
31
+ ```
32
+
33
+ ---
34
+
35
+ ## Why use typed stores?
36
+
37
+ | Without typed | With `memorio.typed<T>()` |
38
+ |---|---|
39
+ | `state.user = { name: 42 }` — runs silently, bug at runtime | `app.user = { name: 42 }` — TypeScript error at compile time |
40
+ | No autocomplete on `state.user.email` | Full IntelliSense: properties, types, method suggestions |
41
+ | Rename `user` to `profile` — no compiler warning anywhere | Every `app.user` access flagged as an error |
42
+ | AI-generated code lacks guardrails | AI gets autocomplete and type feedback inline |
43
+
44
+ ---
45
+
46
+ ## Combine with Schema Validation
47
+
48
+ Typed stores catch type errors at compile time; schema validation catches invalid values at runtime. Together they form a **defense-in-depth** strategy:
49
+
50
+ ```typescript
51
+ import 'memorio'
52
+
53
+ interface ProfileState {
54
+ profile: { bio: string; avatar?: string }
55
+ }
56
+
57
+ const app = memorio.typed<ProfileState>()
58
+
59
+ memorio.registerSchema('profile', {
60
+ type: 'object',
61
+ required: ['bio'],
62
+ properties: {
63
+ bio: { type: 'string', min: 1 },
64
+ avatar: { type: 'string' }
65
+ }
66
+ })
67
+
68
+ app.profile = { bio: 'Developer', avatar: 'pic.png' } // ✅ type + schema pass
69
+ app.profile = { avatar: 'pic.png' } // ❌ TypeScript: bio missing
70
+ // ❌ Runtime: bio required
71
+ ```
72
+
73
+ See [Schema Validation](SCHEMA.md) for runtime validation details.
74
+
75
+ ---
76
+
77
+ ## Named import variant
78
+
79
+ `typed` is also available as a named export if you prefer explicit dependencies:
80
+
81
+ ```typescript
82
+ import { typed } from 'memorio'
83
+
84
+ const app = typed<AppState>()
85
+ ```
86
+
87
+ The `memorio` namespace object is the same — `import 'memorio'` is the recommended entry, named exports are an alternative.
88
+
89
+ ---
90
+
91
+ ## Full API
92
+
93
+ | Method | Parameters | Returns | Description |
94
+ |--------|-----------|---------|-------------|
95
+ | `memorio.typed<T>()` | Generic type `T` | `T` | Returns the global `state` proxy cast to `T` |
96
+
97
+ The returned object shares the same identity as `globalThis.state`:
98
+
99
+ ```typescript
100
+ const app = memorio.typed<AppState>()
101
+ console.debug(app === state) // true — same Proxy instance
102
+ ```
103
+
104
+ ---
105
+
106
+ ## React + typed stores
107
+
108
+ Pair with the `useObserver` hook for type-safe, reactive React components:
109
+
110
+ ```tsx
111
+ import 'memorio'
112
+ import { useReducer } from 'react'
113
+
114
+ interface AppState {
115
+ user: { name: string; age: number }
116
+ theme: 'light' | 'dark'
117
+ }
118
+
119
+ const app = memorio.typed<AppState>()
120
+
121
+ function UserProfile() {
122
+ const [, forceUpdate] = useReducer(x => x + 1, 0)
123
+
124
+ useObserver(forceUpdate, [state.user.name])
125
+
126
+ return (
127
+ <div>
128
+ <h1>{app.user.name}</h1>
129
+ <span>Theme: {app.theme}</span>
130
+ </div>
131
+ )
132
+ }
133
+ ```
134
+
135
+ ---
136
+
137
+ ## Best Practices
138
+
139
+ 1. **Define your AppState at the root** of your app and import it everywhere:
140
+
141
+ ```typescript
142
+ // types/app-state.ts
143
+ export interface AppState {
144
+ user: { name: string; email: string }
145
+ theme: 'light' | 'dark'
146
+ }
147
+ ```
148
+
149
+ ```typescript
150
+ // anywhere in your app
151
+ import 'memorio'
152
+ import type { AppState } from '../types/app-state'
153
+ const app = memorio.typed<AppState>()
154
+ ```
155
+
156
+ 2. **Layer schema validation on top** for runtime safety, especially for data coming from APIs or user input.
157
+
158
+ 3. **Use alongside `memorio.help()`** to list available globals during development.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "memorio",
3
3
  "codeName": "memorio",
4
- "version": "4.7.1",
4
+ "version": "4.7.3",
5
5
  "description": "Memorio, State + Observer, Store and iDB for an easy life - Cross-platform compatible",
6
6
  "main": "./index.cjs",
7
7
  "browser": "./index.js",
@@ -52,15 +52,15 @@
52
52
  "markdown/**/*",
53
53
  "types/**/*",
54
54
  "COPYRIGHT.md",
55
- "index.d.ts",
56
- "index.cjs",
57
- "index.js",
58
- "LICENSE.md",
59
- "llms.txt",
60
55
  "README.md",
61
56
  "FUNDING.yml",
62
57
  "SECURITY.md",
63
- "SUMMARY.md"
58
+ "SUMMARY.md",
59
+ "LICENSE.md",
60
+ "index.d.ts",
61
+ "index.cjs",
62
+ "index.js",
63
+ "llms.txt"
64
64
  ],
65
65
  "publishConfig": {
66
66
  "access": "public"
@@ -8,6 +8,9 @@
8
8
  * @see index.ts (runtime re-export)
9
9
  */
10
10
 
11
+ /// <reference path="./schema.d.ts" />
12
+ /// <reference path="./history.d.ts" />
13
+ /// <reference path="./inspect.d.ts" />
11
14
  /// <reference path="./memorio.d.ts" />
12
15
  /// <reference path="./state.d.ts" />
13
16
  /// <reference path="./store.d.ts" />
@@ -40,6 +43,28 @@ export const isolate: _memorio['isolate']
40
43
  export const message: (...args: unknown[]) => void
41
44
  export const help: () => void
42
45
 
46
+ export const registerSchema: (path: string, schema: any) => void
47
+ export const validate: (path: string, value: any) => { valid: boolean; errors?: string[] }
48
+ export const unregisterSchema: (path: string) => boolean
49
+ export const listSchemas: () => string[]
50
+ export const typed: <T extends Record<string, any>>() => T
51
+ export const snapshot: () => Record<string, any>
52
+ export const diff: (snap: Record<string, any>) => Array<{ path: string; oldValue: any; newValue: any }>
53
+ export const undo: () => any
54
+ export const redo: () => any
55
+ export const canUndo: () => boolean
56
+ export const canRedo: () => boolean
57
+ export const rollback: (snap: Record<string, any>) => void
58
+ export const trace: () => any[]
59
+ export const enableHistory: (enabled?: boolean) => void
60
+ export const clearHistory: () => void
61
+ export const clearRedo: () => void
62
+ export const stateKeys: () => string[]
63
+ export const pathExists: (path: string) => boolean
64
+ export const stateType: (path: string) => string
65
+ export const stateGet: (path: string) => any
66
+ export const stateSchema: () => Array<{ path: string; type: string; defined: boolean }>
67
+
43
68
  export const propertyName: (container: any, object: any) => string | null
44
69
  export const internal: {
45
70
  debug: boolean
@@ -0,0 +1,27 @@
1
+ /// MEMORIO HISTORY TYPES
2
+ /// Ambient declarations for the snapshot / undo / redo / trace API.
3
+
4
+ ///
5
+ // A single recorded state mutation.
6
+ ///
7
+ interface _mutationRecord {
8
+ /** Dotted state path (e.g. 'user.name'). */
9
+ path: string
10
+ /** 'set' or 'delete'. */
11
+ action: 'set' | 'delete'
12
+ /** The new value written (for 'set'), undefined for 'delete'. */
13
+ newValue: any
14
+ /** The previous value before the mutation. */
15
+ previousValue: any
16
+ /** Epoch timestamp (ms) when the mutation occurred. */
17
+ timestamp: number
18
+ }
19
+
20
+ ///
21
+ // Result of diffing a snapshot against current state.
22
+ ///
23
+ interface _diffEntry {
24
+ path: string
25
+ oldValue: any
26
+ newValue: any
27
+ }
@@ -0,0 +1,14 @@
1
+ /// MEMORIO INSPECT TYPES
2
+ /// Ambient declarations for the state introspection API.
3
+
4
+ ///
5
+ // Schema report entry describing a single state path.
6
+ ///
7
+ interface _stateSchemaEntry {
8
+ /** Dotted path relative to `state`. */
9
+ path: string
10
+ /** Runtime type: 'string', 'number', 'boolean', 'object', 'array', 'undefined'. */
11
+ type: string
12
+ /** Whether the path resolves to a defined value. */
13
+ defined: boolean
14
+ }
@@ -1,3 +1,12 @@
1
+ import type {
2
+ MemoryEntry,
3
+ RememberOptions,
4
+ RecallOptions,
5
+ ContextOptions,
6
+ ContextEntry,
7
+ MemoryStats
8
+ } from './memory'
9
+
1
10
  /**
2
11
  * Environment capabilities
3
12
  */
@@ -60,10 +69,47 @@ interface _memorio {
60
69
  session: any
61
70
  cache: any
62
71
  }
63
- help?: () => void
72
+ help?: () => void
73
+ // Schema validation
74
+ registerSchema?: (path: string, schema: any) => void
75
+ validate?: (path: string, value: any) => { valid: boolean; errors?: string[] }
76
+ unregisterSchema?: (path: string) => boolean
77
+ listSchemas?: () => string[]
78
+ // Typed store
79
+ typed?: <T extends Record<string, any>>() => T
80
+ // History / snapshot / undo / redo / trace
81
+ snapshot?: () => Record<string, any>
82
+ diff?: (snap: Record<string, any>) => Array<{ path: string; oldValue: any; newValue: any }>
83
+ undo?: () => _mutationRecord | undefined
84
+ redo?: () => _mutationRecord | undefined
85
+ canUndo?: () => boolean
86
+ canRedo?: () => boolean
87
+ rollback?: (snap: Record<string, any>) => void
88
+ trace?: () => _mutationRecord[]
89
+ enableHistory?: (enabled?: boolean) => void
90
+ clearHistory?: () => void
91
+ clearRedo?: () => void
92
+ // Introspection
93
+ stateKeys?: () => string[]
94
+ pathExists?: (path: string) => boolean
95
+ stateType?: (path: string) => string
96
+ stateGet?: (path: string) => any
97
+ stateSchema?: () => Array<{ path: string; type: string; defined: boolean }>
98
+ memory?: MemoryAPI
99
+ }
100
+
101
+ interface MemoryAPI {
102
+ remember<T>(key: string, value: T, opts?: RememberOptions<T>): Promise<void>
103
+ recall<T>(query: string, opts?: RecallOptions): Promise<T | null>
104
+ update(key: string, value: any, opts?: Partial<RememberOptions>): Promise<void>
105
+ forget(key: string): Promise<void>
106
+ context(opts?: ContextOptions): Promise<ContextEntry[]>
107
+ stats(): Promise<MemoryStats>
108
+ forgetExpired(): Promise<number>
109
+ clear(): Promise<void>
64
110
  }
65
111
 
66
- type memorio = _memorio
112
+ type memorio = _memorio
67
113
  declare var memorio: _memorio
68
114
 
69
115
  interface GlobalMemorio {
@@ -0,0 +1,70 @@
1
+ export type MemoryScope = 'hot' | 'session' | 'local' | 'durable'
2
+
3
+ export type MemoryType =
4
+ | 'fact'
5
+ | 'preference'
6
+ | 'decision'
7
+ | 'task'
8
+ | 'context'
9
+
10
+ export type MemoryStatus = 'active' | 'obsolete' | 'superseded'
11
+
12
+ export interface MemoryEntry<T = any> {
13
+ id: string
14
+ key: string
15
+ value: T
16
+ type: MemoryType
17
+ confidence: number
18
+ scope: MemoryScope
19
+ ttl?: number | null
20
+ tags: string[]
21
+ source?: string
22
+ status: MemoryStatus
23
+ createdAt: number
24
+ lastConfirmedAt: number
25
+ supersededId?: string | null
26
+ }
27
+
28
+ export interface RememberOptions<T = any> {
29
+ id?: string
30
+ type?: MemoryType
31
+ confidence?: number
32
+ scope?: MemoryScope
33
+ ttl?: number | null
34
+ tags?: string | string[]
35
+ source?: string
36
+ }
37
+
38
+ export interface RecallOptions {
39
+ type?: MemoryType | MemoryType[]
40
+ tags?: string | string[]
41
+ minConfidence?: number
42
+ includeObsolete?: boolean
43
+ }
44
+
45
+ export interface ContextOptions {
46
+ tags?: string | string[]
47
+ types?: MemoryType | MemoryType[]
48
+ minConfidence?: number
49
+ maxEntries?: number
50
+ scopes?: MemoryScope[]
51
+ }
52
+
53
+ export interface ContextEntry {
54
+ key: string
55
+ value: any
56
+ type: MemoryType
57
+ confidence: number
58
+ scope: MemoryScope
59
+ tags: string[]
60
+ age: number
61
+ accessCount: number
62
+ lastAccessedAt: number
63
+ }
64
+
65
+ export interface MemoryStats {
66
+ total: number
67
+ byScope: Record<MemoryScope, number>
68
+ byType: Partial<Record<MemoryType, number>>
69
+ expired: number
70
+ }
@@ -0,0 +1,53 @@
1
+ /// MEMORIO SCHEMA TYPES
2
+ /// Ambient declarations for the schema validation system.
3
+
4
+ ///
5
+ // Schema type — describes the expected runtime shape of a value.
6
+ ///
7
+ interface _schemaDef {
8
+ /** Expected runtime type of the value. */
9
+ type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any'
10
+ /** Required property names when type is 'object'. */
11
+ required?: string[]
12
+ /** Nested property schemas (validated recursively). */
13
+ properties?: Record<string, _schemaDef>
14
+ /** Minimum: value for numbers, length for strings. */
15
+ min?: number
16
+ /** Maximum: value for numbers, length for strings. */
17
+ max?: number
18
+ /** Regex pattern a string value must match. */
19
+ pattern?: RegExp
20
+ /** Whitelist of allowed values. */
21
+ enum?: any[]
22
+ /** Custom validator: return true for pass, or a string describing the error. */
23
+ validator?: (value: any) => boolean | string
24
+ }
25
+
26
+ ///
27
+ // Result of a validation check.
28
+ ///
29
+ interface _validationResult {
30
+ /** Whether the value passed all checks. */
31
+ valid: boolean
32
+ /** Array of human-readable error strings (present when valid is false). */
33
+ errors?: string[]
34
+ }
35
+
36
+ ///
37
+ // Schema namespace — the public `memorio.schema`-style helpers live on `memorio`.
38
+ ///
39
+ interface _schemaHelpers {
40
+ /** Registers a schema (or custom validator) for a state path. */
41
+ register: (path: string, schema: _schemaDef | ((value: any) => boolean | string)) => void
42
+ /** Validates a value against a registered schema. */
43
+ validate: (path: string, value: any) => _validationResult
44
+ /** Removes a previously registered schema. */
45
+ unregister: (path: string) => boolean
46
+ /** Lists all registered schema paths. */
47
+ list: () => string[]
48
+ /** Retrieves the schema registered for a path. */
49
+ get: (path: string) => _schemaDef | undefined
50
+ }
51
+
52
+ declare var _schemaDef: _schemaDef
53
+ declare var _validationResult: _validationResult