@portel/photon-core 2.19.1 → 2.20.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/dist/index.d.ts CHANGED
@@ -59,7 +59,7 @@ export { getMimeType } from './mime-types.js';
59
59
  export { parseRuntimeRequirement, checkRuntimeCompatibility, } from './version-check.js';
60
60
  export { PhotonError, ValidationError, type ValidationResult, type Validator, combineResults, isString, isNumber, isBoolean, isObject, isArray, notEmpty, hasLength, matchesPattern, isEmail, isUrl, inRange, isPositive, isInteger, hasArrayLength, arrayOf, hasFields, oneOf, validate, validateOrThrow, pathExists, hasExtension, assertDefined, assertString, assertNumber, assertObject, assertArray, } from './validation.js';
61
61
  export { AuditTrail, getAuditTrail, setAuditTrail, generateExecutionId, type ExecutionRecord, type AuditQueryOptions, } from './audit.js';
62
- export { MemoryProvider, type MemoryScope, } from './memory.js';
62
+ export { MemoryProvider, FileMemoryBackend, setDefaultMemoryBackend, getDefaultMemoryBackend, type MemoryBackend, type MemoryScope, } from './memory.js';
63
63
  export { ScheduleProvider, type ScheduleStatus, type ScheduledTask, type CreateScheduleOptions, type UpdateScheduleOptions, } from './schedule.js';
64
64
  export { discoverAssets, autoDiscoverAssets, } from './asset-discovery.js';
65
65
  export { parseDuration, parseRate } from './utils/duration.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -136,7 +136,8 @@ export { PhotonError, ValidationError, combineResults, isString, isNumber, isBoo
136
136
  export { AuditTrail, getAuditTrail, setAuditTrail, generateExecutionId, } from './audit.js';
137
137
  // ===== SCOPED MEMORY =====
138
138
  // Framework-level key-value storage (this.memory on Photon base class)
139
- export { MemoryProvider, } from './memory.js';
139
+ // MemoryBackend is the pluggable interface; FileMemoryBackend is the default.
140
+ export { MemoryProvider, FileMemoryBackend, setDefaultMemoryBackend, getDefaultMemoryBackend, } from './memory.js';
140
141
  // ===== RUNTIME SCHEDULING =====
141
142
  // Programmatic task scheduling (this.schedule on Photon base class)
142
143
  export { ScheduleProvider, } from './schedule.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/memory.d.ts CHANGED
@@ -4,102 +4,91 @@
4
4
  * Framework-level key-value storage for photons that eliminates
5
5
  * boilerplate file I/O. Available as `this.memory` on Photon.
6
6
  *
7
+ * Architecture: MemoryProvider delegates to a pluggable MemoryBackend.
8
+ * The default backend is FileMemoryBackend (JSON files on disk).
9
+ * Enterprise deployments can swap in Redis, Postgres, or SQLite.
10
+ *
7
11
  * Three scopes:
8
- * | Scope | Meaning | Storage |
9
- * |----------|----------------------------------|-----------------------------------------------|
10
- * | photon | Private to this photon (default) | .data/{namespace}/{photonName}/memory/ |
11
- * | session | Per-user session (Beam sessions) | .data/_sessions/{sessionId}/{ns}/{photon}/ |
12
- * | global | Shared across all photons | .data/_global/ |
12
+ * | Scope | Meaning |
13
+ * |----------|----------------------------------|
14
+ * | photon | Private to this photon (default) |
15
+ * | session | Per-user session (Beam sessions) |
16
+ * | global | Shared across all photons |
17
+ */
18
+ export type MemoryScope = 'photon' | 'session' | 'global';
19
+ /**
20
+ * Pluggable storage backend for MemoryProvider.
21
+ *
22
+ * Implementations handle the actual persistence. All methods receive
23
+ * a resolved namespace (scope + photonId + sessionId already baked in)
24
+ * so the backend doesn't need to know about scoping rules.
25
+ */
26
+ export interface MemoryBackend {
27
+ get(namespace: string, key: string): Promise<any | null>;
28
+ set(namespace: string, key: string, value: any): Promise<void>;
29
+ delete(namespace: string, key: string): Promise<boolean>;
30
+ has(namespace: string, key: string): Promise<boolean>;
31
+ keys(namespace: string): Promise<string[]>;
32
+ clear(namespace: string): Promise<void>;
33
+ /**
34
+ * Atomic read-modify-write. Backends with native transactions (Redis WATCH,
35
+ * Postgres FOR UPDATE) should use them here. The default file backend
36
+ * uses a per-key promise chain.
37
+ */
38
+ update(namespace: string, key: string, updater: (current: any | null) => any): Promise<any>;
39
+ }
40
+ /**
41
+ * File-based memory backend. Each key is a JSON file on disk.
42
+ * Uses per-key promise chains and temp+rename for safe concurrent access.
43
+ */
44
+ export declare class FileMemoryBackend implements MemoryBackend {
45
+ private _locks;
46
+ private withLock;
47
+ get(namespace: string, key: string): Promise<any | null>;
48
+ set(namespace: string, key: string, value: any): Promise<void>;
49
+ delete(namespace: string, key: string): Promise<boolean>;
50
+ has(namespace: string, key: string): Promise<boolean>;
51
+ keys(namespace: string): Promise<string[]>;
52
+ clear(namespace: string): Promise<void>;
53
+ update(namespace: string, key: string, updater: (current: any | null) => any): Promise<any>;
54
+ }
55
+ /**
56
+ * Set the global default memory backend.
57
+ * Call before any photons are loaded to switch storage layer.
13
58
  *
14
59
  * @example
15
60
  * ```typescript
16
- * export default class TodoList extends Photon {
17
- * async add({ text }: { text: string }) {
18
- * const items = await this.memory.get<Task[]>('items') ?? [];
19
- * items.push({ id: crypto.randomUUID(), text });
20
- * await this.memory.set('items', items);
21
- * return items;
22
- * }
23
- * }
61
+ * import { setDefaultMemoryBackend } from '@portel/photon-core';
62
+ * import { RedisMemoryBackend } from '@portel/photon-redis';
63
+ * setDefaultMemoryBackend(new RedisMemoryBackend({ url: 'redis://...' }));
24
64
  * ```
25
65
  */
