@serveryyswys/node.operit 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILTINS.json +150 -0
- package/LICENSE +201 -674
- package/NOTICE +17 -0
- package/README.md +10 -0
- package/dist/console.d.ts +60 -0
- package/dist/console.js +193 -0
- package/dist/diagnostics_channel.d.ts +36 -0
- package/dist/diagnostics_channel.js +76 -0
- package/dist/fs/promises.d.ts +2 -1
- package/dist/fs/promises.js +1 -0
- package/dist/index.d.ts +424 -25
- package/dist/index.js +38 -2
- package/dist/lib/bridge.js +3 -1
- package/dist/lib/console-types.d.ts +12 -0
- package/dist/lib/console-types.js +2 -0
- package/dist/lib/diagnostics-channel-types.d.ts +7 -0
- package/dist/lib/diagnostics-channel-types.js +2 -0
- package/dist/lib/stream-consumers-types.d.ts +4 -0
- package/dist/lib/stream-consumers-types.js +2 -0
- package/dist/lib/util-types.d.ts +13 -0
- package/dist/lib/util-types.js +2 -0
- package/dist/lib/v8-types.d.ts +30 -0
- package/dist/lib/v8-types.js +2 -0
- package/dist/module.js +30 -0
- package/dist/punycode.d.ts +22 -0
- package/dist/punycode.js +53 -0
- package/dist/stream/consumers.d.ts +24 -0
- package/dist/stream/consumers.js +75 -0
- package/dist/sys.d.ts +8 -0
- package/dist/sys.js +9 -0
- package/dist/util/types.d.ts +16 -0
- package/dist/util/types.js +9 -0
- package/dist/util.d.ts +1 -12
- package/dist/util.js +12 -0
- package/dist/v8.d.ts +25 -0
- package/dist/v8.js +127 -0
- package/package.json +14 -12
package/NOTICE
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
@serveryyswys/node.operit
|
|
2
|
+
Copyright 2026 serveryyswys
|
|
3
|
+
|
|
4
|
+
This product includes software developed by serveryyswys
|
|
5
|
+
(https://www.serveryyswys.top/).
|
|
6
|
+
|
|
7
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
|
+
you may not use this file except in compliance with the License.
|
|
9
|
+
You may obtain a copy of the License at
|
|
10
|
+
|
|
11
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
|
|
13
|
+
Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
See the License for the specific language governing permissions and
|
|
17
|
+
limitations under the License.
|
package/README.md
CHANGED
|
@@ -299,4 +299,14 @@ globalThis.Buffer = require('<rel>/node_modules/@serveryyswys/node.operit/dist/
|
|
|
299
299
|
读流是"按需整块读 + 按 `highWaterMark` 切片"(**没有流式的内存特性**),`'open'` 事件参数为 `null`(无真实 fd)
|
|
300
300
|
- **Java 驱动尚未在真机验证**;已知近似:`atime`/`ctime`/`birthtime` 取 `mtime`、
|
|
301
301
|
`mode` 为按类型的默认值、`readdir` 不区分符号链接、fd 系列(`open`/`read`/`write`/`close`)未实现
|
|
302
|
+
- `console`:**partial** —— 完整的 Node console API;**输出与 Node 逐字节对拍通过**(含 `%s`/`%d`/`%j`、
|
|
303
|
+
`assert` 只打印不抛错、`group` 缩进)。差异:不指定输出流时写 prelude console;`table` 只覆盖常用形态
|
|
304
|
+
- `util/types` / `sys`:**ready** —— 分别是 `util.types` 与 `util` 的同一个对象(与 Node 一致)
|
|
305
|
+
- `punycode`:**ready** —— 各方法与 Node 的 punycode 对拍一致(含 `ucs2`)
|
|
306
|
+
- `stream/consumers`:**partial** —— `buffer`/`text`/`json`/`arrayBuffer` 可用;
|
|
307
|
+
`blob` 显式抛 `ONJ_UNSUPPORTED`(运行时不提供 Blob)
|
|
308
|
+
- `diagnostics_channel`:**partial** —— 发布订阅完整可用;依赖 AsyncLocalStorage 的
|
|
309
|
+
`bindStore`/`unbindStore`/`runStores` 与 `tracingChannel` 显式抛 `ONJ_UNSUPPORTED`
|
|
310
|
+
- `v8`:**partial** —— 堆统计字段名与 Node 一致,但取的是 **JVM 堆**;
|
|
311
|
+
`serialize`/`deserialize`/`setFlagsFromString` 等 V8 专有能力显式抛 `ONJ_UNSUPPORTED`
|
|
302
312
|
- 其余见 `BUILTINS.json`
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { WriteStreamLike } from './lib/console-types';
|
|
2
|
+
declare class Console {
|
|
3
|
+
constructor(stdout?: unknown, stderr?: unknown);
|
|
4
|
+
readonly stdout: WriteStreamLike | null;
|
|
5
|
+
readonly stderr: WriteStreamLike | null;
|
|
6
|
+
readonly counts: Map<string, number>;
|
|
7
|
+
readonly timers: Map<string, number>;
|
|
8
|
+
indent: string;
|
|
9
|
+
emit(target: WriteStreamLike | null, channel: 'log' | 'info' | 'warn' | 'error', text: string): void;
|
|
10
|
+
line(...args: unknown[]): string;
|
|
11
|
+
log(...args: unknown[]): void;
|
|
12
|
+
info(...args: unknown[]): void;
|
|
13
|
+
debug(...args: unknown[]): void;
|
|
14
|
+
warn(...args: unknown[]): void;
|
|
15
|
+
error(...args: unknown[]): void;
|
|
16
|
+
/** Node 的 console.assert 只在断言失败时输出,且不抛错。 */
|
|
17
|
+
assert(value: unknown, ...args: unknown[]): void;
|
|
18
|
+
dir(value: unknown, options?: unknown): void;
|
|
19
|
+
count(label?: string): void;
|
|
20
|
+
countReset(label?: string): void;
|
|
21
|
+
time(label?: string): void;
|
|
22
|
+
timeEnd(label?: string): void;
|
|
23
|
+
timeLog(label?: string, ...args: unknown[]): void;
|
|
24
|
+
trace(...args: unknown[]): void;
|
|
25
|
+
table(data: unknown, columns?: readonly string[]): void;
|
|
26
|
+
group(...args: unknown[]): void;
|
|
27
|
+
groupCollapsed(...args: unknown[]): void;
|
|
28
|
+
groupEnd(): void;
|
|
29
|
+
/** 非 TTY 下与 Node 一样什么都不做。 */
|
|
30
|
+
clear(): void;
|
|
31
|
+
profile(): void;
|
|
32
|
+
profileEnd(): void;
|
|
33
|
+
timeStamp(): void;
|
|
34
|
+
}
|
|
35
|
+
/** Node 的 require('console') 给的是实例,并把 Console 挂在它上面。 */
|
|
36
|
+
declare const consoleModule: {
|
|
37
|
+
Console: typeof Console;
|
|
38
|
+
log: (...args: unknown[]) => void;
|
|
39
|
+
info: (...args: unknown[]) => void;
|
|
40
|
+
debug: (...args: unknown[]) => void;
|
|
41
|
+
warn: (...args: unknown[]) => void;
|
|
42
|
+
error: (...args: unknown[]) => void;
|
|
43
|
+
assert: (value: unknown, ...args: unknown[]) => void;
|
|
44
|
+
dir: (value: unknown, options?: unknown) => void;
|
|
45
|
+
count: (label?: string) => void;
|
|
46
|
+
countReset: (label?: string) => void;
|
|
47
|
+
time: (label?: string) => void;
|
|
48
|
+
timeEnd: (label?: string) => void;
|
|
49
|
+
timeLog: (label?: string, ...args: unknown[]) => void;
|
|
50
|
+
trace: (...args: unknown[]) => void;
|
|
51
|
+
table: (data: unknown, columns?: readonly string[]) => void;
|
|
52
|
+
group: (...args: unknown[]) => void;
|
|
53
|
+
groupCollapsed: (...args: unknown[]) => void;
|
|
54
|
+
groupEnd: () => void;
|
|
55
|
+
clear: () => void;
|
|
56
|
+
profile: () => void;
|
|
57
|
+
profileEnd: () => void;
|
|
58
|
+
timeStamp: () => void;
|
|
59
|
+
};
|
|
60
|
+
export = consoleModule;
|
package/dist/console.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* console。
|
|
4
|
+
*
|
|
5
|
+
* 沙箱的 prelude 已经在每个模块作用域里提供了一个 console(JsExecutionScriptBuilder.kt:53),
|
|
6
|
+
* 但它只有 log / info / warn / error 四个方法,而且是 `arguments.join(' ')` ——
|
|
7
|
+
* 也就是 `console.log('%s', 'x')` 会原样打印 "%s x",与 Node 不同。
|
|
8
|
+
*
|
|
9
|
+
* 本模块在这之上补齐 Node 的 console API,并改用 util.format 格式化。
|
|
10
|
+
*
|
|
11
|
+
* 与 Node 的差异(都写进 BUILTINS.json):
|
|
12
|
+
* - 不指定输出流时走 prelude console(Node 是 process.stdout / stderr);
|
|
13
|
+
* - clear / profile / profileEnd / timeStamp 与 Node 在非 TTY 下一样是空操作;
|
|
14
|
+
* - table 只实现 Node 的常用形态(对象数组 / 单对象),不做列的自动推算。
|
|
15
|
+
*/
|
|
16
|
+
const utilModule = require("./util");
|
|
17
|
+
const hostConsole = console;
|
|
18
|
+
function hasWrite(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && typeof value.write === 'function';
|
|
20
|
+
}
|
|
21
|
+
function nowMillis() {
|
|
22
|
+
return typeof performance === 'object' && performance !== null ? performance.now() : Date.now();
|
|
23
|
+
}
|
|
24
|
+
function describeTime(milliseconds) {
|
|
25
|
+
return milliseconds.toFixed(3) + 'ms';
|
|
26
|
+
}
|
|
27
|
+
class Console {
|
|
28
|
+
constructor(stdout, stderr) {
|
|
29
|
+
this.counts = new Map();
|
|
30
|
+
this.timers = new Map();
|
|
31
|
+
this.indent = '';
|
|
32
|
+
this.stdout = hasWrite(stdout) ? stdout : null;
|
|
33
|
+
this.stderr = hasWrite(stderr) ? stderr : null;
|
|
34
|
+
}
|
|
35
|
+
emit(target, channel, text) {
|
|
36
|
+
if (target !== null) {
|
|
37
|
+
target.write(text + '\n');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
hostConsole[channel](text);
|
|
41
|
+
}
|
|
42
|
+
line(...args) {
|
|
43
|
+
return this.indent + utilModule.format.apply(null, args);
|
|
44
|
+
}
|
|
45
|
+
log(...args) {
|
|
46
|
+
this.emit(this.stdout, 'log', this.line(...args));
|
|
47
|
+
}
|
|
48
|
+
info(...args) {
|
|
49
|
+
this.emit(this.stdout, 'info', this.line(...args));
|
|
50
|
+
}
|
|
51
|
+
debug(...args) {
|
|
52
|
+
this.emit(this.stdout, 'log', this.line(...args));
|
|
53
|
+
}
|
|
54
|
+
warn(...args) {
|
|
55
|
+
this.emit(this.stderr, 'warn', this.line(...args));
|
|
56
|
+
}
|
|
57
|
+
error(...args) {
|
|
58
|
+
this.emit(this.stderr, 'error', this.line(...args));
|
|
59
|
+
}
|
|
60
|
+
/** Node 的 console.assert 只在断言失败时输出,且不抛错。 */
|
|
61
|
+
assert(value, ...args) {
|
|
62
|
+
if (value) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const detail = args.length === 0 ? '' : ': ' + utilModule.format.apply(null, args);
|
|
66
|
+
this.emit(this.stderr, 'error', 'Assertion failed' + detail);
|
|
67
|
+
}
|
|
68
|
+
dir(value, options) {
|
|
69
|
+
this.emit(this.stdout, 'log', this.indent + utilModule.inspect(value, options));
|
|
70
|
+
}
|
|
71
|
+
count(label) {
|
|
72
|
+
const key = label === undefined ? 'default' : String(label);
|
|
73
|
+
const next = (this.counts.get(key) ?? 0) + 1;
|
|
74
|
+
this.counts.set(key, next);
|
|
75
|
+
this.emit(this.stdout, 'log', this.indent + key + ': ' + next);
|
|
76
|
+
}
|
|
77
|
+
countReset(label) {
|
|
78
|
+
const key = label === undefined ? 'default' : String(label);
|
|
79
|
+
this.counts.set(key, 0);
|
|
80
|
+
this.emit(this.stdout, 'log', this.indent + key + ': 0');
|
|
81
|
+
}
|
|
82
|
+
time(label) {
|
|
83
|
+
this.timers.set(label === undefined ? 'default' : String(label), nowMillis());
|
|
84
|
+
}
|
|
85
|
+
timeEnd(label) {
|
|
86
|
+
const key = label === undefined ? 'default' : String(label);
|
|
87
|
+
const started = this.timers.get(key);
|
|
88
|
+
if (started === undefined) {
|
|
89
|
+
this.emit(this.stderr, 'warn', 'Warning: No such label \'' + key + '\' for console.timeEnd()');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.timers.delete(key);
|
|
93
|
+
this.emit(this.stdout, 'log', this.indent + key + ': ' + describeTime(nowMillis() - started));
|
|
94
|
+
}
|
|
95
|
+
timeLog(label, ...args) {
|
|
96
|
+
const key = label === undefined ? 'default' : String(label);
|
|
97
|
+
const started = this.timers.get(key);
|
|
98
|
+
if (started === undefined) {
|
|
99
|
+
this.emit(this.stderr, 'warn', 'Warning: No such label \'' + key + '\' for console.timeLog()');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const suffix = args.length === 0 ? '' : ' ' + utilModule.format.apply(null, args);
|
|
103
|
+
this.emit(this.stdout, 'log', this.indent + key + ': ' + describeTime(nowMillis() - started) + suffix);
|
|
104
|
+
}
|
|
105
|
+
trace(...args) {
|
|
106
|
+
const message = args.length === 0 ? 'Trace' : 'Trace: ' + utilModule.format.apply(null, args);
|
|
107
|
+
const stack = new Error(message).stack;
|
|
108
|
+
this.emit(this.stderr, 'error', this.indent + message + (stack === undefined ? '' : '\n' + stack));
|
|
109
|
+
}
|
|
110
|
+
table(data, columns) {
|
|
111
|
+
if (data === null || typeof data !== 'object') {
|
|
112
|
+
this.log(data);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const rows = Array.isArray(data) ? data : [data];
|
|
116
|
+
const keys = [];
|
|
117
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
118
|
+
const row = rows[index];
|
|
119
|
+
if (row === null || typeof row !== 'object') {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const names = columns === undefined ? Object.keys(row) : columns;
|
|
123
|
+
for (let name = 0; name < names.length; name += 1) {
|
|
124
|
+
if (keys.indexOf(names[name]) < 0) {
|
|
125
|
+
keys.push(names[name]);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const lines = ['┌─────────┬' + keys.map(() => '──────────').join('┬') + '┐'];
|
|
130
|
+
lines.push('│ (index) │' + keys.map((key) => ' ' + key.padEnd(8) + ' │').join(''));
|
|
131
|
+
for (let index = 0; index < rows.length; index += 1) {
|
|
132
|
+
const row = rows[index];
|
|
133
|
+
const cells = keys.map((key) => ' ' + utilModule.inspect(row === null || row === undefined ? undefined : row[key]).slice(0, 8).padEnd(8) + ' │');
|
|
134
|
+
lines.push('│ ' + String(index).padEnd(7) + ' │' + cells.join(''));
|
|
135
|
+
}
|
|
136
|
+
lines.push('└─────────┴' + keys.map(() => '──────────').join('┴') + '┘');
|
|
137
|
+
this.emit(this.stdout, 'log', this.indent + lines.join('\n' + this.indent));
|
|
138
|
+
}
|
|
139
|
+
group(...args) {
|
|
140
|
+
if (args.length > 0) {
|
|
141
|
+
this.log(...args);
|
|
142
|
+
}
|
|
143
|
+
this.indent += ' ';
|
|
144
|
+
}
|
|
145
|
+
groupCollapsed(...args) {
|
|
146
|
+
this.group(...args);
|
|
147
|
+
}
|
|
148
|
+
groupEnd() {
|
|
149
|
+
if (this.indent.length >= 2) {
|
|
150
|
+
this.indent = this.indent.slice(0, -2);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/** 非 TTY 下与 Node 一样什么都不做。 */
|
|
154
|
+
clear() {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
profile() {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
profileEnd() {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
timeStamp() {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const consoleInstance = new Console();
|
|
168
|
+
/** Node 的 require('console') 给的是实例,并把 Console 挂在它上面。 */
|
|
169
|
+
const consoleModule = {
|
|
170
|
+
Console: Console,
|
|
171
|
+
log: consoleInstance.log.bind(consoleInstance),
|
|
172
|
+
info: consoleInstance.info.bind(consoleInstance),
|
|
173
|
+
debug: consoleInstance.debug.bind(consoleInstance),
|
|
174
|
+
warn: consoleInstance.warn.bind(consoleInstance),
|
|
175
|
+
error: consoleInstance.error.bind(consoleInstance),
|
|
176
|
+
assert: consoleInstance.assert.bind(consoleInstance),
|
|
177
|
+
dir: consoleInstance.dir.bind(consoleInstance),
|
|
178
|
+
count: consoleInstance.count.bind(consoleInstance),
|
|
179
|
+
countReset: consoleInstance.countReset.bind(consoleInstance),
|
|
180
|
+
time: consoleInstance.time.bind(consoleInstance),
|
|
181
|
+
timeEnd: consoleInstance.timeEnd.bind(consoleInstance),
|
|
182
|
+
timeLog: consoleInstance.timeLog.bind(consoleInstance),
|
|
183
|
+
trace: consoleInstance.trace.bind(consoleInstance),
|
|
184
|
+
table: consoleInstance.table.bind(consoleInstance),
|
|
185
|
+
group: consoleInstance.group.bind(consoleInstance),
|
|
186
|
+
groupCollapsed: consoleInstance.groupCollapsed.bind(consoleInstance),
|
|
187
|
+
groupEnd: consoleInstance.groupEnd.bind(consoleInstance),
|
|
188
|
+
clear: consoleInstance.clear.bind(consoleInstance),
|
|
189
|
+
profile: consoleInstance.profile.bind(consoleInstance),
|
|
190
|
+
profileEnd: consoleInstance.profileEnd.bind(consoleInstance),
|
|
191
|
+
timeStamp: consoleInstance.timeStamp.bind(consoleInstance)
|
|
192
|
+
};
|
|
193
|
+
module.exports = consoleModule;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* diagnostics_channel。
|
|
3
|
+
*
|
|
4
|
+
* 它的语义是纯粹的「按名字的发布订阅」,本身不依赖任何平台能力,所以可以完整实现。
|
|
5
|
+
*
|
|
6
|
+
* 与 Node 的差异(都写进 BUILTINS.json):
|
|
7
|
+
* - Channel 的 bindStore / unbindStore / runStores 依赖 AsyncLocalStorage(需要 async_hooks),
|
|
8
|
+
* Android 的 QuickJS 运行时没有物化这些钩子,所以这三个方法显式抛 ONJ_UNSUPPORTED,
|
|
9
|
+
* 而不是给一个"看着像但语义不对"的空实现;
|
|
10
|
+
* - tracingChannel 未实现(依赖上面那组 API),同样显式拒绝。
|
|
11
|
+
*/
|
|
12
|
+
import { Subscriber, ChannelStore } from './lib/diagnostics-channel-types';
|
|
13
|
+
declare class Channel {
|
|
14
|
+
constructor(name: string);
|
|
15
|
+
readonly name: string;
|
|
16
|
+
subscribers: Subscriber[];
|
|
17
|
+
get hasSubscribers(): boolean;
|
|
18
|
+
subscribe(onMessage: Subscriber): void;
|
|
19
|
+
unsubscribe(onMessage: Subscriber): void;
|
|
20
|
+
publish(message: unknown): void;
|
|
21
|
+
bindStore(_store: ChannelStore, _transform?: unknown): void;
|
|
22
|
+
unbindStore(_store: ChannelStore): void;
|
|
23
|
+
runStores(_context: unknown, _fn: Function, _thisArg?: unknown, ..._args: unknown[]): unknown;
|
|
24
|
+
}
|
|
25
|
+
declare function channel(name: string): Channel;
|
|
26
|
+
declare function hasSubscribers(name: string): boolean;
|
|
27
|
+
declare function subscribe(name: string, onMessage: Subscriber): void;
|
|
28
|
+
declare function unsubscribe(name: string, onMessage: Subscriber): void;
|
|
29
|
+
declare const diagnosticsChannel: {
|
|
30
|
+
channel: typeof channel;
|
|
31
|
+
hasSubscribers: typeof hasSubscribers;
|
|
32
|
+
subscribe: typeof subscribe;
|
|
33
|
+
unsubscribe: typeof unsubscribe;
|
|
34
|
+
Channel: typeof Channel;
|
|
35
|
+
};
|
|
36
|
+
export = diagnosticsChannel;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const channels = new Map();
|
|
3
|
+
class Channel {
|
|
4
|
+
constructor(name) {
|
|
5
|
+
this.subscribers = [];
|
|
6
|
+
this.name = name;
|
|
7
|
+
}
|
|
8
|
+
get hasSubscribers() {
|
|
9
|
+
return this.subscribers.length > 0;
|
|
10
|
+
}
|
|
11
|
+
subscribe(onMessage) {
|
|
12
|
+
if (typeof onMessage !== 'function') {
|
|
13
|
+
throw new TypeError('The "onMessage" argument must be of type function.');
|
|
14
|
+
}
|
|
15
|
+
if (this.subscribers.indexOf(onMessage) < 0) {
|
|
16
|
+
this.subscribers.push(onMessage);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
unsubscribe(onMessage) {
|
|
20
|
+
const index = this.subscribers.indexOf(onMessage);
|
|
21
|
+
if (index >= 0) {
|
|
22
|
+
this.subscribers.splice(index, 1);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
publish(message) {
|
|
26
|
+
const listeners = this.subscribers.slice();
|
|
27
|
+
for (let index = 0; index < listeners.length; index += 1) {
|
|
28
|
+
listeners[index](message, this.name);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
bindStore(_store, _transform) {
|
|
32
|
+
throw onjUnsupported('diagnostics_channel.Channel.bindStore');
|
|
33
|
+
}
|
|
34
|
+
unbindStore(_store) {
|
|
35
|
+
throw onjUnsupported('diagnostics_channel.Channel.unbindStore');
|
|
36
|
+
}
|
|
37
|
+
runStores(_context, _fn, _thisArg, ..._args) {
|
|
38
|
+
throw onjUnsupported('diagnostics_channel.Channel.runStores');
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function onjUnsupported(feature) {
|
|
42
|
+
const failure = new Error(feature + ' 需要 AsyncLocalStorage(async_hooks),Android 的 QuickJS 运行时不提供异步钩子。');
|
|
43
|
+
failure.code = 'ONJ_UNSUPPORTED';
|
|
44
|
+
return failure;
|
|
45
|
+
}
|
|
46
|
+
function channel(name) {
|
|
47
|
+
if (typeof name !== 'string' && typeof name !== 'symbol') {
|
|
48
|
+
throw new TypeError('The "channel" argument must be of type string or symbol.');
|
|
49
|
+
}
|
|
50
|
+
const key = String(name);
|
|
51
|
+
const existing = channels.get(key);
|
|
52
|
+
if (existing !== undefined) {
|
|
53
|
+
return existing;
|
|
54
|
+
}
|
|
55
|
+
const created = new Channel(key);
|
|
56
|
+
channels.set(key, created);
|
|
57
|
+
return created;
|
|
58
|
+
}
|
|
59
|
+
function hasSubscribers(name) {
|
|
60
|
+
const existing = channels.get(String(name));
|
|
61
|
+
return existing !== undefined && existing.hasSubscribers;
|
|
62
|
+
}
|
|
63
|
+
function subscribe(name, onMessage) {
|
|
64
|
+
channel(name).subscribe(onMessage);
|
|
65
|
+
}
|
|
66
|
+
function unsubscribe(name, onMessage) {
|
|
67
|
+
channel(name).unsubscribe(onMessage);
|
|
68
|
+
}
|
|
69
|
+
const diagnosticsChannel = {
|
|
70
|
+
channel: channel,
|
|
71
|
+
hasSubscribers: hasSubscribers,
|
|
72
|
+
subscribe: subscribe,
|
|
73
|
+
unsubscribe: unsubscribe,
|
|
74
|
+
Channel: Channel
|
|
75
|
+
};
|
|
76
|
+
module.exports = diagnosticsChannel;
|
package/dist/fs/promises.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ declare class FileHandle {
|
|
|
3
3
|
readonly fd: number;
|
|
4
4
|
closed: boolean;
|
|
5
5
|
constructor(fd: number);
|
|
6
|
-
private
|
|
6
|
+
/** 公开而非 private:FileHandle 会随 fs/promises 一起被聚合导出,TS 不允许导出型别含私有成员(TS4094)。 */
|
|
7
|
+
ensureOpen(): void;
|
|
7
8
|
/** Node 的 FileHandle.read 返回 { bytesRead, buffer },不是裸数字。 */
|
|
8
9
|
read(buffer: Uint8Array, offset?: number, length?: number, position?: number | null): Promise<{
|
|
9
10
|
bytesRead: number;
|
package/dist/fs/promises.js
CHANGED