@objectstack/driver-memory 3.0.10 → 3.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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +16 -0
- package/dist/index.d.mts +151 -1
- package/dist/index.d.ts +151 -1
- package/dist/index.js +337 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +332 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +4 -1
- package/src/memory-driver.test.ts +1 -1
- package/src/memory-driver.ts +229 -0
- package/src/persistence/file-adapter.ts +103 -0
- package/src/persistence/index.ts +4 -0
- package/src/persistence/local-storage-adapter.ts +60 -0
- package/src/persistence/persistence.test.ts +298 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
8
13
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -15,12 +20,169 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
33
|
+
// src/persistence/local-storage-adapter.ts
|
|
34
|
+
var local_storage_adapter_exports = {};
|
|
35
|
+
__export(local_storage_adapter_exports, {
|
|
36
|
+
LocalStoragePersistenceAdapter: () => LocalStoragePersistenceAdapter
|
|
37
|
+
});
|
|
38
|
+
var _LocalStoragePersistenceAdapter, LocalStoragePersistenceAdapter;
|
|
39
|
+
var init_local_storage_adapter = __esm({
|
|
40
|
+
"src/persistence/local-storage-adapter.ts"() {
|
|
41
|
+
"use strict";
|
|
42
|
+
_LocalStoragePersistenceAdapter = class _LocalStoragePersistenceAdapter {
|
|
43
|
+
// 4.5MB warning threshold
|
|
44
|
+
constructor(options) {
|
|
45
|
+
this.storageKey = options?.key || "objectstack:memory-db";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Load persisted data from localStorage.
|
|
49
|
+
* Returns null if no data exists.
|
|
50
|
+
*/
|
|
51
|
+
async load() {
|
|
52
|
+
try {
|
|
53
|
+
const raw = localStorage.getItem(this.storageKey);
|
|
54
|
+
if (!raw) return null;
|
|
55
|
+
return JSON.parse(raw);
|
|
56
|
+
} catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Save data to localStorage.
|
|
62
|
+
* Warns if data size approaches the ~5MB localStorage limit.
|
|
63
|
+
*/
|
|
64
|
+
async save(db) {
|
|
65
|
+
const json = JSON.stringify(db);
|
|
66
|
+
if (json.length > _LocalStoragePersistenceAdapter.SIZE_WARNING_BYTES) {
|
|
67
|
+
console.warn(
|
|
68
|
+
`[ObjectStack] localStorage persistence data size (${(json.length / 1024 / 1024).toFixed(2)}MB) is approaching the ~5MB limit. Consider using a different persistence strategy.`
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
localStorage.setItem(this.storageKey, json);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error("[ObjectStack] Failed to persist data to localStorage:", e?.message || e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Flush is a no-op for localStorage (writes are synchronous).
|
|
79
|
+
*/
|
|
80
|
+
async flush() {
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
_LocalStoragePersistenceAdapter.SIZE_WARNING_BYTES = 4.5 * 1024 * 1024;
|
|
84
|
+
LocalStoragePersistenceAdapter = _LocalStoragePersistenceAdapter;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// src/persistence/file-adapter.ts
|
|
89
|
+
var file_adapter_exports = {};
|
|
90
|
+
__export(file_adapter_exports, {
|
|
91
|
+
FileSystemPersistenceAdapter: () => FileSystemPersistenceAdapter
|
|
92
|
+
});
|
|
93
|
+
var fs, path, FileSystemPersistenceAdapter;
|
|
94
|
+
var init_file_adapter = __esm({
|
|
95
|
+
"src/persistence/file-adapter.ts"() {
|
|
96
|
+
"use strict";
|
|
97
|
+
fs = __toESM(require("fs"));
|
|
98
|
+
path = __toESM(require("path"));
|
|
99
|
+
FileSystemPersistenceAdapter = class {
|
|
100
|
+
constructor(options) {
|
|
101
|
+
this.dirty = false;
|
|
102
|
+
this.timer = null;
|
|
103
|
+
this.currentDb = null;
|
|
104
|
+
this.filePath = options?.path || path.join(".objectstack", "data", "memory-driver.json");
|
|
105
|
+
this.autoSaveInterval = options?.autoSaveInterval ?? 2e3;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Load persisted data from disk.
|
|
109
|
+
* Returns null if no file exists.
|
|
110
|
+
*/
|
|
111
|
+
async load() {
|
|
112
|
+
try {
|
|
113
|
+
if (!fs.existsSync(this.filePath)) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
const raw = fs.readFileSync(this.filePath, "utf-8");
|
|
117
|
+
const data = JSON.parse(raw);
|
|
118
|
+
return data;
|
|
119
|
+
} catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Save data to disk using atomic write (temp file + rename).
|
|
125
|
+
*/
|
|
126
|
+
async save(db) {
|
|
127
|
+
this.currentDb = db;
|
|
128
|
+
this.dirty = true;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Flush pending writes to disk immediately.
|
|
132
|
+
*/
|
|
133
|
+
async flush() {
|
|
134
|
+
if (!this.dirty || !this.currentDb) return;
|
|
135
|
+
await this.writeToDisk(this.currentDb);
|
|
136
|
+
this.dirty = false;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Start the auto-save timer.
|
|
140
|
+
*/
|
|
141
|
+
startAutoSave() {
|
|
142
|
+
if (this.timer) return;
|
|
143
|
+
this.timer = setInterval(async () => {
|
|
144
|
+
if (this.dirty && this.currentDb) {
|
|
145
|
+
await this.writeToDisk(this.currentDb);
|
|
146
|
+
this.dirty = false;
|
|
147
|
+
}
|
|
148
|
+
}, this.autoSaveInterval);
|
|
149
|
+
if (this.timer) {
|
|
150
|
+
this.timer.unref();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Stop the auto-save timer and flush pending writes.
|
|
155
|
+
*/
|
|
156
|
+
async stopAutoSave() {
|
|
157
|
+
if (this.timer) {
|
|
158
|
+
clearInterval(this.timer);
|
|
159
|
+
this.timer = null;
|
|
160
|
+
}
|
|
161
|
+
await this.flush();
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Atomic write: write to temp file, then rename.
|
|
165
|
+
*/
|
|
166
|
+
async writeToDisk(db) {
|
|
167
|
+
const dir = path.dirname(this.filePath);
|
|
168
|
+
if (!fs.existsSync(dir)) {
|
|
169
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
170
|
+
}
|
|
171
|
+
const tmpPath = this.filePath + ".tmp";
|
|
172
|
+
const json = JSON.stringify(db, null, 2);
|
|
173
|
+
fs.writeFileSync(tmpPath, json, "utf-8");
|
|
174
|
+
fs.renameSync(tmpPath, this.filePath);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
20
180
|
// src/index.ts
|
|
21
181
|
var index_exports = {};
|
|
22
182
|
__export(index_exports, {
|
|
183
|
+
FileSystemPersistenceAdapter: () => FileSystemPersistenceAdapter,
|
|
23
184
|
InMemoryDriver: () => InMemoryDriver,
|
|
185
|
+
LocalStoragePersistenceAdapter: () => LocalStoragePersistenceAdapter,
|
|
24
186
|
MemoryAnalyticsService: () => MemoryAnalyticsService,
|
|
25
187
|
default: () => index_default
|
|
26
188
|
});
|
|
@@ -31,22 +193,23 @@ var import_core = require("@objectstack/core");
|
|
|
31
193
|
var import_mingo = require("mingo");
|
|
32
194
|
|
|
33
195
|
// src/memory-matcher.ts
|
|
34
|
-
function getValueByPath(obj,
|
|
35
|
-
if (
|
|
196
|
+
function getValueByPath(obj, path2) {
|
|
197
|
+
if (path2 === "_id" && obj._id === void 0 && obj.id !== void 0) {
|
|
36
198
|
return obj.id;
|
|
37
199
|
}
|
|
38
|
-
if (!
|
|
39
|
-
return
|
|
200
|
+
if (!path2.includes(".")) return obj[path2];
|
|
201
|
+
return path2.split(".").reduce((o, i) => o ? o[i] : void 0, obj);
|
|
40
202
|
}
|
|
41
203
|
|
|
42
204
|
// src/memory-driver.ts
|
|
43
|
-
var
|
|
205
|
+
var _InMemoryDriver = class _InMemoryDriver {
|
|
44
206
|
constructor(config) {
|
|
45
207
|
this.name = "com.objectstack.driver.memory";
|
|
46
208
|
this.type = "driver";
|
|
47
209
|
this.version = "1.0.0";
|
|
48
210
|
this.idCounters = /* @__PURE__ */ new Map();
|
|
49
211
|
this.transactions = /* @__PURE__ */ new Map();
|
|
212
|
+
this.persistenceAdapter = null;
|
|
50
213
|
this.supports = {
|
|
51
214
|
// Transaction & Connection Management
|
|
52
215
|
transactions: true,
|
|
@@ -100,6 +263,31 @@ var InMemoryDriver = class {
|
|
|
100
263
|
// Lifecycle
|
|
101
264
|
// ===================================
|
|
102
265
|
async connect() {
|
|
266
|
+
await this.initPersistence();
|
|
267
|
+
if (this.persistenceAdapter) {
|
|
268
|
+
const persisted = await this.persistenceAdapter.load();
|
|
269
|
+
if (persisted) {
|
|
270
|
+
for (const [objectName, records] of Object.entries(persisted)) {
|
|
271
|
+
this.db[objectName] = records;
|
|
272
|
+
for (const record of records) {
|
|
273
|
+
if (record.id && typeof record.id === "string") {
|
|
274
|
+
const parts = record.id.split("-");
|
|
275
|
+
const lastPart = parts[parts.length - 1];
|
|
276
|
+
const counter = parseInt(lastPart, 10);
|
|
277
|
+
if (!isNaN(counter)) {
|
|
278
|
+
const current = this.idCounters.get(objectName) || 0;
|
|
279
|
+
if (counter > current) {
|
|
280
|
+
this.idCounters.set(objectName, counter);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
this.logger.info("InMemory Database restored from persistence", {
|
|
287
|
+
tables: Object.keys(persisted).length
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
103
291
|
if (this.config.initialData) {
|
|
104
292
|
for (const [objectName, records] of Object.entries(this.config.initialData)) {
|
|
105
293
|
const table = this.getTable(objectName);
|
|
@@ -114,8 +302,17 @@ var InMemoryDriver = class {
|
|
|
114
302
|
} else {
|
|
115
303
|
this.logger.info("InMemory Database Connected (Virtual)");
|
|
116
304
|
}
|
|
305
|
+
if (this.persistenceAdapter?.startAutoSave) {
|
|
306
|
+
this.persistenceAdapter.startAutoSave();
|
|
307
|
+
}
|
|
117
308
|
}
|
|
118
309
|
async disconnect() {
|
|
310
|
+
if (this.persistenceAdapter) {
|
|
311
|
+
if (this.persistenceAdapter.stopAutoSave) {
|
|
312
|
+
await this.persistenceAdapter.stopAutoSave();
|
|
313
|
+
}
|
|
314
|
+
await this.persistenceAdapter.flush();
|
|
315
|
+
}
|
|
119
316
|
const tableCount = Object.keys(this.db).length;
|
|
120
317
|
const recordCount = Object.values(this.db).reduce((sum, table) => sum + table.length, 0);
|
|
121
318
|
this.db = {};
|
|
@@ -195,6 +392,7 @@ var InMemoryDriver = class {
|
|
|
195
392
|
updated_at: data.updated_at || (/* @__PURE__ */ new Date()).toISOString()
|
|
196
393
|
};
|
|
197
394
|
table.push(newRecord);
|
|
395
|
+
this.markDirty();
|
|
198
396
|
this.logger.debug("Record created", { object, id: newRecord.id, tableSize: table.length });
|
|
199
397
|
return { ...newRecord };
|
|
200
398
|
}
|
|
@@ -219,6 +417,7 @@ var InMemoryDriver = class {
|
|
|
219
417
|
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
220
418
|
};
|
|
221
419
|
table[index] = updatedRecord;
|
|
420
|
+
this.markDirty();
|
|
222
421
|
this.logger.debug("Record updated", { object, id });
|
|
223
422
|
return { ...updatedRecord };
|
|
224
423
|
}
|
|
@@ -251,6 +450,7 @@ var InMemoryDriver = class {
|
|
|
251
450
|
return false;
|
|
252
451
|
}
|
|
253
452
|
table.splice(index, 1);
|
|
453
|
+
this.markDirty();
|
|
254
454
|
this.logger.debug("Record deleted", { object, id, tableSize: table.length });
|
|
255
455
|
return true;
|
|
256
456
|
}
|
|
@@ -299,6 +499,7 @@ var InMemoryDriver = class {
|
|
|
299
499
|
table[index] = updated;
|
|
300
500
|
}
|
|
301
501
|
}
|
|
502
|
+
if (count > 0) this.markDirty();
|
|
302
503
|
this.logger.debug("UpdateMany completed", { object, count });
|
|
303
504
|
return { count };
|
|
304
505
|
}
|
|
@@ -320,6 +521,7 @@ var InMemoryDriver = class {
|
|
|
320
521
|
this.db[object] = [];
|
|
321
522
|
}
|
|
322
523
|
const count = initialLength - this.db[object].length;
|
|
524
|
+
if (count > 0) this.markDirty();
|
|
323
525
|
this.logger.debug("DeleteMany completed", { object, count });
|
|
324
526
|
return { count };
|
|
325
527
|
}
|
|
@@ -367,6 +569,7 @@ var InMemoryDriver = class {
|
|
|
367
569
|
const tx = this.transactions.get(txId);
|
|
368
570
|
this.db = tx.snapshot;
|
|
369
571
|
this.transactions.delete(txId);
|
|
572
|
+
this.markDirty();
|
|
370
573
|
this.logger.debug("Transaction rolled back", { txId });
|
|
371
574
|
}
|
|
372
575
|
// ===================================
|
|
@@ -378,6 +581,7 @@ var InMemoryDriver = class {
|
|
|
378
581
|
async clear() {
|
|
379
582
|
this.db = {};
|
|
380
583
|
this.idCounters.clear();
|
|
584
|
+
this.markDirty();
|
|
381
585
|
this.logger.debug("All data cleared");
|
|
382
586
|
}
|
|
383
587
|
/**
|
|
@@ -614,8 +818,8 @@ var InMemoryDriver = class {
|
|
|
614
818
|
return null;
|
|
615
819
|
}
|
|
616
820
|
}
|
|
617
|
-
setValueByPath(obj,
|
|
618
|
-
const parts =
|
|
821
|
+
setValueByPath(obj, path2, value) {
|
|
822
|
+
const parts = path2.split(".");
|
|
619
823
|
let current = obj;
|
|
620
824
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
621
825
|
const part = parts[i];
|
|
@@ -702,7 +906,131 @@ var InMemoryDriver = class {
|
|
|
702
906
|
const timestamp = Date.now();
|
|
703
907
|
return `${key}-${timestamp}-${counter}`;
|
|
704
908
|
}
|
|
909
|
+
// ===================================
|
|
910
|
+
// Persistence
|
|
911
|
+
// ===================================
|
|
912
|
+
/**
|
|
913
|
+
* Mark the database as dirty, triggering persistence save.
|
|
914
|
+
*/
|
|
915
|
+
markDirty() {
|
|
916
|
+
if (this.persistenceAdapter) {
|
|
917
|
+
this.persistenceAdapter.save(this.db);
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Flush pending persistence writes to ensure data is safely stored.
|
|
922
|
+
*/
|
|
923
|
+
async flush() {
|
|
924
|
+
if (this.persistenceAdapter) {
|
|
925
|
+
await this.persistenceAdapter.flush();
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Detect whether the current runtime is a browser environment.
|
|
930
|
+
*/
|
|
931
|
+
isBrowserEnvironment() {
|
|
932
|
+
return typeof globalThis.localStorage !== "undefined";
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Detect whether the current runtime is a serverless/edge environment.
|
|
936
|
+
*
|
|
937
|
+
* Checks well-known environment variables set by serverless platforms:
|
|
938
|
+
* - `VERCEL` / `VERCEL_ENV` — Vercel Functions / Edge
|
|
939
|
+
* - `AWS_LAMBDA_FUNCTION_NAME` — AWS Lambda
|
|
940
|
+
* - `NETLIFY` — Netlify Functions
|
|
941
|
+
* - `FUNCTIONS_WORKER_RUNTIME` — Azure Functions
|
|
942
|
+
* - `K_SERVICE` — Google Cloud Run / Cloud Functions
|
|
943
|
+
* - `FUNCTION_TARGET` — Google Cloud Functions (Node.js)
|
|
944
|
+
* - `DENO_DEPLOYMENT_ID` — Deno Deploy
|
|
945
|
+
*
|
|
946
|
+
* Returns `false` when `process` or `process.env` is unavailable
|
|
947
|
+
* (e.g. browser or edge runtimes without a Node.js process object).
|
|
948
|
+
*/
|
|
949
|
+
isServerlessEnvironment() {
|
|
950
|
+
if (typeof globalThis.process === "undefined" || !globalThis.process.env) {
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
const env = globalThis.process.env;
|
|
954
|
+
return !!(env.VERCEL || env.VERCEL_ENV || env.AWS_LAMBDA_FUNCTION_NAME || env.NETLIFY || env.FUNCTIONS_WORKER_RUNTIME || env.K_SERVICE || env.FUNCTION_TARGET || env.DENO_DEPLOYMENT_ID);
|
|
955
|
+
}
|
|
956
|
+
/**
|
|
957
|
+
* Initialize the persistence adapter based on configuration.
|
|
958
|
+
* Defaults to 'auto' when persistence is not specified.
|
|
959
|
+
* Use `persistence: false` to explicitly disable persistence.
|
|
960
|
+
*
|
|
961
|
+
* In serverless environments (Vercel, AWS Lambda, etc.), auto mode disables
|
|
962
|
+
* file-system persistence and emits a warning. Use `persistence: false` or
|
|
963
|
+
* supply a custom adapter for serverless-safe operation.
|
|
964
|
+
*/
|
|
965
|
+
async initPersistence() {
|
|
966
|
+
const persistence = this.config.persistence === void 0 ? "auto" : this.config.persistence;
|
|
967
|
+
if (persistence === false) return;
|
|
968
|
+
if (typeof persistence === "string") {
|
|
969
|
+
if (persistence === "auto") {
|
|
970
|
+
if (this.isBrowserEnvironment()) {
|
|
971
|
+
const { LocalStoragePersistenceAdapter: LocalStoragePersistenceAdapter2 } = await Promise.resolve().then(() => (init_local_storage_adapter(), local_storage_adapter_exports));
|
|
972
|
+
this.persistenceAdapter = new LocalStoragePersistenceAdapter2();
|
|
973
|
+
this.logger.debug("Auto-detected browser environment, using localStorage persistence");
|
|
974
|
+
} else if (this.isServerlessEnvironment()) {
|
|
975
|
+
this.logger.warn(_InMemoryDriver.SERVERLESS_PERSISTENCE_WARNING);
|
|
976
|
+
} else {
|
|
977
|
+
const { FileSystemPersistenceAdapter: FileSystemPersistenceAdapter2 } = await Promise.resolve().then(() => (init_file_adapter(), file_adapter_exports));
|
|
978
|
+
this.persistenceAdapter = new FileSystemPersistenceAdapter2();
|
|
979
|
+
this.logger.debug("Auto-detected Node.js environment, using file persistence");
|
|
980
|
+
}
|
|
981
|
+
} else if (persistence === "file") {
|
|
982
|
+
const { FileSystemPersistenceAdapter: FileSystemPersistenceAdapter2 } = await Promise.resolve().then(() => (init_file_adapter(), file_adapter_exports));
|
|
983
|
+
this.persistenceAdapter = new FileSystemPersistenceAdapter2();
|
|
984
|
+
} else if (persistence === "local") {
|
|
985
|
+
const { LocalStoragePersistenceAdapter: LocalStoragePersistenceAdapter2 } = await Promise.resolve().then(() => (init_local_storage_adapter(), local_storage_adapter_exports));
|
|
986
|
+
this.persistenceAdapter = new LocalStoragePersistenceAdapter2();
|
|
987
|
+
} else {
|
|
988
|
+
throw new Error(`Unknown persistence type: "${persistence}". Use 'file', 'local', or 'auto'.`);
|
|
989
|
+
}
|
|
990
|
+
} else if ("adapter" in persistence && persistence.adapter) {
|
|
991
|
+
this.persistenceAdapter = persistence.adapter;
|
|
992
|
+
} else if ("type" in persistence) {
|
|
993
|
+
if (persistence.type === "auto") {
|
|
994
|
+
if (this.isBrowserEnvironment()) {
|
|
995
|
+
const { LocalStoragePersistenceAdapter: LocalStoragePersistenceAdapter2 } = await Promise.resolve().then(() => (init_local_storage_adapter(), local_storage_adapter_exports));
|
|
996
|
+
this.persistenceAdapter = new LocalStoragePersistenceAdapter2({
|
|
997
|
+
key: persistence.key
|
|
998
|
+
});
|
|
999
|
+
this.logger.debug("Auto-detected browser environment, using localStorage persistence");
|
|
1000
|
+
} else if (this.isServerlessEnvironment()) {
|
|
1001
|
+
this.logger.warn(_InMemoryDriver.SERVERLESS_PERSISTENCE_WARNING);
|
|
1002
|
+
} else {
|
|
1003
|
+
const { FileSystemPersistenceAdapter: FileSystemPersistenceAdapter2 } = await Promise.resolve().then(() => (init_file_adapter(), file_adapter_exports));
|
|
1004
|
+
this.persistenceAdapter = new FileSystemPersistenceAdapter2({
|
|
1005
|
+
path: persistence.path,
|
|
1006
|
+
autoSaveInterval: persistence.autoSaveInterval
|
|
1007
|
+
});
|
|
1008
|
+
this.logger.debug("Auto-detected Node.js environment, using file persistence");
|
|
1009
|
+
}
|
|
1010
|
+
} else if (persistence.type === "file") {
|
|
1011
|
+
const { FileSystemPersistenceAdapter: FileSystemPersistenceAdapter2 } = await Promise.resolve().then(() => (init_file_adapter(), file_adapter_exports));
|
|
1012
|
+
this.persistenceAdapter = new FileSystemPersistenceAdapter2({
|
|
1013
|
+
path: persistence.path,
|
|
1014
|
+
autoSaveInterval: persistence.autoSaveInterval
|
|
1015
|
+
});
|
|
1016
|
+
} else if (persistence.type === "local") {
|
|
1017
|
+
const { LocalStoragePersistenceAdapter: LocalStoragePersistenceAdapter2 } = await Promise.resolve().then(() => (init_local_storage_adapter(), local_storage_adapter_exports));
|
|
1018
|
+
this.persistenceAdapter = new LocalStoragePersistenceAdapter2({
|
|
1019
|
+
key: persistence.key
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
if (this.persistenceAdapter) {
|
|
1024
|
+
this.logger.debug("Persistence adapter initialized");
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
705
1027
|
};
|
|
1028
|
+
_InMemoryDriver.SERVERLESS_PERSISTENCE_WARNING = "Serverless environment detected \u2014 file-system persistence is disabled in auto mode. Data will NOT be persisted across function invocations. Set persistence: false to silence this warning, or provide a custom adapter (e.g. Upstash Redis, Vercel KV) via persistence: { adapter: yourAdapter }.";
|
|
1029
|
+
var InMemoryDriver = _InMemoryDriver;
|
|
1030
|
+
|
|
1031
|
+
// src/index.ts
|
|
1032
|
+
init_file_adapter();
|
|
1033
|
+
init_local_storage_adapter();
|
|
706
1034
|
|
|
707
1035
|
// src/memory-analytics.ts
|
|
708
1036
|
var import_core2 = require("@objectstack/core");
|
|
@@ -1115,7 +1443,9 @@ var index_default = {
|
|
|
1115
1443
|
};
|
|
1116
1444
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1117
1445
|
0 && (module.exports = {
|
|
1446
|
+
FileSystemPersistenceAdapter,
|
|
1118
1447
|
InMemoryDriver,
|
|
1448
|
+
LocalStoragePersistenceAdapter,
|
|
1119
1449
|
MemoryAnalyticsService
|
|
1120
1450
|
});
|
|
1121
1451
|
//# sourceMappingURL=index.js.map
|