26
- export type MemoryScope = 'photon' | 'session' | 'global';
66
+ export declare function setDefaultMemoryBackend(backend: MemoryBackend): void;
67
+ export declare function getDefaultMemoryBackend(): MemoryBackend;
27
68
  /**
28
69
  * Scoped Memory Provider
29
70
  *
30
- * Provides key-value storage with automatic JSON serialization.
31
- * Each key is stored as a separate file for atomic operations.
71
+ * The public API surface for `this.memory` on photon instances.
72
+ * Delegates all operations to the configured MemoryBackend.
32
73
  */
33
74
  export declare class MemoryProvider {
34
75
  private _photonId;
35
76
  private _namespace;
36
77
  private _sessionId?;
37
78
  private _baseDir?;
38
- constructor(photonId: string, sessionId?: string, namespace?: string, baseDir?: string);
39
- /**
40
- * Current session ID (can be updated by the runtime)
41
- */
79
+ private _backend;
80
+ constructor(photonId: string, sessionId?: string, namespace?: string, baseDir?: string, backend?: MemoryBackend);
42
81
  get sessionId(): string | undefined;
43
82
  set sessionId(id: string | undefined);
44
- /**
45
- * Get a value from memory
46
- *
47
- * @param key The key to retrieve
48
- * @param scope Storage scope (default: 'photon')
49
- * @returns The stored value, or null if not found
50
- */
83
+ /** Resolve the storage namespace (directory for file backend, prefix for Redis, etc.) */
84
+ private ns;
51
85
  get<T = any>(key: string, scope?: MemoryScope): Promise<T | null>;
52
- /**
53
- * Set a value in memory
54
- *
55
- * @param key The key to store
56
- * @param value The value (must be JSON-serializable)
57
- * @param scope Storage scope (default: 'photon')
58
- */
59
86
  set<T = any>(key: string, value: T, scope?: MemoryScope): Promise<void>;
60
- /**
61
- * Delete a key from memory
62
- *
63
- * @param key The key to delete
64
- * @param scope Storage scope (default: 'photon')
65
- * @returns true if the key existed and was deleted
66
- */
67
87
  delete(key: string, scope?: MemoryScope): Promise<boolean>;
68
- /**
69
- * Check if a key exists in memory
70
- *
71
- * @param key The key to check
72
- * @param scope Storage scope (default: 'photon')
73
- */
74
88
  has(key: string, scope?: MemoryScope): Promise<boolean>;
75
- /**
76
- * List all keys in memory for a scope
77
- *
78
- * @param scope Storage scope (default: 'photon')
79
- */
80
89
  keys(scope?: MemoryScope): Promise<string[]>;
81
- /**
82
- * Clear all keys in a scope
83
- *
84
- * @param scope Storage scope (default: 'photon')
85
- */
86
90
  clear(scope?: MemoryScope): Promise<void>;
87
- /**
88
- * Get all key-value pairs in a scope
89
- *
90
- * @param scope Storage scope (default: 'photon')
91
- */
92
91
  getAll<T = any>(scope?: MemoryScope): Promise<Record<string, T>>;
93
- /**
94
- * Update a value with read-modify-write
95
- *
96
- * Note: Not truly atomic under concurrent access. For concurrent
97
- * writes, use distributed locking via `withLock()`.
98
- *
99
- * @param key The key to update
100
- * @param updater Function that receives current value and returns new value
101
- * @param scope Storage scope (default: 'photon')
102
- */
103
92
  update<T = any>(key: string, updater: (current: T | null) => T, scope?: MemoryScope): Promise<T>;
104
93
  }
105
94
  //# sourceMappingURL=memory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAeH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;AAmE1D;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,CAAS;gBAEd,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAOtF;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,IAAI,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAEnC;IAED;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAajF;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAWvF;;;;;;OAMG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;IAa1E;;;;;OAKG;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvE;;;;OAIG;IACG,IAAI,CAAC,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAc5D;;;;OAIG;IACG,KAAK,CAAC,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAazD;;;;OAIG;IACG,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,GAAE,WAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAchF;;;;;;;;;OASG;IACG,MAAM,CAAC,CAAC,GAAG,GAAG,EAClB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,KAAK,CAAC,EACjC,KAAK,GAAE,WAAsB,GAC5B,OAAO,CAAC,CAAC,CAAC;CAMd"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
package/dist/memory.js CHANGED
@@ -4,38 +4,155 @@
4
4
  * Framework-level key-value storage for photons that eliminates
5
5
  * boilerplate file I/O. Available as `this.memory` on Photon.
6
6
  *
