@matter/nodejs 0.15.3 → 0.16.0-alpha.0-20250802-1af103e3d
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/cjs/net/NodeJsNetwork.js +1 -1
- package/dist/cjs/net/NodeJsNetwork.js.map +1 -1
- package/dist/cjs/storage/StorageBackendDisk.d.ts +5 -2
- package/dist/cjs/storage/StorageBackendDisk.d.ts.map +1 -1
- package/dist/cjs/storage/StorageBackendDisk.js +72 -15
- package/dist/cjs/storage/StorageBackendDisk.js.map +1 -1
- package/dist/esm/net/NodeJsNetwork.js +1 -1
- package/dist/esm/net/NodeJsNetwork.js.map +1 -1
- package/dist/esm/storage/StorageBackendDisk.d.ts +5 -2
- package/dist/esm/storage/StorageBackendDisk.d.ts.map +1 -1
- package/dist/esm/storage/StorageBackendDisk.js +75 -17
- package/dist/esm/storage/StorageBackendDisk.js.map +1 -1
- package/package.json +11 -11
- package/src/net/NodeJsNetwork.ts +1 -3
- package/src/storage/StorageBackendDisk.ts +88 -18
|
@@ -143,6 +143,6 @@ class NodeJsNetwork extends import_general.Network {
|
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
145
|
function familyIs(version, { family }) {
|
|
146
|
-
return family === `IPv${version}
|
|
146
|
+
return family === `IPv${version}`;
|
|
147
147
|
}
|
|
148
148
|
//# sourceMappingURL=NodeJsNetwork.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/net/NodeJsNetwork.ts"],
|
|
4
|
-
"mappings": "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
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["netInterface"]
|
|
6
6
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
export declare class StorageBackendDisk extends
|
|
6
|
+
import { Storage, SupportedStorageTypes } from "#general";
|
|
7
|
+
export declare class StorageBackendDisk extends Storage {
|
|
8
8
|
#private;
|
|
9
9
|
protected isInitialized: boolean;
|
|
10
10
|
constructor(path: string, clear?: boolean);
|
|
@@ -15,7 +15,10 @@ export declare class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
15
15
|
clear(): Promise<void>;
|
|
16
16
|
getContextBaseKey(contexts: string[], allowEmptyContext?: boolean): string;
|
|
17
17
|
buildStorageKey(contexts: string[], key: string): string;
|
|
18
|
+
has(contexts: string[], key: string): Promise<boolean>;
|
|
18
19
|
get<T extends SupportedStorageTypes>(contexts: string[], key: string): Promise<T | undefined>;
|
|
20
|
+
openBlob(contexts: string[], key: string): Promise<Blob>;
|
|
21
|
+
writeBlobFromStream(contexts: string[], key: string, stream: ReadableStream<Uint8Array>): Promise<void>;
|
|
19
22
|
set(contexts: string[], key: string, value: SupportedStorageTypes): Promise<void>;
|
|
20
23
|
set(contexts: string[], values: Record<string, SupportedStorageTypes>): Promise<void>;
|
|
21
24
|
delete(contexts: string[], key: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageBackendDisk.d.ts","sourceRoot":"","sources":["../../../src/storage/StorageBackendDisk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"StorageBackendDisk.d.ts","sourceRoot":"","sources":["../../../src/storage/StorageBackendDisk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAKH,OAAO,EAEP,qBAAqB,EAExB,MAAM,UAAU,CAAC;AAOlB,qBAAa,kBAAmB,SAAQ,OAAO;;IAG3C,SAAS,CAAC,aAAa,UAAS;gBAGpB,IAAI,EAAE,MAAM,EAAE,KAAK,UAAQ;IAMvC,IAAI,WAAW,YAEd;IAEK,UAAU;IA2BV,KAAK;IAKX,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAInB,KAAK;IAMX,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,iBAAiB,UAAQ;IAY/D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM;IAWhC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe/D,GAAG,CAAC,CAAC,SAAS,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAkB7F,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC;IAIvF,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IACjF,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA2F/E,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM;IAM5C,yEAAyE;IACnE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;IAiBvB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE;IAmBzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;IAsB3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;CAgBpC;AAED;;GAEG"}
|
|
@@ -22,6 +22,7 @@ __export(StorageBackendDisk_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(StorageBackendDisk_exports);
|
|
24
24
|
var import_general = require("#general");
|
|
25
|
+
var import_node_fs = require("node:fs");
|
|
25
26
|
var import_promises = require("node:fs/promises");
|
|
26
27
|
var import_node_path = require("node:path");
|
|
27
28
|
/**
|
|
@@ -30,7 +31,7 @@ var import_node_path = require("node:path");
|
|
|
30
31
|
* SPDX-License-Identifier: Apache-2.0
|
|
31
32
|
*/
|
|
32
33
|
const logger = new import_general.Logger("StorageBackendDisk");
|
|
33
|
-
class StorageBackendDisk extends import_general.
|
|
34
|
+
class StorageBackendDisk extends import_general.Storage {
|
|
34
35
|
#path;
|
|
35
36
|
#clear;
|
|
36
37
|
isInitialized = false;
|
|
@@ -51,16 +52,18 @@ class StorageBackendDisk extends import_general.MaybeAsyncStorage {
|
|
|
51
52
|
this.isInitialized = true;
|
|
52
53
|
}
|
|
53
54
|
async #finishAllWrites(filename) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
if (filename !== void 0 && this.#writeFileBlocker.has(filename) || filename === void 0 && this.#writeFileBlocker.size > 0) {
|
|
56
|
+
for (let i = 0; i < 10; i++) {
|
|
57
|
+
await import_general.MatterAggregateError.allSettled(
|
|
58
|
+
filename !== void 0 ? [this.#writeFileBlocker.get(filename)] : this.#writeFileBlocker.values(),
|
|
59
|
+
"Error on finishing all file system writes to storage"
|
|
60
|
+
);
|
|
61
|
+
if (!this.#writeFileBlocker.size) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
61
64
|
}
|
|
65
|
+
await this.#fsyncStorageDir();
|
|
62
66
|
}
|
|
63
|
-
await this.#fsyncStorageDir();
|
|
64
67
|
}
|
|
65
68
|
async close() {
|
|
66
69
|
this.isInitialized = false;
|
|
@@ -88,10 +91,25 @@ class StorageBackendDisk extends import_general.MaybeAsyncStorage {
|
|
|
88
91
|
const rawName = `${contextKey}.${key}`;
|
|
89
92
|
return encodeURIComponent(rawName).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
|
|
90
93
|
}
|
|
94
|
+
async has(contexts, key) {
|
|
95
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
96
|
+
if (this.#writeFileBlocker.has(fileName)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const stats = await (0, import_promises.stat)(fileName);
|
|
101
|
+
return stats.isFile();
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (error.code === "ENOENT") return false;
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
91
107
|
async get(contexts, key) {
|
|
108
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
109
|
+
await this.#finishAllWrites(fileName);
|
|
92
110
|
let value;
|
|
93
111
|
try {
|
|
94
|
-
value = await (0, import_promises.readFile)(
|
|
112
|
+
value = await (0, import_promises.readFile)(fileName, "utf8");
|
|
95
113
|
} catch (error) {
|
|
96
114
|
if (error.code === "ENOENT") return void 0;
|
|
97
115
|
throw error;
|
|
@@ -102,6 +120,18 @@ class StorageBackendDisk extends import_general.MaybeAsyncStorage {
|
|
|
102
120
|
logger.error(`Failed to parse storage value for key ${key} in context ${contexts.join(".")}`);
|
|
103
121
|
}
|
|
104
122
|
}
|
|
123
|
+
async openBlob(contexts, key) {
|
|
124
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
125
|
+
await this.#finishAllWrites(fileName);
|
|
126
|
+
if (await this.has(contexts, key)) {
|
|
127
|
+
return await (0, import_node_fs.openAsBlob)(fileName);
|
|
128
|
+
} else {
|
|
129
|
+
return new Blob();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
writeBlobFromStream(contexts, key, stream) {
|
|
133
|
+
return this.#writeFile(this.buildStorageKey(contexts, key), stream);
|
|
134
|
+
}
|
|
105
135
|
async set(contexts, keyOrValues, value) {
|
|
106
136
|
if (typeof keyOrValues === "string") {
|
|
107
137
|
return this.#writeFile(this.buildStorageKey(contexts, keyOrValues), (0, import_general.toJson)(value));
|
|
@@ -113,21 +143,48 @@ class StorageBackendDisk extends import_general.MaybeAsyncStorage {
|
|
|
113
143
|
await import_general.MatterAggregateError.allSettled(promises, "Error when writing values into filesystem storage");
|
|
114
144
|
}
|
|
115
145
|
/** According to Node.js documentation, writeFile is not atomic. This method ensures atomicity. */
|
|
116
|
-
async #writeFile(fileName,
|
|
146
|
+
async #writeFile(fileName, valueOrStream) {
|
|
117
147
|
const blocker = this.#writeFileBlocker.get(fileName);
|
|
118
148
|
if (blocker !== void 0) {
|
|
119
149
|
await blocker;
|
|
120
|
-
return this.#writeFile(fileName,
|
|
150
|
+
return this.#writeFile(fileName, valueOrStream);
|
|
121
151
|
}
|
|
122
|
-
const promise = this.#writeAndMoveFile(this.filePath(fileName),
|
|
152
|
+
const promise = this.#writeAndMoveFile(this.filePath(fileName), valueOrStream).finally(() => {
|
|
123
153
|
this.#writeFileBlocker.delete(fileName);
|
|
124
154
|
});
|
|
125
155
|
this.#writeFileBlocker.set(fileName, promise);
|
|
126
156
|
return promise;
|
|
127
157
|
}
|
|
128
|
-
async #writeAndMoveFile(filepath,
|
|
158
|
+
async #writeAndMoveFile(filepath, valueOrStream) {
|
|
129
159
|
const tmpName = `${filepath}.tmp`;
|
|
130
|
-
await (0, import_promises.
|
|
160
|
+
const handle = await (0, import_promises.open)(tmpName, "w");
|
|
161
|
+
const isStream = valueOrStream instanceof ReadableStream;
|
|
162
|
+
const writer = handle.createWriteStream({ encoding: isStream ? null : "utf8", flush: true });
|
|
163
|
+
const { resolver, rejecter, promise: writePromise } = (0, import_general.createPromise)();
|
|
164
|
+
writer.on("finish", resolver);
|
|
165
|
+
writer.on("error", rejecter);
|
|
166
|
+
try {
|
|
167
|
+
if (isStream) {
|
|
168
|
+
const reader = valueOrStream.getReader();
|
|
169
|
+
while (true) {
|
|
170
|
+
const { value: chunk, done } = await reader.read();
|
|
171
|
+
if (chunk) {
|
|
172
|
+
if (!writer.write(chunk)) {
|
|
173
|
+
await new Promise((resolve) => writer.once("drain", resolve));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (done) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
writer.write(valueOrStream);
|
|
182
|
+
}
|
|
183
|
+
writer.end();
|
|
184
|
+
await writePromise;
|
|
185
|
+
} finally {
|
|
186
|
+
await handle.close();
|
|
187
|
+
}
|
|
131
188
|
await (0, import_promises.rename)(tmpName, filepath);
|
|
132
189
|
}
|
|
133
190
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/storage/StorageBackendDisk.ts"],
|
|
4
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["value"]
|
|
6
6
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/net/NodeJsNetwork.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,OAGG;AACP,SAA+B,yBAAyB;AACxD,SAAS,wBAAwB;AAEjC,MAAM,SAAS,OAAO,IAAI,aAAa;AAEhC,MAAM,sBAAsB,QAAQ;AAAA,EACvC,OAAO,0BAA0B,cAA0C;AACvE,UAAM,mBAAmB,kBAAkB,EAAE,YAAY;AACzD,QAAI,qBAAqB,OAAW,OAAM,IAAI,aAAa,sBAAsB,YAAY,EAAE;AAC/F,eAAW,QAAQ,kBAAkB;AACjC,UAAI,SAAS,GAAG,IAAI,GAAG;AACnB,eAAO,KAAK;AAAA,MAChB;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,iCAAiC,cAAkC,MAAuC;AAC7G,QAAI,MAAM;AACN,aAAO,CAAC,MAAS;AAAA,IACrB,OAAO;AACH,UAAI,0BAA0B,OAAO,QAAQ,kBAAkB,CAAC;AAChE,UAAI,iBAAiB,QAAW;AAC5B,kCAA0B,wBAAwB,OAAO,CAAC,CAAC,IAAI,MAAM,SAAS,YAAY;AAAA,MAC9F;AACA,YAAM,sBAAsB,wBAAwB,QAAQ,CAAC,CAACA,eAAc,gBAAgB,MAAM;AAC9F,YAAI,qBAAqB,OAAW,QAAO,CAAC;AAC5C,cAAM,OAAO,KAAK,gCAAgCA,eAAc,gBAAgB;AAChF,eAAO,SAAS,SAAY,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE;AAAA,MAClD,CAAC;AACD,UAAI,oBAAoB,WAAW,GAAG;AAClC,eAAO;AAAA,UACH,oCACI,iBAAiB,SAAY,kBAAkB,YAAY,KAAK,EACpE;AAAA,QACJ;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,OAAO,wBAAwB,cAA0C;AACrE,UAAM,mBAAmB,kBAAkB,EAAE,YAAY;AACzD,QAAI,qBAAqB,OAAW,OAAM,IAAI,aAAa,sBAAsB,YAAY,EAAE;AAC/F,WAAO,KAAK,gCAAgC,cAAc,gBAAgB;AAAA,EAC9E;AAAA,EAEA,OAAO,qBAAqB,IAAY;AAGpC,WAAO,KAAK,cAAc,IAAI,EAAE;AAAA,EACpC;AAAA,EAEA,OAAwB,gBAAgB,IAAI;AAAA,IACxC;AAAA,IACA,CAAC,OAAe,KAAK,gCAAgC,EAAE;AAAA,IACvD,IAAI,KAAK;AAAA,EACb;AAAA,EAEA,MAAe,QAAQ;AACnB,UAAM,cAAc,cAAc,MAAM;AAAA,EAC5C;AAAA,EAEA,OAAe,gCAAgC,IAAY;AACvD,QAAI,GAAG,SAAS,GAAG,GAAG;AAElB,aAAO,GAAG,MAAM,GAAG,EAAE,CAAC;AAAA,IAC1B,OAAO;AACH,YAAM,aAAa,kBAAkB;AACrC,iBAAW,QAAQ,YAAY;AAC3B,cAAM,gBAAgB,WAAW,IAAI;AACrC,mBAAW,EAAE,SAAS,QAAQ,KAAK,eAAe;AAC9C,cAAI,cAAc,IAAI,SAAS,OAAO,GAAG;AACrC,mBAAO,KAAK,gCAAgC,MAAM,aAAa;AAAA,UACnE;AAAA,QACJ;AAAA,MACJ;AACA,UAAI,OAAO,EAAE,GAAG;AACZ,YAAI,GAAG,WAAW,IAAI,GAAG;AAErB,iBAAO;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,OAAe,gCACX,cACA,mBACkB;AAClB,QAAI,QAAQ,aAAa,SAAS;AAC9B,aAAO;AAAA,IACX;AACA,QAAI,sBAAsB,OAAW,QAAO;AAC5C,WAAO,kBACF,KAAK,UAAQ,SAAS,GAAG,IAAI,KAAK,KAAK,QAAQ,WAAW,QAAQ,CAAC,GAClE,SAAS,SAAS;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,iBAAiB,gBAAoC,CAAC,GAAuB;AACzE,UAAM,SAAS,IAAI,MAAwB;AAC3C,UAAM,aAAa,kBAAkB;AACrC,eAAW,QAAQ,YAAY;AAC3B,YAAM,gBAAgB,WAAW,IAAI;AACrC,UAAI,cAAc,WAAW,EAAG;AAChC,UAAI,cAAc,CAAC,EAAE,SAAU;AAC/B,UAAI,OAAO,cAAc;AACzB,UAAI,cAAc,SAAS,GAAG;AAC1B,cAAM,WAAW,cAAc,KAAK,CAAC,EAAE,MAAM,QAAQ,MAAM,SAAS,OAAO;AAC3E,YAAI,aAAa,UAAa,SAAS,SAAS,QAAW;AACvD,iBAAO,SAAS;AAAA,QACpB;AAAA,MACJ;AACA,aAAO,KAAK,EAAE,MAAM,KAAK,CAAC;AAAA,IAC9B;AACA,WAAO;AAAA,EACX;AAAA,EAEA,SAAS,cAA2D;AAChE,UAAM,mBAAmB,kBAAkB,EAAE,YAAY;AACzD,QAAI,qBAAqB,OAAW,QAAO;AAC3C,UAAM,OAAO,iBAAiB,OAAO,UAAQ,SAAS,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,MAAM,OAAO;AAC5F,UAAM,OAAO,iBAAiB,OAAO,UAAQ,SAAS,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,MAAM,OAAO;AAC5F,WAAO,EAAE,KAAK,iBAAiB,CAAC,EAAE,KAAK,MAAM,KAAK;AAAA,EACtD;AAAA,EAES,iBAAiB,SAAiD;AACvE,WAAO,iBAAiB,OAAO,OAAO;AAAA,EAC1C;AACJ;AAEA,SAAS,SAAS,SAAiB,EAAE,OAAO,GAAyB;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["netInterface"]
|
|
6
6
|
}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Copyright 2022-2025 Matter.js Authors
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
export declare class StorageBackendDisk extends
|
|
6
|
+
import { Storage, SupportedStorageTypes } from "#general";
|
|
7
|
+
export declare class StorageBackendDisk extends Storage {
|
|
8
8
|
#private;
|
|
9
9
|
protected isInitialized: boolean;
|
|
10
10
|
constructor(path: string, clear?: boolean);
|
|
@@ -15,7 +15,10 @@ export declare class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
15
15
|
clear(): Promise<void>;
|
|
16
16
|
getContextBaseKey(contexts: string[], allowEmptyContext?: boolean): string;
|
|
17
17
|
buildStorageKey(contexts: string[], key: string): string;
|
|
18
|
+
has(contexts: string[], key: string): Promise<boolean>;
|
|
18
19
|
get<T extends SupportedStorageTypes>(contexts: string[], key: string): Promise<T | undefined>;
|
|
20
|
+
openBlob(contexts: string[], key: string): Promise<Blob>;
|
|
21
|
+
writeBlobFromStream(contexts: string[], key: string, stream: ReadableStream<Uint8Array>): Promise<void>;
|
|
19
22
|
set(contexts: string[], key: string, value: SupportedStorageTypes): Promise<void>;
|
|
20
23
|
set(contexts: string[], values: Record<string, SupportedStorageTypes>): Promise<void>;
|
|
21
24
|
delete(contexts: string[], key: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageBackendDisk.d.ts","sourceRoot":"","sources":["../../../src/storage/StorageBackendDisk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"StorageBackendDisk.d.ts","sourceRoot":"","sources":["../../../src/storage/StorageBackendDisk.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAKH,OAAO,EAEP,qBAAqB,EAExB,MAAM,UAAU,CAAC;AAOlB,qBAAa,kBAAmB,SAAQ,OAAO;;IAG3C,SAAS,CAAC,aAAa,UAAS;gBAGpB,IAAI,EAAE,MAAM,EAAE,KAAK,UAAQ;IAMvC,IAAI,WAAW,YAEd;IAEK,UAAU;IA2BV,KAAK;IAKX,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAInB,KAAK;IAMX,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,iBAAiB,UAAQ;IAY/D,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM;IAWhC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAe/D,GAAG,CAAC,CAAC,SAAS,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAkB7F,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC;IAIvF,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IACjF,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA2F/E,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM;IAM5C,yEAAyE;IACnE,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE;IAiBvB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE;IAmBzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;IAsB3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE;CAgBpC;AAED;;GAEG"}
|
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import {
|
|
7
|
+
createPromise,
|
|
7
8
|
fromJson,
|
|
8
9
|
Logger,
|
|
9
10
|
MatterAggregateError,
|
|
10
|
-
|
|
11
|
+
Storage,
|
|
11
12
|
StorageError,
|
|
12
13
|
toJson
|
|
13
14
|
} from "#general";
|
|
14
|
-
import {
|
|
15
|
+
import { openAsBlob } from "node:fs";
|
|
16
|
+
import { mkdir, open, readdir, readFile, rename, rm, stat } from "node:fs/promises";
|
|
15
17
|
import { join } from "node:path";
|
|
16
18
|
const logger = new Logger("StorageBackendDisk");
|
|
17
|
-
class StorageBackendDisk extends
|
|
19
|
+
class StorageBackendDisk extends Storage {
|
|
18
20
|
#path;
|
|
19
21
|
#clear;
|
|
20
22
|
isInitialized = false;
|
|
@@ -35,16 +37,18 @@ class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
35
37
|
this.isInitialized = true;
|
|
36
38
|
}
|
|
37
39
|
async #finishAllWrites(filename) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
if (filename !== void 0 && this.#writeFileBlocker.has(filename) || filename === void 0 && this.#writeFileBlocker.size > 0) {
|
|
41
|
+
for (let i = 0; i < 10; i++) {
|
|
42
|
+
await MatterAggregateError.allSettled(
|
|
43
|
+
filename !== void 0 ? [this.#writeFileBlocker.get(filename)] : this.#writeFileBlocker.values(),
|
|
44
|
+
"Error on finishing all file system writes to storage"
|
|
45
|
+
);
|
|
46
|
+
if (!this.#writeFileBlocker.size) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
45
49
|
}
|
|
50
|
+
await this.#fsyncStorageDir();
|
|
46
51
|
}
|
|
47
|
-
await this.#fsyncStorageDir();
|
|
48
52
|
}
|
|
49
53
|
async close() {
|
|
50
54
|
this.isInitialized = false;
|
|
@@ -72,10 +76,25 @@ class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
72
76
|
const rawName = `${contextKey}.${key}`;
|
|
73
77
|
return encodeURIComponent(rawName).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
|
|
74
78
|
}
|
|
79
|
+
async has(contexts, key) {
|
|
80
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
81
|
+
if (this.#writeFileBlocker.has(fileName)) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const stats = await stat(fileName);
|
|
86
|
+
return stats.isFile();
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (error.code === "ENOENT") return false;
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
75
92
|
async get(contexts, key) {
|
|
93
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
94
|
+
await this.#finishAllWrites(fileName);
|
|
76
95
|
let value;
|
|
77
96
|
try {
|
|
78
|
-
value = await readFile(
|
|
97
|
+
value = await readFile(fileName, "utf8");
|
|
79
98
|
} catch (error) {
|
|
80
99
|
if (error.code === "ENOENT") return void 0;
|
|
81
100
|
throw error;
|
|
@@ -86,6 +105,18 @@ class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
86
105
|
logger.error(`Failed to parse storage value for key ${key} in context ${contexts.join(".")}`);
|
|
87
106
|
}
|
|
88
107
|
}
|
|
108
|
+
async openBlob(contexts, key) {
|
|
109
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
110
|
+
await this.#finishAllWrites(fileName);
|
|
111
|
+
if (await this.has(contexts, key)) {
|
|
112
|
+
return await openAsBlob(fileName);
|
|
113
|
+
} else {
|
|
114
|
+
return new Blob();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
writeBlobFromStream(contexts, key, stream) {
|
|
118
|
+
return this.#writeFile(this.buildStorageKey(contexts, key), stream);
|
|
119
|
+
}
|
|
89
120
|
async set(contexts, keyOrValues, value) {
|
|
90
121
|
if (typeof keyOrValues === "string") {
|
|
91
122
|
return this.#writeFile(this.buildStorageKey(contexts, keyOrValues), toJson(value));
|
|
@@ -97,21 +128,48 @@ class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
97
128
|
await MatterAggregateError.allSettled(promises, "Error when writing values into filesystem storage");
|
|
98
129
|
}
|
|
99
130
|
/** According to Node.js documentation, writeFile is not atomic. This method ensures atomicity. */
|
|
100
|
-
async #writeFile(fileName,
|
|
131
|
+
async #writeFile(fileName, valueOrStream) {
|
|
101
132
|
const blocker = this.#writeFileBlocker.get(fileName);
|
|
102
133
|
if (blocker !== void 0) {
|
|
103
134
|
await blocker;
|
|
104
|
-
return this.#writeFile(fileName,
|
|
135
|
+
return this.#writeFile(fileName, valueOrStream);
|
|
105
136
|
}
|
|
106
|
-
const promise = this.#writeAndMoveFile(this.filePath(fileName),
|
|
137
|
+
const promise = this.#writeAndMoveFile(this.filePath(fileName), valueOrStream).finally(() => {
|
|
107
138
|
this.#writeFileBlocker.delete(fileName);
|
|
108
139
|
});
|
|
109
140
|
this.#writeFileBlocker.set(fileName, promise);
|
|
110
141
|
return promise;
|
|
111
142
|
}
|
|
112
|
-
async #writeAndMoveFile(filepath,
|
|
143
|
+
async #writeAndMoveFile(filepath, valueOrStream) {
|
|
113
144
|
const tmpName = `${filepath}.tmp`;
|
|
114
|
-
await
|
|
145
|
+
const handle = await open(tmpName, "w");
|
|
146
|
+
const isStream = valueOrStream instanceof ReadableStream;
|
|
147
|
+
const writer = handle.createWriteStream({ encoding: isStream ? null : "utf8", flush: true });
|
|
148
|
+
const { resolver, rejecter, promise: writePromise } = createPromise();
|
|
149
|
+
writer.on("finish", resolver);
|
|
150
|
+
writer.on("error", rejecter);
|
|
151
|
+
try {
|
|
152
|
+
if (isStream) {
|
|
153
|
+
const reader = valueOrStream.getReader();
|
|
154
|
+
while (true) {
|
|
155
|
+
const { value: chunk, done } = await reader.read();
|
|
156
|
+
if (chunk) {
|
|
157
|
+
if (!writer.write(chunk)) {
|
|
158
|
+
await new Promise((resolve) => writer.once("drain", resolve));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (done) {
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
writer.write(valueOrStream);
|
|
167
|
+
}
|
|
168
|
+
writer.end();
|
|
169
|
+
await writePromise;
|
|
170
|
+
} finally {
|
|
171
|
+
await handle.close();
|
|
172
|
+
}
|
|
115
173
|
await rename(tmpName, filepath);
|
|
116
174
|
}
|
|
117
175
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/storage/StorageBackendDisk.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,OACG;AACP,SAAS,OAAO,MAAM,SAAS,UAAU,QAAQ,IAAI,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": ["value"]
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/nodejs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
4
4
|
"description": "Node.js platform support for matter.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"url": "git+https://github.com/matter-js/matter.git"
|
|
26
26
|
},
|
|
27
27
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
28
|
+
"node": ">=20.0.0"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"clean": "matter-build clean",
|
|
@@ -44,17 +44,17 @@
|
|
|
44
44
|
"#*": "./src/*"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@matter/general": "0.
|
|
48
|
-
"@matter/node": "0.
|
|
49
|
-
"@matter/protocol": "0.
|
|
50
|
-
"@matter/types": "0.
|
|
47
|
+
"@matter/general": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
48
|
+
"@matter/node": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
49
|
+
"@matter/protocol": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
50
|
+
"@matter/types": "0.16.0-alpha.0-20250802-1af103e3d"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@matter/model": "0.
|
|
54
|
-
"@matter/protocol": "0.
|
|
55
|
-
"@matter/tools": "0.
|
|
56
|
-
"@matter/testing": "0.
|
|
57
|
-
"@project-chip/matter.js": "0.
|
|
53
|
+
"@matter/model": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
54
|
+
"@matter/protocol": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
55
|
+
"@matter/tools": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
56
|
+
"@matter/testing": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
57
|
+
"@project-chip/matter.js": "0.16.0-alpha.0-20250802-1af103e3d",
|
|
58
58
|
"@types/bytebuffer": "^5.0.49"
|
|
59
59
|
},
|
|
60
60
|
"files": [
|
package/src/net/NodeJsNetwork.ts
CHANGED
|
@@ -157,7 +157,5 @@ export class NodeJsNetwork extends Network {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
function familyIs(version: number, { family }: NetworkInterfaceInfo) {
|
|
160
|
-
|
|
161
|
-
// TODO: Remove when killing Node.js 18 support after EOL
|
|
162
|
-
return family === `IPv${version}` || `${family}` === `${version}`;
|
|
160
|
+
return family === `IPv${version}`;
|
|
163
161
|
}
|
|
@@ -5,20 +5,22 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
+
createPromise,
|
|
8
9
|
fromJson,
|
|
9
10
|
Logger,
|
|
10
11
|
MatterAggregateError,
|
|
11
|
-
|
|
12
|
+
Storage,
|
|
12
13
|
StorageError,
|
|
13
14
|
SupportedStorageTypes,
|
|
14
15
|
toJson,
|
|
15
16
|
} from "#general";
|
|
16
|
-
import {
|
|
17
|
+
import { openAsBlob } from "node:fs";
|
|
18
|
+
import { mkdir, open, readdir, readFile, rename, rm, stat } from "node:fs/promises";
|
|
17
19
|
import { join } from "node:path";
|
|
18
20
|
|
|
19
21
|
const logger = new Logger("StorageBackendDisk");
|
|
20
22
|
|
|
21
|
-
export class StorageBackendDisk extends
|
|
23
|
+
export class StorageBackendDisk extends Storage {
|
|
22
24
|
readonly #path: string;
|
|
23
25
|
readonly #clear: boolean;
|
|
24
26
|
protected isInitialized = false;
|
|
@@ -44,16 +46,21 @@ export class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
44
46
|
|
|
45
47
|
async #finishAllWrites(filename?: string) {
|
|
46
48
|
// Let's try max up to 10 times to finish all writes out there, otherwise something is strange
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
if (
|
|
50
|
+
(filename !== undefined && this.#writeFileBlocker.has(filename)) ||
|
|
51
|
+
(filename === undefined && this.#writeFileBlocker.size > 0)
|
|
52
|
+
) {
|
|
53
|
+
for (let i = 0; i < 10; i++) {
|
|
54
|
+
await MatterAggregateError.allSettled(
|
|
55
|
+
filename !== undefined ? [this.#writeFileBlocker.get(filename)] : this.#writeFileBlocker.values(),
|
|
56
|
+
"Error on finishing all file system writes to storage",
|
|
57
|
+
);
|
|
58
|
+
if (!this.#writeFileBlocker.size) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
54
61
|
}
|
|
62
|
+
await this.#fsyncStorageDir();
|
|
55
63
|
}
|
|
56
|
-
await this.#fsyncStorageDir();
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
async close() {
|
|
@@ -94,10 +101,28 @@ export class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
94
101
|
.replace(/\*/g, "%2A");
|
|
95
102
|
}
|
|
96
103
|
|
|
104
|
+
override async has(contexts: string[], key: string): Promise<boolean> {
|
|
105
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
106
|
+
if (this.#writeFileBlocker.has(fileName)) {
|
|
107
|
+
// We are writing that key right now, so yes it exists
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
const stats = await stat(fileName);
|
|
112
|
+
return stats.isFile();
|
|
113
|
+
} catch (error: any) {
|
|
114
|
+
if (error.code === "ENOENT") return false;
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
97
119
|
async get<T extends SupportedStorageTypes>(contexts: string[], key: string): Promise<T | undefined> {
|
|
120
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
121
|
+
await this.#finishAllWrites(fileName);
|
|
122
|
+
|
|
98
123
|
let value: string;
|
|
99
124
|
try {
|
|
100
|
-
value = await readFile(
|
|
125
|
+
value = await readFile(fileName, "utf8");
|
|
101
126
|
} catch (error: any) {
|
|
102
127
|
if (error.code === "ENOENT") return undefined;
|
|
103
128
|
throw error;
|
|
@@ -109,6 +134,20 @@ export class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
109
134
|
}
|
|
110
135
|
}
|
|
111
136
|
|
|
137
|
+
async openBlob(contexts: string[], key: string): Promise<Blob> {
|
|
138
|
+
const fileName = this.filePath(this.buildStorageKey(contexts, key));
|
|
139
|
+
await this.#finishAllWrites(fileName);
|
|
140
|
+
if (await this.has(contexts, key)) {
|
|
141
|
+
return await openAsBlob(fileName);
|
|
142
|
+
} else {
|
|
143
|
+
return new Blob();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
writeBlobFromStream(contexts: string[], key: string, stream: ReadableStream<Uint8Array>) {
|
|
148
|
+
return this.#writeFile(this.buildStorageKey(contexts, key), stream);
|
|
149
|
+
}
|
|
150
|
+
|
|
112
151
|
set(contexts: string[], key: string, value: SupportedStorageTypes): Promise<void>;
|
|
113
152
|
set(contexts: string[], values: Record<string, SupportedStorageTypes>): Promise<void>;
|
|
114
153
|
async set(
|
|
@@ -128,15 +167,14 @@ export class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
128
167
|
}
|
|
129
168
|
|
|
130
169
|
/** According to Node.js documentation, writeFile is not atomic. This method ensures atomicity. */
|
|
131
|
-
async #writeFile(fileName: string,
|
|
170
|
+
async #writeFile(fileName: string, valueOrStream: string | ReadableStream<Uint8Array>): Promise<void> {
|
|
132
171
|
const blocker = this.#writeFileBlocker.get(fileName);
|
|
133
172
|
if (blocker !== undefined) {
|
|
134
173
|
await blocker;
|
|
135
|
-
return this.#writeFile(fileName,
|
|
174
|
+
return this.#writeFile(fileName, valueOrStream);
|
|
136
175
|
}
|
|
137
176
|
|
|
138
|
-
|
|
139
|
-
const promise = this.#writeAndMoveFile(this.filePath(fileName), value).finally(() => {
|
|
177
|
+
const promise = this.#writeAndMoveFile(this.filePath(fileName), valueOrStream).finally(() => {
|
|
140
178
|
this.#writeFileBlocker.delete(fileName);
|
|
141
179
|
});
|
|
142
180
|
this.#writeFileBlocker.set(fileName, promise);
|
|
@@ -144,9 +182,41 @@ export class StorageBackendDisk extends MaybeAsyncStorage {
|
|
|
144
182
|
return promise;
|
|
145
183
|
}
|
|
146
184
|
|
|
147
|
-
async #writeAndMoveFile(filepath: string,
|
|
185
|
+
async #writeAndMoveFile(filepath: string, valueOrStream: string | ReadableStream<Uint8Array>): Promise<void> {
|
|
148
186
|
const tmpName = `${filepath}.tmp`;
|
|
149
|
-
await
|
|
187
|
+
const handle = await open(tmpName, "w");
|
|
188
|
+
const isStream = valueOrStream instanceof ReadableStream;
|
|
189
|
+
const writer = handle.createWriteStream({ encoding: isStream ? null : "utf8", flush: true });
|
|
190
|
+
|
|
191
|
+
const { resolver, rejecter, promise: writePromise } = createPromise<void>();
|
|
192
|
+
writer.on("finish", resolver);
|
|
193
|
+
writer.on("error", rejecter);
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
if (isStream) {
|
|
197
|
+
const reader = valueOrStream.getReader();
|
|
198
|
+
while (true) {
|
|
199
|
+
const { value: chunk, done } = await reader.read();
|
|
200
|
+
if (chunk) {
|
|
201
|
+
if (!writer.write(chunk)) {
|
|
202
|
+
// Backpressure: wait for the buffer to drain.
|
|
203
|
+
await new Promise<void>(resolve => writer.once("drain", resolve));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
if (done) {
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
writer.write(valueOrStream);
|
|
212
|
+
}
|
|
213
|
+
writer.end();
|
|
214
|
+
|
|
215
|
+
await writePromise;
|
|
216
|
+
} finally {
|
|
217
|
+
await handle.close();
|
|
218
|
+
}
|
|
219
|
+
|
|
150
220
|
await rename(tmpName, filepath);
|
|
151
221
|
}
|
|
152
222
|
|