@matter/nodejs 0.16.6-alpha.0-20260121-bc6d62766 → 0.16.6-alpha.0-20260122-b5154bcb4

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 (150) hide show
  1. package/dist/cjs/config.d.ts +6 -0
  2. package/dist/cjs/config.d.ts.map +1 -1
  3. package/dist/cjs/config.js +14 -1
  4. package/dist/cjs/config.js.map +1 -1
  5. package/dist/cjs/environment/NodeJsEnvironment.d.ts +2 -1
  6. package/dist/cjs/environment/NodeJsEnvironment.d.ts.map +1 -1
  7. package/dist/cjs/environment/NodeJsEnvironment.js +28 -10
  8. package/dist/cjs/environment/NodeJsEnvironment.js.map +1 -1
  9. package/dist/cjs/storage/StorageFactory.d.ts +52 -0
  10. package/dist/cjs/storage/StorageFactory.d.ts.map +1 -0
  11. package/dist/cjs/storage/StorageFactory.js +215 -0
  12. package/dist/cjs/storage/StorageFactory.js.map +6 -0
  13. package/dist/cjs/storage/fs/StorageBackendDisk.d.ts.map +1 -0
  14. package/dist/cjs/storage/{StorageBackendDisk.js.map → fs/StorageBackendDisk.js.map} +1 -1
  15. package/dist/cjs/storage/fs/StorageBackendJsonFile.d.ts.map +1 -0
  16. package/dist/cjs/storage/{StorageBackendJsonFile.js.map → fs/StorageBackendJsonFile.js.map} +1 -1
  17. package/dist/cjs/storage/fs/index.d.ts +8 -0
  18. package/dist/cjs/storage/fs/index.d.ts.map +1 -0
  19. package/dist/cjs/storage/fs/index.js +25 -0
  20. package/dist/cjs/storage/fs/index.js.map +6 -0
  21. package/dist/cjs/storage/index.d.ts +3 -2
  22. package/dist/cjs/storage/index.d.ts.map +1 -1
  23. package/dist/cjs/storage/index.js +3 -2
  24. package/dist/cjs/storage/index.js.map +1 -1
  25. package/dist/cjs/storage/sqlite/SqliteStorage.d.ts +105 -0
  26. package/dist/cjs/storage/sqlite/SqliteStorage.d.ts.map +1 -0
  27. package/dist/cjs/storage/sqlite/SqliteStorage.js +439 -0
  28. package/dist/cjs/storage/sqlite/SqliteStorage.js.map +6 -0
  29. package/dist/cjs/storage/sqlite/SqliteStorageError.d.ts +19 -0
  30. package/dist/cjs/storage/sqlite/SqliteStorageError.d.ts.map +1 -0
  31. package/dist/cjs/storage/sqlite/SqliteStorageError.js +38 -0
  32. package/dist/cjs/storage/sqlite/SqliteStorageError.js.map +6 -0
  33. package/dist/cjs/storage/sqlite/SqliteTypes.d.ts +67 -0
  34. package/dist/cjs/storage/sqlite/SqliteTypes.d.ts.map +1 -0
  35. package/dist/cjs/storage/sqlite/SqliteTypes.js +35 -0
  36. package/dist/cjs/storage/sqlite/SqliteTypes.js.map +6 -0
  37. package/dist/cjs/storage/sqlite/SqliteUtil.d.ts +33 -0
  38. package/dist/cjs/storage/sqlite/SqliteUtil.d.ts.map +1 -0
  39. package/dist/cjs/storage/sqlite/SqliteUtil.js +64 -0
  40. package/dist/cjs/storage/sqlite/SqliteUtil.js.map +6 -0
  41. package/dist/cjs/storage/sqlite/index.d.ts +10 -0
  42. package/dist/cjs/storage/sqlite/index.d.ts.map +1 -0
  43. package/dist/cjs/storage/sqlite/index.js +34 -0
  44. package/dist/cjs/storage/sqlite/index.js.map +6 -0
  45. package/dist/cjs/storage/sqlite/platform/BunSqlite.d.ts +17 -0
  46. package/dist/cjs/storage/sqlite/platform/BunSqlite.d.ts.map +1 -0
  47. package/dist/cjs/storage/sqlite/platform/BunSqlite.js +62 -0
  48. package/dist/cjs/storage/sqlite/platform/BunSqlite.js.map +6 -0
  49. package/dist/cjs/storage/sqlite/platform/NodeJsSqlite.d.ts +12 -0
  50. package/dist/cjs/storage/sqlite/platform/NodeJsSqlite.d.ts.map +1 -0
  51. package/dist/cjs/storage/sqlite/platform/NodeJsSqlite.js +49 -0
  52. package/dist/cjs/storage/sqlite/platform/NodeJsSqlite.js.map +6 -0
  53. package/dist/cjs/storage/sqlite/platform/PlatformSqlite.d.ts +8 -0
  54. package/dist/cjs/storage/sqlite/platform/PlatformSqlite.d.ts.map +1 -0
  55. package/dist/cjs/storage/sqlite/platform/PlatformSqlite.js +54 -0
  56. package/dist/cjs/storage/sqlite/platform/PlatformSqlite.js.map +6 -0
  57. package/dist/cjs/util/runtimeChecks.d.ts +14 -0
  58. package/dist/cjs/util/runtimeChecks.d.ts.map +1 -0
  59. package/dist/cjs/util/runtimeChecks.js +45 -0
  60. package/dist/cjs/util/runtimeChecks.js.map +6 -0
  61. package/dist/esm/config.d.ts +6 -0
  62. package/dist/esm/config.d.ts.map +1 -1
  63. package/dist/esm/config.js +14 -1
  64. package/dist/esm/config.js.map +1 -1
  65. package/dist/esm/environment/NodeJsEnvironment.d.ts +2 -1
  66. package/dist/esm/environment/NodeJsEnvironment.d.ts.map +1 -1
  67. package/dist/esm/environment/NodeJsEnvironment.js +29 -10
  68. package/dist/esm/environment/NodeJsEnvironment.js.map +1 -1
  69. package/dist/esm/storage/StorageFactory.d.ts +52 -0
  70. package/dist/esm/storage/StorageFactory.d.ts.map +1 -0
  71. package/dist/esm/storage/StorageFactory.js +195 -0
  72. package/dist/esm/storage/StorageFactory.js.map +6 -0
  73. package/dist/esm/storage/fs/StorageBackendDisk.d.ts.map +1 -0
  74. package/dist/esm/storage/{StorageBackendDisk.js.map → fs/StorageBackendDisk.js.map} +1 -1
  75. package/dist/esm/storage/fs/StorageBackendJsonFile.d.ts.map +1 -0
  76. package/dist/esm/storage/{StorageBackendJsonFile.js.map → fs/StorageBackendJsonFile.js.map} +1 -1
  77. package/dist/esm/storage/fs/index.d.ts +8 -0
  78. package/dist/esm/storage/fs/index.d.ts.map +1 -0
  79. package/dist/esm/storage/fs/index.js +8 -0
  80. package/dist/esm/storage/fs/index.js.map +6 -0
  81. package/dist/esm/storage/index.d.ts +3 -2
  82. package/dist/esm/storage/index.d.ts.map +1 -1
  83. package/dist/esm/storage/index.js +3 -2
  84. package/dist/esm/storage/index.js.map +1 -1
  85. package/dist/esm/storage/sqlite/SqliteStorage.d.ts +105 -0
  86. package/dist/esm/storage/sqlite/SqliteStorage.d.ts.map +1 -0
  87. package/dist/esm/storage/sqlite/SqliteStorage.js +423 -0
  88. package/dist/esm/storage/sqlite/SqliteStorage.js.map +6 -0
  89. package/dist/esm/storage/sqlite/SqliteStorageError.d.ts +19 -0
  90. package/dist/esm/storage/sqlite/SqliteStorageError.d.ts.map +1 -0
  91. package/dist/esm/storage/sqlite/SqliteStorageError.js +18 -0
  92. package/dist/esm/storage/sqlite/SqliteStorageError.js.map +6 -0
  93. package/dist/esm/storage/sqlite/SqliteTypes.d.ts +67 -0
  94. package/dist/esm/storage/sqlite/SqliteTypes.d.ts.map +1 -0
  95. package/dist/esm/storage/sqlite/SqliteTypes.js +15 -0
  96. package/dist/esm/storage/sqlite/SqliteTypes.js.map +6 -0
  97. package/dist/esm/storage/sqlite/SqliteUtil.d.ts +33 -0
  98. package/dist/esm/storage/sqlite/SqliteUtil.d.ts.map +1 -0
  99. package/dist/esm/storage/sqlite/SqliteUtil.js +44 -0
  100. package/dist/esm/storage/sqlite/SqliteUtil.js.map +6 -0
  101. package/dist/esm/storage/sqlite/index.d.ts +10 -0
  102. package/dist/esm/storage/sqlite/index.d.ts.map +1 -0
  103. package/dist/esm/storage/sqlite/index.js +14 -0
  104. package/dist/esm/storage/sqlite/index.js.map +6 -0
  105. package/dist/esm/storage/sqlite/platform/BunSqlite.d.ts +17 -0
  106. package/dist/esm/storage/sqlite/platform/BunSqlite.d.ts.map +1 -0
  107. package/dist/esm/storage/sqlite/platform/BunSqlite.js +32 -0
  108. package/dist/esm/storage/sqlite/platform/BunSqlite.js.map +6 -0
  109. package/dist/esm/storage/sqlite/platform/NodeJsSqlite.d.ts +12 -0
  110. package/dist/esm/storage/sqlite/platform/NodeJsSqlite.d.ts.map +1 -0
  111. package/dist/esm/storage/sqlite/platform/NodeJsSqlite.js +29 -0
  112. package/dist/esm/storage/sqlite/platform/NodeJsSqlite.js.map +6 -0
  113. package/dist/esm/storage/sqlite/platform/PlatformSqlite.d.ts +8 -0
  114. package/dist/esm/storage/sqlite/platform/PlatformSqlite.d.ts.map +1 -0
  115. package/dist/esm/storage/sqlite/platform/PlatformSqlite.js +24 -0
  116. package/dist/esm/storage/sqlite/platform/PlatformSqlite.js.map +6 -0
  117. package/dist/esm/util/runtimeChecks.d.ts +14 -0
  118. package/dist/esm/util/runtimeChecks.d.ts.map +1 -0
  119. package/dist/esm/util/runtimeChecks.js +25 -0
  120. package/dist/esm/util/runtimeChecks.js.map +6 -0
  121. package/package.json +10 -10
  122. package/src/config.ts +18 -4
  123. package/src/environment/NodeJsEnvironment.ts +41 -12
  124. package/src/net/NodeJsHttpEndpoint.ts +1 -1
  125. package/src/storage/StorageFactory.ts +310 -0
  126. package/src/storage/fs/index.ts +8 -0
  127. package/src/storage/index.ts +3 -2
  128. package/src/storage/sqlite/SqliteStorage.ts +572 -0
  129. package/src/storage/sqlite/SqliteStorageError.ts +23 -0
  130. package/src/storage/sqlite/SqliteTypes.ts +75 -0
  131. package/src/storage/sqlite/SqliteUtil.ts +61 -0
  132. package/src/storage/sqlite/index.ts +10 -0
  133. package/src/storage/sqlite/platform/BunSqlite.ts +40 -0
  134. package/src/storage/sqlite/platform/NodeJsSqlite.ts +35 -0
  135. package/src/storage/sqlite/platform/PlatformSqlite.ts +52 -0
  136. package/src/util/runtimeChecks.ts +31 -0
  137. package/dist/cjs/storage/StorageBackendDisk.d.ts.map +0 -1
  138. package/dist/cjs/storage/StorageBackendJsonFile.d.ts.map +0 -1
  139. package/dist/esm/storage/StorageBackendDisk.d.ts.map +0 -1
  140. package/dist/esm/storage/StorageBackendJsonFile.d.ts.map +0 -1
  141. /package/dist/cjs/storage/{StorageBackendDisk.d.ts → fs/StorageBackendDisk.d.ts} +0 -0
  142. /package/dist/cjs/storage/{StorageBackendDisk.js → fs/StorageBackendDisk.js} +0 -0
  143. /package/dist/cjs/storage/{StorageBackendJsonFile.d.ts → fs/StorageBackendJsonFile.d.ts} +0 -0
  144. /package/dist/cjs/storage/{StorageBackendJsonFile.js → fs/StorageBackendJsonFile.js} +0 -0
  145. /package/dist/esm/storage/{StorageBackendDisk.d.ts → fs/StorageBackendDisk.d.ts} +0 -0
  146. /package/dist/esm/storage/{StorageBackendDisk.js → fs/StorageBackendDisk.js} +0 -0
  147. /package/dist/esm/storage/{StorageBackendJsonFile.d.ts → fs/StorageBackendJsonFile.d.ts} +0 -0
  148. /package/dist/esm/storage/{StorageBackendJsonFile.js → fs/StorageBackendJsonFile.js} +0 -0
  149. /package/src/storage/{StorageBackendDisk.ts → fs/StorageBackendDisk.ts} +0 -0
  150. /package/src/storage/{StorageBackendJsonFile.ts → fs/StorageBackendJsonFile.ts} +0 -0