7
- * Three scopes:
8
- * | Scope | Meaning | Storage |
9
- * |----------|----------------------------------|-----------------------------------------------|
10
- * | photon | Private to this photon (default) | .data/{namespace}/{photonName}/memory/ |
11
- * | session | Per-user session (Beam sessions) | .data/_sessions/{sessionId}/{ns}/{photon}/ |
12
- * | global | Shared across all photons | .data/_global/ |
7
+ * Architecture: MemoryProvider delegates to a pluggable MemoryBackend.
8
+ * The default backend is FileMemoryBackend (JSON files on disk).
9
+ * Enterprise deployments can swap in Redis, Postgres, or SQLite.
13
10
  *
14
- * @example
15
- * ```typescript
16
- * export default class TodoList extends Photon {
17
- * async add({ text }: { text: string }) {
18
- * const items = await this.memory.get<Task[]>('items') ?? [];
19
- * items.push({ id: crypto.randomUUID(), text });
20
- * await this.memory.set('items', items);
21
- * return items;
22
- * }
23
- * }
24
- * ```
11
+ * Three scopes:
12
+ * | Scope | Meaning |
13
+ * |----------|----------------------------------|
14
+ * | photon | Private to this photon (default) |
15
+ * | session | Per-user session (Beam sessions) |
16
+ * | global | Shared across all photons |
25
17
  */
26
18
  import * as fs from 'fs/promises';
27
19
  import * as fsSync from 'fs';
28
20
  import * as path from 'path';
29
21
  import { getPhotonMemoryDir, getGlobalMemoryDir, getSessionMemoryDir, getLegacyMemoryDir, getLegacyGlobalMemoryDir, getLegacySessionMemoryDir, } from './data-paths.js';