@@ -0,0 +1,310 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2026 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import { supportsSqlite } from "#util/runtimeChecks.js";
8
+ import { Logger, StorageError, StorageMigration, toJson } from "@matter/general";
9
+ import { lstat, mkdir, rename, rm, writeFile } from "node:fs/promises";
10
+ import { resolve } from "node:path";
11
+ import { StorageBackendDisk } from "./fs/StorageBackendDisk.js";
12
+ import { PlatformSqlite } from "./sqlite/index.js";
13
+
14
+ const logger = new Logger("StorageFactory");
15
+
16
+ /**
17
+ * Storage Types which is implemented.
18
+ */
19
+ // Note: Only use lowercase of enum value.
20
+ export enum StorageType {
21
+ FILE = "file",
22
+ SQLITE = "sqlite",
23
+ }
24
+
25
+ /**
26
+ * Factory for creating storage backends with automatic migration support.
27
+ *
28
+ * Provides a unified interface for creating different storage implementations
29
+ * (file-based, SQLite) with seamless migration between storage types.
30
+ *
31
+ * @see {@link StorageType} for available storage types
32
+ * @see {@link create} for creating storage instances
33
+ */
34
+ export namespace StorageFactory {
35
+ const StorageTypes: StorageType[] = [StorageType.FILE, StorageType.SQLITE];
36
+
37
+ /**
38
+ * Creates a storage instance with automatic migration support.
39
+ *
40
+ * It is also initialized while creating.
41
+ *
42
+ * This is the main entry point for creating storage backends.
43
+ * It handles:
44
+ * - Directory creation if not exists
45
+ * - Automatic migration from other storage types
46
+ * - Backup of original data
47
+ */
48
+ export async function create(args: {
49
+ driver: StorageType | string;
50
+ rootDir: string;
51
+ namespace: string;
52
+ clear?: boolean;
53
+ }) {
54
+ const { driver, namespace } = args;
55
+ const rootDir = resolve(args.rootDir);
56
+ const clear = args.clear ?? false;
57
+ const type = getStorageType(driver);
58
+
59
+ // Ensure rootDir exists
60
+ if (!(await exists(rootDir))) {
61
+ await mkdir(rootDir, { recursive: true });
62
+ }
63
+
64
+ const path = getRealPath(type, rootDir, namespace);
65
+
66
+ // No migrate if exists or clear = true
67
+ if (clear || (await exists(path))) {
68
+ return await createRawInit(type, path, clear);
69
+ }
70
+
71
+ // Storage which will use
72
+ const storage = await createRawInit(type, path, false);
73
+
74
+ const migrationRootDir = resolve(rootDir, ".migrations", getResultDirName(namespace));
75
+
76
+ for (const otherType of StorageTypes) {
77
+ if (type === otherType) {
78
+ continue;
79
+ }
80
+
81
+ // Skip if runtime does not support sqlite
82
+ if (otherType === StorageType.SQLITE && !supportsSqlite()) {
83
+ continue;
84
+ }
85
+
86
+ const otherPath = getRealPath(otherType, rootDir, namespace);
87
+ if (!(await hasStorage(otherType, otherPath))) {
88
+ continue;
89
+ }
90
+
91
+ try {
92
+ const otherStorage = await createRawInit(otherType, otherPath, false);
93
+ // Migrate
94
+ const migrationResult = await StorageMigration.migrate(otherStorage, storage);
95
+ // close otherStorage
96
+ await otherStorage.close();
97
+
98
+ // Create result dir
99
+ const resultDir = resolve(migrationRootDir, otherType);
100
+ await mkdir(resultDir, { recursive: true });
101
+
102
+ // Export log
103
+ await writeFile(resolve(resultDir, "migration.log"), StorageMigration.resultToLog(migrationResult));
104
+
105
+ // Export metadata
106
+ await writeFile(
107
+ resolve(resultDir, "metadata.json"),
108
+ toJson(
109
+ getMetadata({
110
+ fromType: otherType,
111
+ fromPath: otherPath,
112
+ toType: type,
113
+ toPath: path,
114
+ result: migrationResult,
115
+ }),
116
+ 4,
117
+ ),
118
+ );
119
+
120
+ // Move migration data
121
+ const backupPath = getRealPath(otherType, resultDir, namespace);
122
+ await rename(otherPath, backupPath);
123
+ } catch (err) {
124
+ const errorMessage = (err as Error)?.message ?? String(err);
125
+ logger.error(
126
+ `[migrate] Failed to migrate '${namespace}' from ${otherType} to ${type}!\nError: ${errorMessage}`,
127
+ );
128
+ }
129
+ }
130
+
131
+ return storage;
132
+ }
133
+
134
+ /**
135
+ * Remove the storage instance completely.
136
+ *
137
+ * use `storage.clear()` for clearing without remove completely.
138
+ */
139
+ export async function remove(args: { driver: StorageType | string; rootDir: string; namespace: string }) {
140
+ const { driver, namespace } = args;
141
+ const rootDir = resolve(args.rootDir);
142
+ const type = getStorageType(driver);
143
+
144
+ const path = getRealPath(type, rootDir, namespace);
145
+
146
+ if (!(await exists(path))) {
147
+ return;
148
+ }
149
+ await rm(path, { recursive: true, force: true });
150
+ }
151
+
152
+ /**
153
+ * Create storage backend without migration/init
154
+ */
155
+ async function createRaw(type: StorageType, path: string, clear: boolean) {
156
+ const normalizedType = type.toLowerCase();
157
+
158
+ // SQLite
159
+ if (normalizedType === StorageType.SQLITE) {
160
+ if (!supportsSqlite()) {
161
+ // Throwing error should be better than fallback
162
+ throw new Error(
163
+ `SQLite storage is not supported in this environment.
164
+ Node.js v22+ is required for SQLite support.
165
+ Current version: ${process.version}
166
+ `.replace(/\n\s+/g, "\n"),
167
+ );
168
+ }
169
+ return await PlatformSqlite(path, clear);
170
+ }
171
+
172
+ // File storage
173
+ if (normalizedType === StorageType.FILE) {
174
+ return new StorageBackendDisk(path, clear);
175
+ }
176
+
177
+ // Not implemented
178
+ // Anyway this shouldn't be happen in production.
179
+ throw new Error(`'${type}' storage type is not implemented.`);
180
+ }
181
+
182
+ /**
183
+ * `createRaw` with initialize
184
+ */
185
+ async function createRawInit(type: StorageType, path: string, clear: boolean) {
186
+ const storage = await createRaw(type, path, clear);
187
+ await storage.initialize();
188
+ return storage;
189
+ }
190
+
191
+ /**
192
+ * Check if storage exists at the given path.
193
+ *
194
+ * Path should be `getRealPath` instead of namespace path!
195
+ *
196
+ * TODO: replace this check to Storage-specific method?
197
+ */
198
+ async function hasStorage(type: StorageType, path: string): Promise<boolean> {
199
+ try {
200
+ const pathStat = await lstat(path);
201
+
202
+ switch (type) {
203
+ case StorageType.FILE:
204
+ return pathStat.isDirectory();
205
+ case StorageType.SQLITE:
206
+ return pathStat.isFile();
207
+ default:
208
+ return false;
209
+ }
210
+ } catch (err) {
211
+ // ENOENT or other errors - storage doesn't exist
212
+ return false;
213
+ }
214
+ }
215
+
216
+ /**
217
+ * Get name of backup directory
218
+ */
219
+ function getResultDirName(namespace: string) {
220
+ const timestamp = new Date()
221
+ .toISOString()
222
+ .slice(0, 19) // 2026-01-18T09:45:00
223
+ .replace(/[-:]/g, "")
224
+ .replace("T", "_")
225
+ .substring(2);
226
+ // 260118_094500
227
+
228
+ return `${namespace}_${timestamp}_${generateRandomId()}`;
229
+ }
230
+
231
+ /**
232
+ * Get metadata information of migration.
233
+ */
234
+ function getMetadata(args: {
235
+ fromType: StorageType;
236
+ fromPath: string;
237
+ toType: StorageType;
238
+ toPath: string;
239
+ result: StorageMigration.MigrationResult;
240
+ }) {
241
+ const migrationResult = args.result;
242
+ return {
243
+ version: "1.0.0",
244
+ timestamp: Date.now(),
245
+ source: {
246
+ type: args.fromType,
247
+ path: args.fromPath,
248
+ },
249
+ target: {
250
+ type: args.toType,
251
+ path: args.toPath,
252
+ },
253
+ result: {
254
+ success: migrationResult.success,
255
+ migratedCount: migrationResult.migratedCount,
256
+ skippedCount: migrationResult.skippedCount,
257
+ totalItems: migrationResult.migratedCount + migrationResult.skippedCount,
258
+ },
259
+ };
260
+ }
261
+
262
+ function getStorageType(inputType: string) {
263
+ for (const storageType of StorageTypes) {
264
+ if (storageType === inputType.toLowerCase()) {
265
+ return storageType;
266
+ }
267
+ }
268
+ throw new StorageError(`Unknown '${inputType}' type storage!`);
269
+ }
270
+
271
+ function getRealPath(type: StorageType, rootDir: string, namespaces: string | string[]) {
272
+ const namespaceArr = typeof namespaces === "string" ? [namespaces] : namespaces;
273
+
274
+ switch (type) {
275
+ case StorageType.FILE:
276
+ return resolve(rootDir, ...namespaceArr);
277
+ case StorageType.SQLITE:
278
+ const lastIndex = namespaceArr.length - 1;
279
+ namespaceArr[lastIndex] += ".db";
280
+ return resolve(rootDir, ...namespaceArr);
281
+ default:
282
+ throw new Error(`NOT IMPLEMENTED ${type} type.`);
283
+ }
284
+ }
285
+
286
+ /**
287
+ * A temporary random id generator
288
+ *
289
+ * TODO: find a better way than this
290
+ */
291
+ function generateRandomId() {
292
+ const characters = "abcdefghijklmnopqrstuvwxyz0123456789";
293
+
294
+ let result = "";
295
+ for (let i = 0; i < 6; i += 1) {
296
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
297
+ }
298
+
299
+ return result;
300
+ }
301
+
302
+ async function exists(path: string) {
303
+ try {
304
+ await lstat(resolve(path));
305
+ return true;
306
+ } catch (err) {
307
+ return false;
308
+ }
309
+ }
310
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2022-2026 Matter.js Authors
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ export * from "./StorageBackendDisk.js";
8
+ export * from "./StorageBackendJsonFile.js";
@@ -4,5 +4,6 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- export * from "./StorageBackendDisk.js";
8
- export * from "./StorageBackendJsonFile.js";
7
+ export * from "./fs/index.js";
8
+ export * from "./sqlite/index.js";
9
+ export * from "./StorageFactory.js";