22
+ // ════════════════════════════════════════════════════════════════════════════════
23
+ // FILE BACKEND (default)
24
+ // ════════════════════════════════════════════════════════════════════════════════
25
+ function keyPath(dir, key) {
26
+ const safeKey = key.replace(/[^a-zA-Z0-9_.-]/g, '_');
27
+ return path.join(dir, `${safeKey}.json`);
28
+ }
29
+ async function pathExists(p) {
30
+ try {
31
+ await fs.access(p);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
30
38
  /**
31
- * Resolve storage directory for a given scope.
32
- * Uses new .data/ paths with fallback to legacy locations.
39
+ * File-based memory backend. Each key is a JSON file on disk.
40
+ * Uses per-key promise chains and temp+rename for safe concurrent access.
33
41
  */
42
+ export class FileMemoryBackend {
43
+ _locks = new Map();
44
+ async withLock(namespace, key, fn) {
45
+ const lockKey = `${namespace}:${key}`;
46
+ const prev = this._locks.get(lockKey) ?? Promise.resolve();
47
+ let resolve;
48
+ const next = new Promise(r => { resolve = r; });
49
+ this._locks.set(lockKey, next);
50
+ try {
51
+ await prev;
52
+ return await fn();
53
+ }
54
+ finally {
55
+ resolve();
56
+ if (this._locks.get(lockKey) === next) {
57
+ this._locks.delete(lockKey);
58
+ }
59
+ }
60
+ }
61
+ async get(namespace, key) {
62
+ return this.withLock(namespace, key, async () => {
63
+ const filePath = keyPath(namespace, key);
64
+ try {
65
+ const content = await fs.readFile(filePath, 'utf-8');
66
+ return JSON.parse(content);
67
+ }
68
+ catch (error) {
69
+ if (error.code === 'ENOENT')
70
+ return null;
71
+ throw error;
72
+ }
73
+ });
74
+ }
75
+ async set(namespace, key, value) {
76
+ return this.withLock(namespace, key, async () => {
77
+ if (!await pathExists(namespace)) {
78
+ await fs.mkdir(namespace, { recursive: true });
79
+ }
80
+ const filePath = keyPath(namespace, key);
81
+ const tmpPath = filePath + '.tmp';
82
+ await fs.writeFile(tmpPath, JSON.stringify(value, null, 2));
83
+ await fs.rename(tmpPath, filePath);
84
+ });
85
+ }
86
+ async delete(namespace, key) {
87
+ return this.withLock(namespace, key, async () => {
88
+ const filePath = keyPath(namespace, key);
89
+ try {
90
+ await fs.unlink(filePath);
91
+ return true;
92
+ }
93
+ catch (error) {
94
+ if (error.code === 'ENOENT')
95
+ return false;
96
+ throw error;
97
+ }
98
+ });
99
+ }
100
+ async has(namespace, key) {
101
+ return pathExists(keyPath(namespace, key));
102
+ }
103
+ async keys(namespace) {
104
+ try {
105
+ const files = await fs.readdir(namespace);
106
+ return files.filter(f => f.endsWith('.json') && !f.endsWith('.tmp')).map(f => f.slice(0, -5));
107
+ }
108
+ catch (error) {
109
+ if (error.code === 'ENOENT')
110
+ return [];
111
+ throw error;
112
+ }
113
+ }
114
+ async clear(namespace) {
115
+ try {
116
+ const files = await fs.readdir(namespace);
117
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
118
+ await Promise.all(jsonFiles.map(file => fs.unlink(path.join(namespace, file))));
119
+ }
120
+ catch (error) {
121
+ if (error.code === 'ENOENT')
122
+ return;
123
+ throw error;
124
+ }
125
+ }
126
+ async update(namespace, key, updater) {
127
+ return this.withLock(namespace, key, async () => {
128
+ const filePath = keyPath(namespace, key);
129
+ let current = null;
130
+ try {
131
+ const content = await fs.readFile(filePath, 'utf-8');
132
+ current = JSON.parse(content);
133
+ }
134
+ catch (error) {
135
+ if (error.code !== 'ENOENT')
136
+ throw error;
137
+ }
138
+ const updated = updater(current);
139
+ if (!await pathExists(namespace)) {
140
+ await fs.mkdir(namespace, { recursive: true });
141
+ }
142
+ const tmpPath = filePath + '.tmp';
143
+ await fs.writeFile(tmpPath, JSON.stringify(updated, null, 2));
144
+ await fs.rename(tmpPath, filePath);
145
+ return updated;
146
+ });
147
+ }
148
+ }
149
+ // ════════════════════════════════════════════════════════════════════════════════
150
+ // SCOPE RESOLUTION
151
+ // ════════════════════════════════════════════════════════════════════════════════
34
152
  function resolveDir(photonId, namespace, scope, sessionId, baseDir) {
35
153
  switch (scope) {
36
154
  case 'photon': {
37
155
  const newDir = getPhotonMemoryDir(namespace, photonId, baseDir);
38
- // Fallback: check legacy path if new path has no data yet
39
156
  if (!fsSync.existsSync(newDir)) {
40
157
  const legacyDir = getLegacyMemoryDir(photonId, baseDir);
41
158
  if (fsSync.existsSync(legacyDir))
@@ -68,184 +185,87 @@ function resolveDir(photonId, namespace, scope, sessionId, baseDir) {
68
185
  throw new Error(`Unknown memory scope: ${scope}`);
69
186
  }
70
187
  }
188
+ // ════════════════════════════════════════════════════════════════════════════════
189
+ // MEMORY PROVIDER (public API — delegates to backend)
190
+ // ════════════════════════════════════════════════════════════════════════════════
191
+ /** Default shared backend instance (file-based) */
192
+ let defaultBackend = new FileMemoryBackend();
71
193
  /**
72
- * Get the file path for a key within a directory
194
+ * Set the global default memory backend.
195
+ * Call before any photons are loaded to switch storage layer.
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * import { setDefaultMemoryBackend } from '@portel/photon-core';
200
+ * import { RedisMemoryBackend } from '@portel/photon-redis';
201
+ * setDefaultMemoryBackend(new RedisMemoryBackend({ url: 'redis://...' }));
202
+ * ```
73
203
  */
74
- function keyPath(dir, key) {
75
- const safeKey = key.replace(/[^a-zA-Z0-9_.-]/g, '_');
76
- return path.join(dir, `${safeKey}.json`);
204
+ export function setDefaultMemoryBackend(backend) {
205
+ defaultBackend = backend;
77
206
  }
78
- /**
79
- * Check if a path exists (async)
80
- */
81
- async function pathExists(p) {
82
- try {
83
- await fs.access(p);
84
- return true;
85
- }
86
- catch {
87
- return false;
88
- }
207
+ export function getDefaultMemoryBackend() {
208
+ return defaultBackend;
89
209
  }
90
210
  /**
91
211
  * Scoped Memory Provider
92
212
  *
93
- * Provides key-value storage with automatic JSON serialization.
94
- * Each key is stored as a separate file for atomic operations.
213
+ * The public API surface for `this.memory` on photon instances.
214
+ * Delegates all operations to the configured MemoryBackend.
95
215
  */
96
216
  export class MemoryProvider {
97
217
  _photonId;
98
218
  _namespace;
99
219
  _sessionId;
100
220
  _baseDir;
101
- constructor(photonId, sessionId, namespace, baseDir) {
221
+ _backend;
222
+ constructor(photonId, sessionId, namespace, baseDir, backend) {
102
223
  this._photonId = photonId;
103
224
  this._namespace = namespace || 'local';
104
225
  this._sessionId = sessionId;
105
226
  this._baseDir = baseDir;
227
+ this._backend = backend ?? defaultBackend;
106
228
  }
107
- /**
108
- * Current session ID (can be updated by the runtime)
109
- */
110
229
  get sessionId() {
111
230
  return this._sessionId;
112
231
  }
113
232
  set sessionId(id) {
114
233
  this._sessionId = id;
115
234
  }
116
- /**
117
- * Get a value from memory
118
- *
119
- * @param key The key to retrieve
120
- * @param scope Storage scope (default: 'photon')
121
- * @returns The stored value, or null if not found
122
- */
235
+ /** Resolve the storage namespace (directory for file backend, prefix for Redis, etc.) */
236
+ ns(scope) {
237
+ return resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
238
+ }
123
239
  async get(key, scope = 'photon') {
124
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
125
- const filePath = keyPath(dir, key);
126
- try {
127
- const content = await fs.readFile(filePath, 'utf-8');
128
- return JSON.parse(content);
129
- }
130
- catch (error) {
131
- if (error.code === 'ENOENT')
132
- return null;
133
- throw error;
134
- }
240
+ return this._backend.get(this.ns(scope), key);
135
241
  }
136
- /**
137
- * Set a value in memory
138
- *
139
- * @param key The key to store
140
- * @param value The value (must be JSON-serializable)
141
- * @param scope Storage scope (default: 'photon')
142
- */
143
242
  async set(key, value, scope = 'photon') {
144
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
145
- if (!await pathExists(dir)) {
146
- await fs.mkdir(dir, { recursive: true });
147
- }
148
- const filePath = keyPath(dir, key);
149
- await fs.writeFile(filePath, JSON.stringify(value, null, 2));
150
- }
151
- /**
152
- * Delete a key from memory
153
- *
154
- * @param key The key to delete
155
- * @param scope Storage scope (default: 'photon')
156
- * @returns true if the key existed and was deleted
157
- */
243
+ return this._backend.set(this.ns(scope), key, value);
244
+ }
158
245
  async delete(key, scope = 'photon') {
159
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
160
- const filePath = keyPath(dir, key);
161
- try {
162
- await fs.unlink(filePath);
163
- return true;
164
- }
165
- catch (error) {
166
- if (error.code === 'ENOENT')
167
- return false;
168
- throw error;
169
- }
246
+ return this._backend.delete(this.ns(scope), key);
170
247
  }
171
- /**
172
- * Check if a key exists in memory
173
- *
174
- * @param key The key to check
175
- * @param scope Storage scope (default: 'photon')
176
- */
177
248
  async has(key, scope = 'photon') {
178
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
179
- return pathExists(keyPath(dir, key));
180
- }
181
- /**
182
- * List all keys in memory for a scope
183
- *
184
- * @param scope Storage scope (default: 'photon')
185
- */
249
+ return this._backend.has(this.ns(scope), key);
250
+ }
186
251
  async keys(scope = 'photon') {
187
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
188
- try {
189
- const files = await fs.readdir(dir);
190
- return files
191
- .filter(f => f.endsWith('.json'))
192
- .map(f => f.slice(0, -5));
193
- }
194
- catch (error) {
195
- if (error.code === 'ENOENT')
196
- return [];
197
- throw error;
198
- }
252
+ return this._backend.keys(this.ns(scope));
199
253
  }
200
- /**
201
- * Clear all keys in a scope
202
- *
203
- * @param scope Storage scope (default: 'photon')
204
- */
205
254
  async clear(scope = 'photon') {
206
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
207
- try {
208
- const files = await fs.readdir(dir);
209
- const jsonFiles = files.filter(f => f.endsWith('.json'));
210
- await Promise.all(jsonFiles.map(file => fs.unlink(path.join(dir, file))));
211
- }
212
- catch (error) {
213
- if (error.code === 'ENOENT')
214
- return;
215
- throw error;
216
- }
255
+ return this._backend.clear(this.ns(scope));
217
256
  }
218
- /**
219
- * Get all key-value pairs in a scope
220
- *
221
- * @param scope Storage scope (default: 'photon')
222
- */
223
257
  async getAll(scope = 'photon') {
224
258
  const allKeys = await this.keys(scope);
225
259
  const result = {};
226
260
  for (const key of allKeys) {
227
261
  const value = await this.get(key, scope);
228
- if (value !== null) {
262
+ if (value !== null)
229
263
  result[key] = value;
230
- }
231
264
  }
232
265
  return result;
233
266
  }
234
- /**
235
- * Update a value with read-modify-write
236
- *
237
- * Note: Not truly atomic under concurrent access. For concurrent
238
- * writes, use distributed locking via `withLock()`.
239
- *
240
- * @param key The key to update
241
- * @param updater Function that receives current value and returns new value
242
- * @param scope Storage scope (default: 'photon')
243
- */
244
267
  async update(key, updater, scope = 'photon') {
245
- const current = await this.get(key, scope);
246
- const updated = updater(current);
247
- await this.set(key, updated, scope);
248
- return updated;
268
+ return this._backend.update(this.ns(scope), key, updater);
249
269
  }
250
270
  }
251
271
  //# sourceMappingURL=memory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portel/photon-core",
3
- "version": "2.19.1",
3
+ "version": "2.20.0",
4
4
  "description": "Core library for parsing, loading, and managing .photon.ts files - runtime-agnostic foundation for building custom Photon runtimes",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
package/src/index.ts CHANGED
@@ -443,8 +443,13 @@ export {
443
443
 
444
444
  // ===== SCOPED MEMORY =====
445
445
  // Framework-level key-value storage (this.memory on Photon base class)
446
+ // MemoryBackend is the pluggable interface; FileMemoryBackend is the default.
446
447
  export {
447
448
  MemoryProvider,
449
+ FileMemoryBackend,
450
+ setDefaultMemoryBackend,
451
+ getDefaultMemoryBackend,
452
+ type MemoryBackend,
448
453
  type MemoryScope,
449
454
  } from './memory.js';
450
455
 
package/src/memory.ts CHANGED
@@ -4,24 +4,16 @@
4
4
  * Framework-level key-value storage for photons that eliminates
5
5
  * boilerplate file I/O. Available as `this.memory` on Photon.
6
6
  *
7
- * Three scopes:
8
- * | Scope | Meaning | Storage |
9
- * |----------|----------------------------------|-----------------------------------------------|
10
- * | photon | Private to this photon (default) | .data/{namespace}/{photonName}/memory/ |
11
- * | session | Per-user session (Beam sessions) | .data/_sessions/{sessionId}/{ns}/{photon}/ |
12
- * | global | Shared across all photons | .data/_global/ |
7
+ * Architecture: MemoryProvider delegates to a pluggable MemoryBackend.
8
+ * The default backend is FileMemoryBackend (JSON files on disk).
9
+ * Enterprise deployments can swap in Redis, Postgres, or SQLite.
13
10
  *
14
- * @example
15
- * ```typescript
16
- * export default class TodoList extends Photon {
17
- * async add({ text }: { text: string }) {
18
- * const items = await this.memory.get<Task[]>('items') ?? [];
19
- * items.push({ id: crypto.randomUUID(), text });
20
- * await this.memory.set('items', items);
21
- * return items;
22
- * }
23
- * }
24
- * ```
11
+ * Three scopes:
12
+ * | Scope | Meaning |
13
+ * |----------|----------------------------------|
14
+ * | photon | Private to this photon (default) |
15
+ * | session | Per-user session (Beam sessions) |
16
+ * | global | Shared across all photons |
25
17
  */
26
18
 
27
19
  import * as fs from 'fs/promises';
@@ -39,10 +31,166 @@ import {
39
31
 
40
32
  export type MemoryScope = 'photon' | 'session' | 'global';
41
33
 
34
+ // ════════════════════════════════════════════════════════════════════════════════
35
+ // BACKEND INTERFACE
36
+ // ════════════════════════════════════════════════════════════════════════════════
37
+
38
+ /**
39
+ * Pluggable storage backend for MemoryProvider.
40
+ *
41
+ * Implementations handle the actual persistence. All methods receive
42
+ * a resolved namespace (scope + photonId + sessionId already baked in)
43
+ * so the backend doesn't need to know about scoping rules.
44
+ */
45
+ export interface MemoryBackend {
46
+ get(namespace: string, key: string): Promise<any | null>;
47
+ set(namespace: string, key: string, value: any): Promise<void>;
48
+ delete(namespace: string, key: string): Promise<boolean>;
49
+ has(namespace: string, key: string): Promise<boolean>;
50
+ keys(namespace: string): Promise<string[]>;
51
+ clear(namespace: string): Promise<void>;
52
+ /**
53
+ * Atomic read-modify-write. Backends with native transactions (Redis WATCH,
54
+ * Postgres FOR UPDATE) should use them here. The default file backend
55
+ * uses a per-key promise chain.
56
+ */
57
+ update(namespace: string, key: string, updater: (current: any | null) => any): Promise<any>;
58
+ }
59
+
60
+ // ════════════════════════════════════════════════════════════════════════════════
61
+ // FILE BACKEND (default)
62
+ // ════════════════════════════════════════════════════════════════════════════════
63
+
64
+ function keyPath(dir: string, key: string): string {
65
+ const safeKey = key.replace(/[^a-zA-Z0-9_.-]/g, '_');
66
+ return path.join(dir, `${safeKey}.json`);
67
+ }
68
+
69
+ async function pathExists(p: string): Promise<boolean> {
70
+ try {
71
+ await fs.access(p);
72
+ return true;
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+
42
78
  /**
43
- * Resolve storage directory for a given scope.
44
- * Uses new .data/ paths with fallback to legacy locations.
79
+ * File-based memory backend. Each key is a JSON file on disk.
80
+ * Uses per-key promise chains and temp+rename for safe concurrent access.
45
81
  */
82
+ export class FileMemoryBackend implements MemoryBackend {
83
+ private _locks = new Map<string, Promise<void>>();
84
+
85
+ private async withLock<T>(namespace: string, key: string, fn: () => Promise<T>): Promise<T> {
86
+ const lockKey = `${namespace}:${key}`;
87
+ const prev = this._locks.get(lockKey) ?? Promise.resolve();
88
+ let resolve!: () => void;
89
+ const next = new Promise<void>(r => { resolve = r; });
90
+ this._locks.set(lockKey, next);
91
+ try {
92
+ await prev;
93
+ return await fn();
94
+ } finally {
95
+ resolve();
96
+ if (this._locks.get(lockKey) === next) {
97
+ this._locks.delete(lockKey);
98
+ }
99
+ }
100
+ }
101
+
102
+ async get(namespace: string, key: string): Promise<any | null> {
103
+ return this.withLock(namespace, key, async () => {
104
+ const filePath = keyPath(namespace, key);
105
+ try {
106
+ const content = await fs.readFile(filePath, 'utf-8');
107
+ return JSON.parse(content);
108
+ } catch (error: any) {
109
+ if (error.code === 'ENOENT') return null;
110
+ throw error;
111
+ }
112
+ });
113
+ }
114
+
115
+ async set(namespace: string, key: string, value: any): Promise<void> {
116
+ return this.withLock(namespace, key, async () => {
117
+ if (!await pathExists(namespace)) {
118
+ await fs.mkdir(namespace, { recursive: true });
119
+ }
120
+ const filePath = keyPath(namespace, key);
121
+ const tmpPath = filePath + '.tmp';
122
+ await fs.writeFile(tmpPath, JSON.stringify(value, null, 2));
123
+ await fs.rename(tmpPath, filePath);
124
+ });
125
+ }
126
+
127
+ async delete(namespace: string, key: string): Promise<boolean> {
128
+ return this.withLock(namespace, key, async () => {
129
+ const filePath = keyPath(namespace, key);
130
+ try {
131
+ await fs.unlink(filePath);
132
+ return true;
133
+ } catch (error: any) {
134
+ if (error.code === 'ENOENT') return false;
135
+ throw error;
136
+ }
137
+ });
138
+ }
139
+
140
+ async has(namespace: string, key: string): Promise<boolean> {
141
+ return pathExists(keyPath(namespace, key));
142
+ }
143
+
144
+ async keys(namespace: string): Promise<string[]> {
145
+ try {
146
+ const files = await fs.readdir(namespace);
147
+ return files.filter(f => f.endsWith('.json') && !f.endsWith('.tmp')).map(f => f.slice(0, -5));
148
+ } catch (error: any) {
149
+ if (error.code === 'ENOENT') return [];
150
+ throw error;
151
+ }
152
+ }
153
+
154
+ async clear(namespace: string): Promise<void> {
155
+ try {
156
+ const files = await fs.readdir(namespace);
157
+ const jsonFiles = files.filter(f => f.endsWith('.json'));
158
+ await Promise.all(jsonFiles.map(file => fs.unlink(path.join(namespace, file))));
159
+ } catch (error: any) {
160
+ if (error.code === 'ENOENT') return;
161
+ throw error;
162
+ }
163
+ }
164
+
165
+ async update(namespace: string, key: string, updater: (current: any | null) => any): Promise<any> {
166
+ return this.withLock(namespace, key, async () => {
167
+ const filePath = keyPath(namespace, key);
168
+
169
+ let current: any = null;
170
+ try {
171
+ const content = await fs.readFile(filePath, 'utf-8');
172
+ current = JSON.parse(content);
173
+ } catch (error: any) {
174
+ if (error.code !== 'ENOENT') throw error;
175
+ }
176
+
177
+ const updated = updater(current);
178
+
179
+ if (!await pathExists(namespace)) {
180
+ await fs.mkdir(namespace, { recursive: true });
181
+ }
182
+ const tmpPath = filePath + '.tmp';
183
+ await fs.writeFile(tmpPath, JSON.stringify(updated, null, 2));
184
+ await fs.rename(tmpPath, filePath);
185
+ return updated;
186
+ });
187
+ }
188
+ }
189
+
190
+ // ════════════════════════════════════════════════════════════════════════════════
191
+ // SCOPE RESOLUTION
192
+ // ════════════════════════════════════════════════════════════════════════════════
193
+
46
194
  function resolveDir(
47
195
  photonId: string,
48
196
  namespace: string,
@@ -53,7 +201,6 @@ function resolveDir(
53
201
  switch (scope) {
54
202
  case 'photon': {
55
203
  const newDir = getPhotonMemoryDir(namespace, photonId, baseDir);
56
- // Fallback: check legacy path if new path has no data yet
57
204
  if (!fsSync.existsSync(newDir)) {
58
205
  const legacyDir = getLegacyMemoryDir(photonId, baseDir);
59
206
  if (fsSync.existsSync(legacyDir)) return legacyDir;
@@ -84,48 +231,59 @@ function resolveDir(
84
231
  }
85
232
  }
86
233
 
234
+ // ════════════════════════════════════════════════════════════════════════════════
235
+ // MEMORY PROVIDER (public API — delegates to backend)
236
+ // ════════════════════════════════════════════════════════════════════════════════
237
+
238
+ /** Default shared backend instance (file-based) */
239
+ let defaultBackend: MemoryBackend = new FileMemoryBackend();
240
+
87
241
  /**
88
- * Get the file path for a key within a directory
242
+ * Set the global default memory backend.
243
+ * Call before any photons are loaded to switch storage layer.
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * import { setDefaultMemoryBackend } from '@portel/photon-core';
248
+ * import { RedisMemoryBackend } from '@portel/photon-redis';
249
+ * setDefaultMemoryBackend(new RedisMemoryBackend({ url: 'redis://...' }));
250
+ * ```
89
251
  */
90
- function keyPath(dir: string, key: string): string {
91
- const safeKey = key.replace(/[^a-zA-Z0-9_.-]/g, '_');
92
- return path.join(dir, `${safeKey}.json`);
252
+ export function setDefaultMemoryBackend(backend: MemoryBackend): void {
253
+ defaultBackend = backend;
93
254
  }
94
255
 
95
- /**
96
- * Check if a path exists (async)
97
- */
98
- async function pathExists(p: string): Promise<boolean> {
99
- try {
100
- await fs.access(p);
101
- return true;
102
- } catch {
103
- return false;
104
- }
256
+ export function getDefaultMemoryBackend(): MemoryBackend {
257
+ return defaultBackend;
105
258
  }
106
259
 
107
260
  /**
108
261
  * Scoped Memory Provider
109
262
  *
110
- * Provides key-value storage with automatic JSON serialization.
111
- * Each key is stored as a separate file for atomic operations.
263
+ * The public API surface for `this.memory` on photon instances.
264
+ * Delegates all operations to the configured MemoryBackend.
112
265
  */
113
266
  export class MemoryProvider {
114
267
  private _photonId: string;
115
268
  private _namespace: string;
116
269
  private _sessionId?: string;
117
270
  private _baseDir?: string;
271
+ private _backend: MemoryBackend;
118
272
 
119
- constructor(photonId: string, sessionId?: string, namespace?: string, baseDir?: string) {
273
+ constructor(
274
+ photonId: string,
275
+ sessionId?: string,
276
+ namespace?: string,
277
+ baseDir?: string,
278
+ backend?: MemoryBackend
279
+ ) {
120
280
  this._photonId = photonId;
121
281
  this._namespace = namespace || 'local';
122
282
  this._sessionId = sessionId;
123
283
  this._baseDir = baseDir;
284
+ this._backend = backend ?? defaultBackend;
124
285
  }
125
286
 
126
- /**
127
- * Current session ID (can be updated by the runtime)
128
- */
129
287
  get sessionId(): string | undefined {
130
288
  return this._sessionId;
131
289
  }
@@ -134,149 +292,50 @@ export class MemoryProvider {
134
292
  this._sessionId = id;
135
293
  }
136
294
 
137
- /**
138
- * Get a value from memory
139
- *
140
- * @param key The key to retrieve
141
- * @param scope Storage scope (default: 'photon')
142
- * @returns The stored value, or null if not found
143
- */
144
- async get<T = any>(key: string, scope: MemoryScope = 'photon'): Promise<T | null> {
145
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
146
- const filePath = keyPath(dir, key);
295
+ /** Resolve the storage namespace (directory for file backend, prefix for Redis, etc.) */
296
+ private ns(scope: MemoryScope): string {
297
+ return resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
298
+ }
147
299
 
148
- try {
149
- const content = await fs.readFile(filePath, 'utf-8');
150
- return JSON.parse(content) as T;
151
- } catch (error: any) {
152
- if (error.code === 'ENOENT') return null;
153
- throw error;
154
- }
300
+ async get<T = any>(key: string, scope: MemoryScope = 'photon'): Promise<T | null> {
301
+ return this._backend.get(this.ns(scope), key);
155
302
  }
156
303
 
157
- /**
158
- * Set a value in memory
159
- *
160
- * @param key The key to store
161
- * @param value The value (must be JSON-serializable)
162
- * @param scope Storage scope (default: 'photon')
163
- */
164
304
  async set<T = any>(key: string, value: T, scope: MemoryScope = 'photon'): Promise<void> {
165
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
166
-
167
- if (!await pathExists(dir)) {
168
- await fs.mkdir(dir, { recursive: true });
169
- }
170
-
171
- const filePath = keyPath(dir, key);
172
- await fs.writeFile(filePath, JSON.stringify(value, null, 2));
305
+ return this._backend.set(this.ns(scope), key, value);
173
306
  }
174
307
 
175
- /**
176
- * Delete a key from memory
177
- *
178
- * @param key The key to delete
179
- * @param scope Storage scope (default: 'photon')
180
- * @returns true if the key existed and was deleted
181
- */
182
308
  async delete(key: string, scope: MemoryScope = 'photon'): Promise<boolean> {
183
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
184
- const filePath = keyPath(dir, key);
185
-
186
- try {
187
- await fs.unlink(filePath);
188
- return true;
189
- } catch (error: any) {
190
- if (error.code === 'ENOENT') return false;
191
- throw error;
192
- }
309
+ return this._backend.delete(this.ns(scope), key);
193
310
  }
194
311
 
195
- /**
196
- * Check if a key exists in memory
197
- *
198
- * @param key The key to check
199
- * @param scope Storage scope (default: 'photon')
200
- */
201
312
  async has(key: string, scope: MemoryScope = 'photon'): Promise<boolean> {
202
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
203
- return pathExists(keyPath(dir, key));
313
+ return this._backend.has(this.ns(scope), key);
204
314
  }
205
315
 
206
- /**
207
- * List all keys in memory for a scope
208
- *
209
- * @param scope Storage scope (default: 'photon')
210
- */
211
316
  async keys(scope: MemoryScope = 'photon'): Promise<string[]> {
212
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
213
-
214
- try {
215
- const files = await fs.readdir(dir);
216
- return files
217
- .filter(f => f.endsWith('.json'))
218
- .map(f => f.slice(0, -5));
219
- } catch (error: any) {
220
- if (error.code === 'ENOENT') return [];
221
- throw error;
222
- }
317
+ return this._backend.keys(this.ns(scope));
223
318
  }
224
319
 
225
- /**
226
- * Clear all keys in a scope
227
- *
228
- * @param scope Storage scope (default: 'photon')
229
- */
230
320
  async clear(scope: MemoryScope = 'photon'): Promise<void> {
231
- const dir = resolveDir(this._photonId, this._namespace, scope, this._sessionId, this._baseDir);
232
-
233
- try {
234
- const files = await fs.readdir(dir);
235
- const jsonFiles = files.filter(f => f.endsWith('.json'));
236
- await Promise.all(jsonFiles.map(file => fs.unlink(path.join(dir, file))));
237
- } catch (error: any) {
238
- if (error.code === 'ENOENT') return;
239
- throw error;
240
- }
321
+ return this._backend.clear(this.ns(scope));
241
322
  }
242
323
 
243
- /**
244
- * Get all key-value pairs in a scope
245
- *
246
- * @param scope Storage scope (default: 'photon')
247
- */
248
324
  async getAll<T = any>(scope: MemoryScope = 'photon'): Promise<Record<string, T>> {
249
325
  const allKeys = await this.keys(scope);
250
326
  const result: Record<string, T> = {};
251
-
252
327
  for (const key of allKeys) {
253
328
  const value = await this.get<T>(key, scope);
254
- if (value !== null) {
255
- result[key] = value;
256
- }
329
+ if (value !== null) result[key] = value;
257
330
  }
258
-
259
331
  return result;
260
332
  }
261
333
 
262
- /**
263
- * Update a value with read-modify-write
264
- *
265
- * Note: Not truly atomic under concurrent access. For concurrent
266
- * writes, use distributed locking via `withLock()`.
267
- *
268
- * @param key The key to update
269
- * @param updater Function that receives current value and returns new value
270
- * @param scope Storage scope (default: 'photon')
271
- */
272
334
  async update<T = any>(
273
335
  key: string,
274
336
  updater: (current: T | null) => T,
275
337
  scope: MemoryScope = 'photon'
276
338
  ): Promise<T> {
277
- const current = await this.get<T>(key, scope);
278
- const updated = updater(current);
279
- await this.set(key, updated, scope);
280
- return updated;
339
+ return this._backend.update(this.ns(scope), key, updater);
281
340
  }
282
341
  }