@vobs/logger 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,170 +1,38 @@
1
- 'use strict';
2
-
1
+ var __VOBS_CJS_FILE_URL = require("url").pathToFileURL(__filename).href;
2
+ "use strict";
3
3
  var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
7
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
-
6
- // packages/reactivity/src/debug.ts
7
- var activeDebugHooks = null;
8
- function hasDebugHooks() {
9
- return activeDebugHooks !== null;
10
- }
11
- __name(hasDebugHooks, "hasDebugHooks");
12
- function invokeDebug(name, ...args) {
13
- return;
14
- }
15
- __name(invokeDebug, "invokeDebug");
16
-
17
- // packages/reactivity/src/owner.ts
18
- var currentOwner = null;
19
- function getCurrentOwner() {
20
- return currentOwner;
21
- }
22
- __name(getCurrentOwner, "getCurrentOwner");
23
- function onDispose(cleanup) {
24
- throw new Error("Vobs: onDispose \u5FC5\u987B\u5728 Owner \u4F5C\u7528\u57DF\u5185\u8C03\u7528");
25
- }
26
- __name(onDispose, "onDispose");
27
-
28
- // packages/reactivity/src/scheduler.ts
29
- var _Scheduler = class _Scheduler {
30
- constructor() {
31
- this.dirtyEffects = /* @__PURE__ */ new Set();
32
- this.lowPriorityEffects = /* @__PURE__ */ new Set();
33
- // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。
34
- this.normalBuffer = [];
35
- this.lowBuffer = [];
36
- this.flushing = false;
37
- this.scheduled = false;
38
- this.batchDepth = 0;
39
- }
40
- schedule(effect2) {
41
- if (effect2.disposed) return;
42
- this.dirtyEffects.add(effect2);
43
- this.lowPriorityEffects.delete(effect2);
44
- this.ensureScheduled();
45
- }
46
- /** Queue an effect behind normal updates while preserving deterministic order. */
47
- scheduleLow(effect2) {
48
- if (effect2.disposed) return;
49
- if (!this.dirtyEffects.has(effect2)) this.lowPriorityEffects.add(effect2);
50
- this.ensureScheduled();
51
- }
52
- ensureScheduled() {
53
- if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {
54
- this.scheduled = true;
55
- queueMicrotask(() => {
56
- this.scheduled = false;
57
- this.flush();
58
- });
59
- }
60
- }
61
- remove(effect2) {
62
- this.dirtyEffects.delete(effect2);
63
- this.lowPriorityEffects.delete(effect2);
64
- }
65
- batch(fn) {
66
- this.batchDepth++;
67
- try {
68
- return fn();
69
- } finally {
70
- this.batchDepth--;
71
- if (this.batchDepth === 0) this.flush();
72
- }
73
- }
74
- flush() {
75
- if (this.flushing || this.batchDepth > 0) return;
76
- this.flushing = true;
77
- let rounds = 0;
78
- let firstError;
79
- let hasError = false;
80
- try {
81
- while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {
82
- if (++rounds > 100) {
83
- this.dirtyEffects.clear();
84
- this.lowPriorityEffects.clear();
85
- throw new Error("Vobs: \u54CD\u5E94\u5F0F\u66F4\u65B0\u8D85\u8FC7 100 \u8F6E\uFF0C\u53EF\u80FD\u5B58\u5728\u5FAA\u73AF\u4F9D\u8D56");
86
- }
87
- this.collectRunnable(this.dirtyEffects, this.normalBuffer);
88
- this.collectRunnable(this.lowPriorityEffects, this.lowBuffer);
89
- sortEffects(this.normalBuffer);
90
- sortEffects(this.lowBuffer);
91
- for (const effect2 of this.normalBuffer) {
92
- try {
93
- effect2.run();
94
- } catch (error) {
95
- if (!hasError) {
96
- firstError = error;
97
- hasError = true;
98
- }
99
- }
100
- }
101
- for (const effect2 of this.lowBuffer) {
102
- try {
103
- effect2.run();
104
- } catch (error) {
105
- if (!hasError) {
106
- firstError = error;
107
- hasError = true;
108
- }
109
- }
110
- }
111
- this.normalBuffer.length = 0;
112
- this.lowBuffer.length = 0;
113
- }
114
- } finally {
115
- this.normalBuffer.length = 0;
116
- this.lowBuffer.length = 0;
117
- this.flushing = false;
118
- }
119
- if (hasError) throw firstError;
120
- }
121
- /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */
122
- collectRunnable(source, target) {
123
- for (const effect2 of source) {
124
- if (!effect2.disposed) target.push(effect2);
125
- }
126
- source.clear();
127
- }
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
128
11
  };
129
- __name(_Scheduler, "Scheduler");
130
- function sortEffects(effects) {
131
- if (effects.length > 1) {
132
- effects.sort((a, b) => b.depth - a.depth || a.order - b.order);
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
133
17
  }
134
- }
135
- __name(sortEffects, "sortEffects");
136
-
137
- // packages/runtime/src/hmr.ts
138
- var globalTarget = globalThis;
139
- var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map() };
140
- globalTarget.__VOBS_HMR__ = hmrGlobal;
141
-
142
- // packages/vobs/src/context.ts
143
- var ownerProviders = /* @__PURE__ */ new WeakMap();
144
- function inject(key, fallback) {
145
- const owner = getCurrentOwner();
146
- const value = owner ? injectFromOwner(owner, key) : void 0;
147
- return value === void 0 ? fallback : value;
148
- }
149
- __name(inject, "inject");
150
- function injectFromOwner(owner, key) {
151
- let current = owner;
152
- while (current) {
153
- const providers = ownerProviders.get(current);
154
- if (providers?.has(key)) return providers.get(key);
155
- current = current.parent;
156
- }
157
- return void 0;
158
- }
159
- __name(injectFromOwner, "injectFromOwner");
160
-
161
- // packages/vobs/src/app.ts
162
- function createInjectionKey(description) {
163
- return Symbol(description);
164
- }
165
- __name(createInjectionKey, "createInjectionKey");
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
166
21
 
167
22
  // packages/logger/src/index.ts
23
+ var src_exports = {};
24
+ __export(src_exports, {
25
+ LOGGER_KEY: () => LOGGER_KEY,
26
+ LoggerError: () => LoggerError,
27
+ createConsoleTransport: () => createConsoleTransport,
28
+ createLogger: () => createLogger,
29
+ createMemoryTransport: () => createMemoryTransport,
30
+ loggerPlugin: () => loggerPlugin,
31
+ useLogger: () => useLogger
32
+ });
33
+ module.exports = __toCommonJS(src_exports);
34
+ var import_reactivity = require("@vobs/reactivity");
35
+ var import_vobs = require("@vobs/vobs");
168
36
  var _LoggerError = class _LoggerError extends Error {
169
37
  constructor(code, message) {
170
38
  super(message);
@@ -174,7 +42,7 @@ var _LoggerError = class _LoggerError extends Error {
174
42
  };
175
43
  __name(_LoggerError, "LoggerError");
176
44
  var LoggerError = _LoggerError;
177
- var LOGGER_KEY = createInjectionKey("vobs.logger");
45
+ var LOGGER_KEY = (0, import_vobs.createInjectionKey)("vobs.logger");
178
46
  var levels = {
179
47
  debug: 10,
180
48
  info: 20,
@@ -193,7 +61,7 @@ function createLogger(options = {}) {
193
61
  if (transports.some((transport) => !transport || typeof transport.write !== "function")) {
194
62
  throw new LoggerError("INVALID_TRANSPORT", "Vobs Logger: transport \u5FC5\u987B\u63D0\u4F9B write(entry)");
195
63
  }
196
- const state2 = {
64
+ const state = {
197
65
  level,
198
66
  transports,
199
67
  redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map((key) => key.toLowerCase())),
@@ -203,7 +71,8 @@ function createLogger(options = {}) {
203
71
  pending: /* @__PURE__ */ new Set(),
204
72
  disposed: false
205
73
  };
206
- const logger = createLoggerScope(state2, options.context ?? {}, true);
74
+ const logger = createLoggerScope(state, options.context ?? {}, true);
75
+ if ((0, import_reactivity.getCurrentOwner)()) (0, import_reactivity.onDispose)(logger.dispose);
207
76
  return logger;
208
77
  }
209
78
  __name(createLogger, "createLogger");
@@ -248,25 +117,25 @@ function loggerPlugin(options = {}) {
248
117
  }
249
118
  __name(loggerPlugin, "loggerPlugin");
250
119
  function useLogger() {
251
- const logger = inject(LOGGER_KEY);
120
+ const logger = (0, import_vobs.inject)(LOGGER_KEY);
252
121
  if (!logger) throw new LoggerError("LOGGER_CONTEXT_MISSING", "Vobs Logger: \u627E\u4E0D\u5230\u4E0A\u4E0B\u6587\uFF0C\u8BF7\u5B89\u88C5 loggerPlugin");
253
122
  return logger;
254
123
  }
255
124
  __name(useLogger, "useLogger");
256
- function createLoggerScope(state2, baseContext, ownsTransports = false) {
125
+ function createLoggerScope(state, baseContext, ownsTransports = false) {
257
126
  const context = { ...baseContext };
258
127
  let disposed = false;
259
128
  return {
260
- level: state2.level,
129
+ level: state.level,
261
130
  log(level, message, details = {}) {
262
- if (state2.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state2.level]) return;
131
+ if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return;
263
132
  const entry = freezeEntry({
264
- timestamp: state2.clock().toISOString(),
133
+ timestamp: state.clock().toISOString(),
265
134
  level,
266
135
  message,
267
- context: sanitizeContext({ ...context, ...details }, state2.redactKeys, state2.maxDepth)
136
+ context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)
268
137
  });
269
- for (const transport of state2.transports) writeToTransport(state2, transport, entry);
138
+ for (const transport of state.transports) writeToTransport(state, transport, entry);
270
139
  },
271
140
  debug(message, details) {
272
141
  this.log("debug", message, details);
@@ -281,51 +150,51 @@ function createLoggerScope(state2, baseContext, ownsTransports = false) {
281
150
  this.log("error", message, details);
282
151
  },
283
152
  child(details) {
284
- return createLoggerScope(state2, { ...context, ...details });
153
+ return createLoggerScope(state, { ...context, ...details });
285
154
  },
286
155
  async flush() {
287
- while (state2.pending.size > 0) await Promise.all([...state2.pending]);
288
- for (const transport of state2.transports) {
156
+ while (state.pending.size > 0) await Promise.all([...state.pending]);
157
+ for (const transport of state.transports) {
289
158
  try {
290
159
  await transport.flush?.();
291
160
  } catch (error) {
292
- reportTransportError(state2, error, transport);
161
+ reportTransportError(state, error, transport);
293
162
  }
294
163
  }
295
164
  },
296
165
  dispose() {
297
166
  if (disposed) return;
298
167
  disposed = true;
299
- if (!ownsTransports || state2.disposed) return;
300
- state2.disposed = true;
301
- for (const transport of state2.transports) {
168
+ if (!ownsTransports || state.disposed) return;
169
+ state.disposed = true;
170
+ for (const transport of state.transports) {
302
171
  try {
303
172
  transport.dispose?.();
304
173
  } catch (error) {
305
- reportTransportError(state2, error, transport);
174
+ reportTransportError(state, error, transport);
306
175
  }
307
176
  }
308
177
  }
309
178
  };
310
179
  }
311
180
  __name(createLoggerScope, "createLoggerScope");
312
- function writeToTransport(state2, transport, entry) {
181
+ function writeToTransport(state, transport, entry) {
313
182
  try {
314
183
  const result = transport.write(entry);
315
184
  if (!isPromiseLike(result)) return;
316
185
  const pending = Promise.resolve(result).catch((error) => {
317
- reportTransportError(state2, error, transport, entry);
186
+ reportTransportError(state, error, transport, entry);
318
187
  });
319
- state2.pending.add(pending);
320
- void pending.then(() => state2.pending.delete(pending));
188
+ state.pending.add(pending);
189
+ void pending.then(() => state.pending.delete(pending));
321
190
  } catch (error) {
322
- reportTransportError(state2, error, transport, entry);
191
+ reportTransportError(state, error, transport, entry);
323
192
  }
324
193
  }
325
194
  __name(writeToTransport, "writeToTransport");
326
- function reportTransportError(state2, error, transport, entry) {
195
+ function reportTransportError(state, error, transport, entry) {
327
196
  try {
328
- state2.onTransportError?.(error, transport, entry);
197
+ state.onTransportError?.(error, transport, entry);
329
198
  } catch {
330
199
  }
331
200
  }
@@ -377,13 +246,14 @@ function isLogLevel(value) {
377
246
  return typeof value === "string" && value in levels;
378
247
  }
379
248
  __name(isLogLevel, "isLogLevel");
380
-
381
- exports.LOGGER_KEY = LOGGER_KEY;
382
- exports.LoggerError = LoggerError;
383
- exports.createConsoleTransport = createConsoleTransport;
384
- exports.createLogger = createLogger;
385
- exports.createMemoryTransport = createMemoryTransport;
386
- exports.loggerPlugin = loggerPlugin;
387
- exports.useLogger = useLogger;
388
- //# sourceMappingURL=index.cjs.map
249
+ // Annotate the CommonJS export names for ESM import in node:
250
+ 0 && (module.exports = {
251
+ LOGGER_KEY,
252
+ LoggerError,
253
+ createConsoleTransport,
254
+ createLogger,
255
+ createMemoryTransport,
256
+ loggerPlugin,
257
+ useLogger
258
+ });
389
259
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../reactivity/src/debug.ts","../../reactivity/src/owner.ts","../../reactivity/src/scheduler.ts","../../runtime/src/hmr.ts","../../vobs/src/context.ts","../../vobs/src/app.ts","../src/index.ts"],"names":["effect","state"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Effect } from './effect'\nimport type { Owner } from './owner'\nimport type { Dependency, ReadableSignal, Subscriber } from './signal'\n\nexport interface ReactivityDebugHooks {\n ownerCreated?(owner: Owner): void\n ownerNamed?(owner: Owner, name: string): void\n ownerDisposed?(owner: Owner): void\n signalCreated?(signal: ReadableSignal<unknown>, owner: Owner | null): void\n signalNamed?(signal: ReadableSignal<unknown>, name: string): void\n signalRead?(signal: ReadableSignal<unknown>, subscriber: Subscriber): void\n signalChanged?(signal: ReadableSignal<unknown>, previousValue: unknown, nextValue: unknown): void\n signalDisposed?(signal: ReadableSignal<unknown>): void\n dependencyTracked?(dependency: Dependency, subscriber: Subscriber): void\n dependencyUntracked?(dependency: Dependency, subscriber: Subscriber): void\n effectCreated?(effect: Effect, owner: Owner | null): void\n effectInvalidated?(effect: Effect): void\n effectRunStart?(effect: Effect): void\n effectRunEnd?(effect: Effect, error?: unknown, handled?: boolean): void\n effectDisposed?(effect: Effect): void\n memoCreated?(signal: ReadableSignal<unknown>, subscriber: Subscriber, owner: Owner | null): void\n memoInvalidated?(signal: ReadableSignal<unknown>): void\n flushStart?(): void\n flushEnd?(): void\n}\n\nlet activeDebugHooks: ReactivityDebugHooks | null = null\nconst signalNames = new WeakMap<object, string>()\n\nexport function setDebugHooks(hooks: ReactivityDebugHooks | null): ReactivityDebugHooks | null {\n const previous = activeDebugHooks\n activeDebugHooks = hooks\n return previous\n}\n\nexport function getDebugHooks(): ReactivityDebugHooks | null {\n return activeDebugHooks\n}\n\n/** 热路径守卫:无 hooks 时跳过 invokeDebug 调用,避免 rest 参数数组分配。 */\nexport function hasDebugHooks(): boolean {\n return activeDebugHooks !== null\n}\n\nexport function setSignalDebugName(signal: ReadableSignal<unknown>, name: string): void {\n signalNames.set(signal, name)\n invokeDebug('signalNamed', signal, name)\n}\n\nexport function getSignalDebugName(signal: ReadableSignal<unknown>): string | undefined {\n return signalNames.get(signal)\n}\n\nexport function invokeDebug<K extends keyof ReactivityDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<ReactivityDebugHooks[K]>>\n): void {\n const callback = activeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change application behavior.\n }\n}\n","import { invokeDebug, hasDebugHooks } from './debug'\n\nexport interface Owner {\n readonly id: string\n readonly parent: Owner | null\n readonly children: readonly Owner[]\n readonly depth: number\n readonly disposed: boolean\n run<T>(fn: () => T): T\n addCleanup(cleanup: () => void): void\n onDispose(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n handleError(error: unknown): boolean\n dispose(): void\n}\n\nlet currentOwner: Owner | null = null\nlet nextOwnerId = 1\nconst ownerNames = new WeakMap<Owner, string>()\n\nexport function createOwner(): Owner {\n const parent = currentOwner\n let disposed = parent?.disposed ?? false\n const children: Owner[] = []\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n\n const owner: Owner = {\n id: `owner-${nextOwnerId++}`,\n parent,\n children,\n depth: (parent?.depth ?? -1) + 1,\n\n get disposed(): boolean {\n return disposed\n },\n\n run<T>(fn: () => T): T {\n if (disposed) throw new Error('Vobs: 已销毁的 Owner 不能继续运行')\n const previous = currentOwner\n currentOwner = owner\n try {\n return fn()\n } finally {\n currentOwner = previous\n }\n },\n\n addCleanup(cleanup: () => void): void {\n if (disposed) {\n cleanup()\n return\n }\n cleanups.push(cleanup)\n },\n\n onDispose(cleanup: () => void): void {\n owner.addCleanup(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n owner.addCleanup(remove)\n return remove\n },\n\n handleError(error: unknown): boolean {\n for (const handler of [...errorHandlers].reverse()) {\n try {\n handler(error)\n return true\n } catch (handlerError) {\n return parent?.handleError(handlerError) ?? false\n }\n }\n return parent?.handleError(error) ?? false\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const child of [...children]) child.dispose()\n children.length = 0\n\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n if (parent) {\n const index = parent.children.indexOf(owner)\n if (index >= 0) (parent.children as Owner[]).splice(index, 1)\n }\n if (hasDebugHooks()) invokeDebug('ownerDisposed', owner)\n if (firstError) throw firstError\n }\n }\n\n if (parent && !parent.disposed) (parent.children as Owner[]).push(owner)\n if (hasDebugHooks()) invokeDebug('ownerCreated', owner)\n return owner\n}\n\nexport function setOwnerDebugName(owner: Owner, name: string): void {\n ownerNames.set(owner, name)\n if (hasDebugHooks()) invokeDebug('ownerNamed', owner, name)\n}\n\nexport function getOwnerDebugName(owner: Owner): string | undefined {\n return ownerNames.get(owner)\n}\n\nexport function getCurrentOwner(): Owner | null {\n return currentOwner\n}\n\n/** Re-enter an Owner for an explicitly captured asynchronous continuation. */\nexport function runWithOwner<T>(owner: Owner, fn: () => T): T {\n return owner.run(fn)\n}\n\nexport function onDispose(cleanup: () => void): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: onDispose 必须在 Owner 作用域内调用')\n owner.onDispose(cleanup)\n}\n","import type { Effect } from './effect'\nimport { hasDebugHooks, invokeDebug } from './debug'\n\nexport class Scheduler {\n private readonly dirtyEffects = new Set<Effect>()\n private readonly lowPriorityEffects = new Set<Effect>()\n // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。\n private readonly normalBuffer: Effect[] = []\n private readonly lowBuffer: Effect[] = []\n private flushing = false\n private scheduled = false\n private batchDepth = 0\n\n schedule(effect: Effect): void {\n if (effect.disposed) return\n this.dirtyEffects.add(effect)\n this.lowPriorityEffects.delete(effect)\n this.ensureScheduled()\n }\n\n /** Queue an effect behind normal updates while preserving deterministic order. */\n scheduleLow(effect: Effect): void {\n if (effect.disposed) return\n if (!this.dirtyEffects.has(effect)) this.lowPriorityEffects.add(effect)\n this.ensureScheduled()\n }\n\n private ensureScheduled(): void {\n if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flush()\n })\n }\n }\n\n remove(effect: Effect): void {\n this.dirtyEffects.delete(effect)\n this.lowPriorityEffects.delete(effect)\n }\n\n batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) this.flush()\n }\n }\n\n flush(): void {\n if (this.flushing || this.batchDepth > 0) return\n this.flushing = true\n const debugEnabled = hasDebugHooks()\n if (debugEnabled) invokeDebug('flushStart')\n let rounds = 0\n let firstError: unknown\n let hasError = false\n try {\n while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {\n if (++rounds > 100) {\n this.dirtyEffects.clear()\n this.lowPriorityEffects.clear()\n throw new Error('Vobs: 响应式更新超过 100 轮,可能存在循环依赖')\n }\n\n // normal 先、low 后,两组分别排序:与旧的合并排序语义一致\n // (旧比较器里 low 优先级本就高于 depth),但消除了比较器内的 Set 查找。\n this.collectRunnable(this.dirtyEffects, this.normalBuffer)\n this.collectRunnable(this.lowPriorityEffects, this.lowBuffer)\n sortEffects(this.normalBuffer)\n sortEffects(this.lowBuffer)\n for (const effect of this.normalBuffer) {\n try {\n effect.run()\n } catch (error) {\n // Isolate one failed effect from the rest of the flush. Re-throw\n // the first error after all runnable effects have had a chance.\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n for (const effect of this.lowBuffer) {\n try {\n effect.run()\n } catch (error) {\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n }\n } finally {\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n this.flushing = false\n if (debugEnabled) invokeDebug('flushEnd')\n }\n if (hasError) throw firstError\n }\n\n /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */\n private collectRunnable(source: Set<Effect>, target: Effect[]): void {\n for (const effect of source) {\n if (!effect.disposed) target.push(effect)\n }\n source.clear()\n }\n}\n\n/** depth 深的先跑(子 effect 先于父),同深度按创建顺序。 */\nfunction sortEffects(effects: Effect[]): void {\n if (effects.length > 1) {\n effects.sort((a, b) => b.depth - a.depth || a.order - b.order)\n }\n}\n\nexport const scheduler = new Scheduler()\n\nexport function batch<T>(fn: () => T): T {\n return scheduler.batch(fn)\n}\n\n/** Schedule a low-priority effect explicitly. */\nexport function scheduleLow(effect: Effect): void {\n effect.scheduleLow()\n}\n","import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(_moduleId: string, nextModule: Record<string, unknown>): void {\n const modules = [...hmrGlobal.modules.values()]\n for (const module of modules) {\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) continue\n for (const instance of module.instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","import { getCurrentOwner, type Owner } from '@vobs/reactivity'\nimport type { InjectionKey, ProvideOptions } from './app'\n\nconst ownerProviders = new WeakMap<Owner, Map<InjectionKey<unknown>, unknown>>()\n\nexport function provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: provide 必须在组件或 Owner 作用域内调用')\n provideToOwner(owner, key, value, options)\n}\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T\nexport function inject<T>(key: InjectionKey<T>, fallback?: T): T | undefined {\n const owner = getCurrentOwner()\n const value = owner ? injectFromOwner(owner, key) : undefined\n return value === undefined ? fallback : value\n}\n\nexport function injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = inject(key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n}\n\nexport function provideToOwner<T>(\n owner: Owner,\n key: InjectionKey<T>,\n value: T,\n options: ProvideOptions = {}\n): void {\n let providers = ownerProviders.get(owner)\n if (!providers) {\n providers = new Map<InjectionKey<unknown>, unknown>()\n ownerProviders.set(owner, providers)\n owner.onDispose(() => ownerProviders.delete(owner))\n }\n if (providers.has(key) && !options.override) {\n throw new Error(`Vobs: 注入项 ${String(key)} 已存在;如需覆盖请传入 override: true`)\n }\n providers.set(key, value)\n}\n\nexport function injectFromOwner<T>(owner: Owner, key: InjectionKey<T>): T | undefined {\n let current: Owner | null = owner\n while (current) {\n const providers = ownerProviders.get(current)\n if (providers?.has(key)) return providers.get(key) as T\n current = current.parent\n }\n return undefined\n}\n","import { createOwner, scheduler, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { createDOMRenderer } from '@vobs/dom'\nimport { insertBefore as insertRuntimeNode, setRenderer, type VobsFragment, type VobsRenderer } from '@vobs/runtime'\nimport { injectFromOwner, provideToOwner } from './context'\n\nexport type InjectionKey<T> = symbol & {\n readonly __vobsType?: T\n}\n\nexport interface ProvideOptions {\n override?: boolean\n}\n\nexport interface VobsPlugin {\n name: string\n version?: string\n requires?: readonly VobsPlugin[]\n optional?: readonly VobsPlugin[]\n install?: (ctx: VobsContext) => void | (() => void)\n}\n\nexport interface VobsContext {\n readonly app: VobsApp\n provide<T>(key: InjectionKey<T>, value: T, options?: ProvideOptions): void\n inject<T>(key: InjectionKey<T>): T | undefined\n injectRequired<T>(key: InjectionKey<T>, description?: string): T\n onDestroy(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n}\n\nexport interface VobsConfig<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n> {\n render: () => NodeType | VobsFragment | Node | null | undefined\n renderer?: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n plugins?: VobsPlugin[]\n /** Optional application-level error observer. Observers are isolated from the app. */\n onError?: (error: unknown) => void\n}\n\nexport interface VobsApp<NodeType = Node> {\n readonly mounted: boolean\n readonly destroyed: boolean\n use(plugin: VobsPlugin): VobsApp<NodeType>\n mount(target: string | NodeType): void\n hydrate(target: string | NodeType): void\n update(): void\n destroy(): void\n}\n\nexport function createInjectionKey<T>(description: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>\n}\n\nexport function createVobs(\n config: VobsConfig<Node, Text, Element, Comment>\n): VobsApp<Node>\nexport function createVobs<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n>(\n config: VobsConfig<NodeType, TextNode, ElementNode, CommentNode> & {\n renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n }\n): VobsApp<NodeType>\nexport function createVobs(\n config: VobsConfig<any, any, any, any>\n): VobsApp<any> {\n if (!config.render) throw new Error('createVobs: render 不能为空')\n\n const renderer = config.renderer ?? createDOMRenderer()\n const rootOwner: Owner = createOwner()\n setOwnerDebugName(rootOwner, 'App')\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n const installed = new Set<string>()\n const installing = new Set<string>()\n let mounted = false\n let destroyed = false\n let container: any = null\n let app!: VobsApp<any>\n\n if (config.onError) {\n errorHandlers.add(config.onError)\n cleanups.push(() => errorHandlers.delete(config.onError!))\n }\n\n const context: VobsContext = {\n get app(): VobsApp<any> {\n return app\n },\n\n provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n provideToOwner(rootOwner, key, value, options)\n },\n\n inject<T>(key: InjectionKey<T>): T | undefined {\n return injectFromOwner(rootOwner, key)\n },\n\n injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = injectFromOwner(rootOwner, key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n },\n\n onDestroy(cleanup: () => void): void {\n cleanups.push(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n cleanups.push(remove)\n return remove\n }\n }\n\n function notifyError(error: unknown): void {\n for (const handler of [...errorHandlers]) {\n try {\n handler(error)\n } catch {\n // 错误处理器不能覆盖触发它的原始错误。\n }\n }\n }\n\n function installPlugin(plugin: VobsPlugin): void {\n if (installed.has(plugin.name)) return\n if (installing.has(plugin.name)) {\n throw new Error(`Vobs: 插件依赖存在循环:${plugin.name}`)\n }\n\n installing.add(plugin.name)\n try {\n for (const dependency of plugin.requires ?? []) installPlugin(dependency)\n const cleanup = plugin.install?.(context)\n if (cleanup) cleanups.push(cleanup)\n installed.add(plugin.name)\n } finally {\n installing.delete(plugin.name)\n }\n }\n\n function cleanup(clearContainer = true): unknown {\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n try {\n rootOwner.dispose()\n } catch (error) {\n firstError ??= error\n }\n\n if (container && clearContainer) {\n try {\n renderer.clear(container)\n } catch (error) {\n firstError ??= error\n }\n }\n return firstError\n }\n\n function start(target: string | any, hydrating: boolean): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能挂载')\n if (mounted) return\n\n container = typeof target === 'string' ? document.querySelector(target) : target\n if (!container) throw new Error(`mount: 目标不存在: ${target}`)\n if (hydrating && !renderer.beginHydration) {\n throw new Error('Vobs: 当前渲染器不支持 Hydration')\n }\n\n setRenderer(renderer)\n try {\n if (hydrating) renderer.beginHydration?.()\n const rootNode = rootOwner.run(config.render)\n if (!hydrating) renderer.clear(container)\n if (rootNode) insertRuntimeNode(container, rootNode as any, null)\n if (hydrating) renderer.completeHydration?.()\n mounted = true\n } catch (error) {\n notifyError(error)\n const cleanupError = cleanup(!hydrating)\n destroyed = true\n throw cleanupError ?? error\n }\n }\n\n app = {\n get mounted(): boolean {\n return mounted\n },\n\n get destroyed(): boolean {\n return destroyed\n },\n\n use(plugin: VobsPlugin): VobsApp<any> {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能安装插件')\n installPlugin(plugin)\n return app\n },\n\n mount(target: string | any): void {\n start(target, false)\n },\n\n hydrate(target: string | any): void {\n start(target, true)\n },\n\n update(): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能更新')\n try {\n scheduler.flush()\n } catch (error) {\n notifyError(error)\n throw error\n }\n },\n\n destroy(): void {\n if (destroyed) return\n try {\n const cleanupError = cleanup()\n if (cleanupError) {\n notifyError(cleanupError)\n throw cleanupError\n }\n } finally {\n mounted = false\n destroyed = true\n }\n }\n }\n\n try {\n for (const plugin of config.plugins ?? []) app.use(plugin)\n } catch (error) {\n notifyError(error)\n cleanup()\n destroyed = true\n throw error\n }\n\n return app\n}\n","import { getCurrentOwner, onDispose } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\nexport type LogValue = string | number | boolean | null | Readonly<LogObject> | readonly LogValue[]\n\nexport interface LogObject {\n readonly [key: string]: LogValue\n}\n\nexport type LogContext = Readonly<Record<string, unknown>>\n\nexport interface LogEntry {\n readonly timestamp: string\n readonly level: LogLevel\n readonly message: string\n readonly context: Readonly<LogObject>\n}\n\nexport interface LogTransport {\n write(entry: LogEntry): void | PromiseLike<void>\n flush?(): void | PromiseLike<void>\n dispose?(): void\n}\n\nexport interface Logger {\n readonly level: LogLevel\n log(level: LogLevel, message: string, context?: LogContext): void\n debug(message: string, context?: LogContext): void\n info(message: string, context?: LogContext): void\n warn(message: string, context?: LogContext): void\n error(message: string, context?: LogContext): void\n child(context: LogContext): Logger\n flush(): Promise<void>\n dispose(): void\n}\n\nexport interface LoggerOptions {\n readonly level?: LogLevel\n readonly context?: LogContext\n readonly transports?: readonly LogTransport[]\n readonly redactKeys?: readonly string[]\n readonly maxDepth?: number\n readonly clock?: () => Date\n readonly onTransportError?: (error: unknown, transport: LogTransport, entry?: LogEntry) => void\n}\n\nexport interface LoggerPluginOptions extends LoggerOptions {\n readonly logger?: Logger\n}\n\nexport interface ConsoleLike {\n debug?: (...data: unknown[]) => void\n info?: (...data: unknown[]) => void\n warn?: (...data: unknown[]) => void\n error?: (...data: unknown[]) => void\n log?: (...data: unknown[]) => void\n}\n\nexport interface MemoryLogTransport extends LogTransport {\n readonly entries: readonly LogEntry[]\n clear(): void\n}\n\nexport type LoggerErrorCode = 'LOGGER_CONTEXT_MISSING' | 'INVALID_LEVEL' | 'INVALID_TRANSPORT' | 'INVALID_MAX_DEPTH'\n\nexport class LoggerError extends Error {\n readonly code: LoggerErrorCode\n\n constructor(code: LoggerErrorCode, message: string) {\n super(message)\n this.name = 'LoggerError'\n this.code = code\n }\n}\n\nexport const LOGGER_KEY: InjectionKey<Logger> = createInjectionKey<Logger>('vobs.logger')\n\nconst levels: Readonly<Record<LogLevel, number>> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40\n}\n\nconst defaultRedactKeys = ['password', 'passwd', 'secret', 'token', 'authorization', 'cookie']\n\ninterface LoggerState {\n readonly level: LogLevel\n readonly transports: readonly LogTransport[]\n readonly redactKeys: ReadonlySet<string>\n readonly maxDepth: number\n readonly clock: () => Date\n readonly onTransportError: LoggerOptions['onTransportError']\n readonly pending: Set<Promise<void>>\n disposed: boolean\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const level = options.level ?? 'info'\n if (!isLogLevel(level)) throw new LoggerError('INVALID_LEVEL', `Vobs Logger: 不支持日志级别 ${String(level)}`)\n\n const maxDepth = options.maxDepth ?? 8\n if (!Number.isInteger(maxDepth) || maxDepth < 0) {\n throw new LoggerError('INVALID_MAX_DEPTH', 'Vobs Logger: maxDepth 必须是大于等于 0 的整数')\n }\n\n const transports = options.transports ?? [createConsoleTransport()]\n if (transports.some(transport => !transport || typeof transport.write !== 'function')) {\n throw new LoggerError('INVALID_TRANSPORT', 'Vobs Logger: transport 必须提供 write(entry)')\n }\n\n const state: LoggerState = {\n level,\n transports,\n redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map(key => key.toLowerCase())),\n maxDepth,\n clock: options.clock ?? (() => new Date()),\n onTransportError: options.onTransportError,\n pending: new Set(),\n disposed: false\n }\n const logger = createLoggerScope(state, options.context ?? {}, true)\n if (getCurrentOwner()) onDispose(logger.dispose)\n return logger\n}\n\nexport function createConsoleTransport(target: ConsoleLike | undefined = globalThis.console): LogTransport {\n return {\n write(entry): void {\n const output = target?.[entry.level] ?? target?.log\n output?.call(target, `[${entry.level}] ${entry.message}`, entry.context)\n }\n }\n}\n\nexport function createMemoryTransport(limit = Infinity): MemoryLogTransport {\n if ((!Number.isInteger(limit) && limit !== Infinity) || limit <= 0) {\n throw new RangeError('Vobs Logger: memory transport 的 limit 必须是正整数或 Infinity')\n }\n\n const entries: LogEntry[] = []\n return {\n get entries(): readonly LogEntry[] {\n return entries\n },\n write(entry): void {\n entries.push(entry)\n if (entries.length > limit) entries.splice(0, entries.length - limit)\n },\n clear(): void {\n entries.length = 0\n }\n }\n}\n\nexport function loggerPlugin(options: LoggerPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/logger',\n version: '0.1.0',\n install(context) {\n const ownedLogger = options.logger ? undefined : createLogger(options)\n context.provide(LOGGER_KEY, options.logger ?? ownedLogger!)\n return () => ownedLogger?.dispose()\n }\n }\n}\n\nexport function useLogger(): Logger {\n const logger = inject(LOGGER_KEY)\n if (!logger) throw new LoggerError('LOGGER_CONTEXT_MISSING', 'Vobs Logger: 找不到上下文,请安装 loggerPlugin')\n return logger\n}\n\nfunction createLoggerScope(state: LoggerState, baseContext: LogContext, ownsTransports = false): Logger {\n const context = { ...baseContext }\n let disposed = false\n return {\n level: state.level,\n\n log(level, message, details = {}): void {\n if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return\n const entry = freezeEntry({\n timestamp: state.clock().toISOString(),\n level,\n message,\n context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)\n })\n for (const transport of state.transports) writeToTransport(state, transport, entry)\n },\n\n debug(message, details): void {\n this.log('debug', message, details)\n },\n\n info(message, details): void {\n this.log('info', message, details)\n },\n\n warn(message, details): void {\n this.log('warn', message, details)\n },\n\n error(message, details): void {\n this.log('error', message, details)\n },\n\n child(details): Logger {\n return createLoggerScope(state, { ...context, ...details })\n },\n\n async flush(): Promise<void> {\n while (state.pending.size > 0) await Promise.all([...state.pending])\n for (const transport of state.transports) {\n try {\n await transport.flush?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n if (!ownsTransports || state.disposed) return\n state.disposed = true\n for (const transport of state.transports) {\n try {\n transport.dispose?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n }\n }\n}\n\nfunction writeToTransport(state: LoggerState, transport: LogTransport, entry: LogEntry): void {\n try {\n const result = transport.write(entry)\n if (!isPromiseLike(result)) return\n const pending = Promise.resolve(result).catch(error => {\n reportTransportError(state, error, transport, entry)\n })\n state.pending.add(pending)\n void pending.then(() => state.pending.delete(pending))\n } catch (error) {\n reportTransportError(state, error, transport, entry)\n }\n}\n\nfunction reportTransportError(\n state: LoggerState,\n error: unknown,\n transport: LogTransport,\n entry?: LogEntry\n): void {\n try {\n state.onTransportError?.(error, transport, entry)\n } catch {\n // Transport error reporting must never make application logging throw.\n }\n}\n\nfunction sanitizeContext(input: LogContext, redactKeys: ReadonlySet<string>, maxDepth: number): LogObject {\n const seen = new WeakSet<object>()\n return Object.freeze(sanitizeObject(input, redactKeys, maxDepth, seen))\n}\n\nfunction sanitizeObject(\n input: LogContext,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogObject {\n const output: Record<string, LogValue> = {}\n for (const [key, value] of Object.entries(input)) {\n output[key] = redactKeys.has(key.toLowerCase())\n ? '[REDACTED]'\n : sanitizeValue(value, redactKeys, depth, seen)\n }\n return Object.freeze(output)\n}\n\nfunction sanitizeValue(\n value: unknown,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value)\n if (typeof value === 'bigint' || typeof value === 'symbol' || typeof value === 'undefined') return String(value)\n if (typeof value === 'function') return `[Function ${value.name || 'anonymous'}]`\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString()\n if (value instanceof Error) {\n return Object.freeze({\n name: value.name,\n message: value.message,\n ...(value.stack ? { stack: value.stack } : {})\n })\n }\n if (depth === 0) return '[MaxDepth]'\n if (seen.has(value as object)) return '[Circular]'\n seen.add(value as object)\n if (Array.isArray(value)) {\n return Object.freeze(value.map(item => sanitizeValue(item, redactKeys, depth - 1, seen)))\n }\n return sanitizeObject(value as LogContext, redactKeys, depth - 1, seen)\n}\n\nfunction freezeEntry(entry: LogEntry): LogEntry {\n return Object.freeze(entry)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<void> {\n return Boolean(value) && typeof (value as PromiseLike<void>).then === 'function'\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === 'string' && value in levels\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getCurrentOwner, onDispose } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\nexport type LogValue = string | number | boolean | null | Readonly<LogObject> | readonly LogValue[]\n\nexport interface LogObject {\n readonly [key: string]: LogValue\n}\n\nexport type LogContext = Readonly<Record<string, unknown>>\n\nexport interface LogEntry {\n readonly timestamp: string\n readonly level: LogLevel\n readonly message: string\n readonly context: Readonly<LogObject>\n}\n\nexport interface LogTransport {\n write(entry: LogEntry): void | PromiseLike<void>\n flush?(): void | PromiseLike<void>\n dispose?(): void\n}\n\nexport interface Logger {\n readonly level: LogLevel\n log(level: LogLevel, message: string, context?: LogContext): void\n debug(message: string, context?: LogContext): void\n info(message: string, context?: LogContext): void\n warn(message: string, context?: LogContext): void\n error(message: string, context?: LogContext): void\n child(context: LogContext): Logger\n flush(): Promise<void>\n dispose(): void\n}\n\nexport interface LoggerOptions {\n readonly level?: LogLevel\n readonly context?: LogContext\n readonly transports?: readonly LogTransport[]\n readonly redactKeys?: readonly string[]\n readonly maxDepth?: number\n readonly clock?: () => Date\n readonly onTransportError?: (error: unknown, transport: LogTransport, entry?: LogEntry) => void\n}\n\nexport interface LoggerPluginOptions extends LoggerOptions {\n readonly logger?: Logger\n}\n\nexport interface ConsoleLike {\n debug?: (...data: unknown[]) => void\n info?: (...data: unknown[]) => void\n warn?: (...data: unknown[]) => void\n error?: (...data: unknown[]) => void\n log?: (...data: unknown[]) => void\n}\n\nexport interface MemoryLogTransport extends LogTransport {\n readonly entries: readonly LogEntry[]\n clear(): void\n}\n\nexport type LoggerErrorCode = 'LOGGER_CONTEXT_MISSING' | 'INVALID_LEVEL' | 'INVALID_TRANSPORT' | 'INVALID_MAX_DEPTH'\n\nexport class LoggerError extends Error {\n readonly code: LoggerErrorCode\n\n constructor(code: LoggerErrorCode, message: string) {\n super(message)\n this.name = 'LoggerError'\n this.code = code\n }\n}\n\nexport const LOGGER_KEY: InjectionKey<Logger> = createInjectionKey<Logger>('vobs.logger')\n\nconst levels: Readonly<Record<LogLevel, number>> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40\n}\n\nconst defaultRedactKeys = ['password', 'passwd', 'secret', 'token', 'authorization', 'cookie']\n\ninterface LoggerState {\n readonly level: LogLevel\n readonly transports: readonly LogTransport[]\n readonly redactKeys: ReadonlySet<string>\n readonly maxDepth: number\n readonly clock: () => Date\n readonly onTransportError: LoggerOptions['onTransportError']\n readonly pending: Set<Promise<void>>\n disposed: boolean\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const level = options.level ?? 'info'\n if (!isLogLevel(level)) throw new LoggerError('INVALID_LEVEL', `Vobs Logger: 不支持日志级别 ${String(level)}`)\n\n const maxDepth = options.maxDepth ?? 8\n if (!Number.isInteger(maxDepth) || maxDepth < 0) {\n throw new LoggerError('INVALID_MAX_DEPTH', 'Vobs Logger: maxDepth 必须是大于等于 0 的整数')\n }\n\n const transports = options.transports ?? [createConsoleTransport()]\n if (transports.some(transport => !transport || typeof transport.write !== 'function')) {\n throw new LoggerError('INVALID_TRANSPORT', 'Vobs Logger: transport 必须提供 write(entry)')\n }\n\n const state: LoggerState = {\n level,\n transports,\n redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map(key => key.toLowerCase())),\n maxDepth,\n clock: options.clock ?? (() => new Date()),\n onTransportError: options.onTransportError,\n pending: new Set(),\n disposed: false\n }\n const logger = createLoggerScope(state, options.context ?? {}, true)\n if (getCurrentOwner()) onDispose(logger.dispose)\n return logger\n}\n\nexport function createConsoleTransport(target: ConsoleLike | undefined = globalThis.console): LogTransport {\n return {\n write(entry): void {\n const output = target?.[entry.level] ?? target?.log\n output?.call(target, `[${entry.level}] ${entry.message}`, entry.context)\n }\n }\n}\n\nexport function createMemoryTransport(limit = Infinity): MemoryLogTransport {\n if ((!Number.isInteger(limit) && limit !== Infinity) || limit <= 0) {\n throw new RangeError('Vobs Logger: memory transport 的 limit 必须是正整数或 Infinity')\n }\n\n const entries: LogEntry[] = []\n return {\n get entries(): readonly LogEntry[] {\n return entries\n },\n write(entry): void {\n entries.push(entry)\n if (entries.length > limit) entries.splice(0, entries.length - limit)\n },\n clear(): void {\n entries.length = 0\n }\n }\n}\n\nexport function loggerPlugin(options: LoggerPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/logger',\n version: '0.1.0',\n install(context) {\n const ownedLogger = options.logger ? undefined : createLogger(options)\n context.provide(LOGGER_KEY, options.logger ?? ownedLogger!)\n return () => ownedLogger?.dispose()\n }\n }\n}\n\nexport function useLogger(): Logger {\n const logger = inject(LOGGER_KEY)\n if (!logger) throw new LoggerError('LOGGER_CONTEXT_MISSING', 'Vobs Logger: 找不到上下文,请安装 loggerPlugin')\n return logger\n}\n\nfunction createLoggerScope(state: LoggerState, baseContext: LogContext, ownsTransports = false): Logger {\n const context = { ...baseContext }\n let disposed = false\n return {\n level: state.level,\n\n log(level, message, details = {}): void {\n if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return\n const entry = freezeEntry({\n timestamp: state.clock().toISOString(),\n level,\n message,\n context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)\n })\n for (const transport of state.transports) writeToTransport(state, transport, entry)\n },\n\n debug(message, details): void {\n this.log('debug', message, details)\n },\n\n info(message, details): void {\n this.log('info', message, details)\n },\n\n warn(message, details): void {\n this.log('warn', message, details)\n },\n\n error(message, details): void {\n this.log('error', message, details)\n },\n\n child(details): Logger {\n return createLoggerScope(state, { ...context, ...details })\n },\n\n async flush(): Promise<void> {\n while (state.pending.size > 0) await Promise.all([...state.pending])\n for (const transport of state.transports) {\n try {\n await transport.flush?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n if (!ownsTransports || state.disposed) return\n state.disposed = true\n for (const transport of state.transports) {\n try {\n transport.dispose?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n }\n }\n}\n\nfunction writeToTransport(state: LoggerState, transport: LogTransport, entry: LogEntry): void {\n try {\n const result = transport.write(entry)\n if (!isPromiseLike(result)) return\n const pending = Promise.resolve(result).catch(error => {\n reportTransportError(state, error, transport, entry)\n })\n state.pending.add(pending)\n void pending.then(() => state.pending.delete(pending))\n } catch (error) {\n reportTransportError(state, error, transport, entry)\n }\n}\n\nfunction reportTransportError(\n state: LoggerState,\n error: unknown,\n transport: LogTransport,\n entry?: LogEntry\n): void {\n try {\n state.onTransportError?.(error, transport, entry)\n } catch {\n // Transport error reporting must never make application logging throw.\n }\n}\n\nfunction sanitizeContext(input: LogContext, redactKeys: ReadonlySet<string>, maxDepth: number): LogObject {\n const seen = new WeakSet<object>()\n return Object.freeze(sanitizeObject(input, redactKeys, maxDepth, seen))\n}\n\nfunction sanitizeObject(\n input: LogContext,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogObject {\n const output: Record<string, LogValue> = {}\n for (const [key, value] of Object.entries(input)) {\n output[key] = redactKeys.has(key.toLowerCase())\n ? '[REDACTED]'\n : sanitizeValue(value, redactKeys, depth, seen)\n }\n return Object.freeze(output)\n}\n\nfunction sanitizeValue(\n value: unknown,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value)\n if (typeof value === 'bigint' || typeof value === 'symbol' || typeof value === 'undefined') return String(value)\n if (typeof value === 'function') return `[Function ${value.name || 'anonymous'}]`\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString()\n if (value instanceof Error) {\n return Object.freeze({\n name: value.name,\n message: value.message,\n ...(value.stack ? { stack: value.stack } : {})\n })\n }\n if (depth === 0) return '[MaxDepth]'\n if (seen.has(value as object)) return '[Circular]'\n seen.add(value as object)\n if (Array.isArray(value)) {\n return Object.freeze(value.map(item => sanitizeValue(item, redactKeys, depth - 1, seen)))\n }\n return sanitizeObject(value as LogContext, redactKeys, depth - 1, seen)\n}\n\nfunction freezeEntry(entry: LogEntry): LogEntry {\n return Object.freeze(entry)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<void> {\n return Boolean(value) && typeof (value as PromiseLike<void>).then === 'function'\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === 'string' && value in levels\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,168 +1,9 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
 
4
- // packages/reactivity/src/debug.ts
5
- var activeDebugHooks = null;
6
- function hasDebugHooks() {
7
- return activeDebugHooks !== null;
8
- }
9
- __name(hasDebugHooks, "hasDebugHooks");
10
- function invokeDebug(name, ...args) {
11
- return;
12
- }
13
- __name(invokeDebug, "invokeDebug");
14
-
15
- // packages/reactivity/src/owner.ts
16
- var currentOwner = null;
17
- function getCurrentOwner() {
18
- return currentOwner;
19
- }
20
- __name(getCurrentOwner, "getCurrentOwner");
21
- function onDispose(cleanup) {
22
- throw new Error("Vobs: onDispose \u5FC5\u987B\u5728 Owner \u4F5C\u7528\u57DF\u5185\u8C03\u7528");
23
- }
24
- __name(onDispose, "onDispose");
25
-
26
- // packages/reactivity/src/scheduler.ts
27
- var _Scheduler = class _Scheduler {
28
- constructor() {
29
- this.dirtyEffects = /* @__PURE__ */ new Set();
30
- this.lowPriorityEffects = /* @__PURE__ */ new Set();
31
- // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。
32
- this.normalBuffer = [];
33
- this.lowBuffer = [];
34
- this.flushing = false;
35
- this.scheduled = false;
36
- this.batchDepth = 0;
37
- }
38
- schedule(effect2) {
39
- if (effect2.disposed) return;
40
- this.dirtyEffects.add(effect2);
41
- this.lowPriorityEffects.delete(effect2);
42
- this.ensureScheduled();
43
- }
44
- /** Queue an effect behind normal updates while preserving deterministic order. */
45
- scheduleLow(effect2) {
46
- if (effect2.disposed) return;
47
- if (!this.dirtyEffects.has(effect2)) this.lowPriorityEffects.add(effect2);
48
- this.ensureScheduled();
49
- }
50
- ensureScheduled() {
51
- if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {
52
- this.scheduled = true;
53
- queueMicrotask(() => {
54
- this.scheduled = false;
55
- this.flush();
56
- });
57
- }
58
- }
59
- remove(effect2) {
60
- this.dirtyEffects.delete(effect2);
61
- this.lowPriorityEffects.delete(effect2);
62
- }
63
- batch(fn) {
64
- this.batchDepth++;
65
- try {
66
- return fn();
67
- } finally {
68
- this.batchDepth--;
69
- if (this.batchDepth === 0) this.flush();
70
- }
71
- }
72
- flush() {
73
- if (this.flushing || this.batchDepth > 0) return;
74
- this.flushing = true;
75
- let rounds = 0;
76
- let firstError;
77
- let hasError = false;
78
- try {
79
- while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {
80
- if (++rounds > 100) {
81
- this.dirtyEffects.clear();
82
- this.lowPriorityEffects.clear();
83
- throw new Error("Vobs: \u54CD\u5E94\u5F0F\u66F4\u65B0\u8D85\u8FC7 100 \u8F6E\uFF0C\u53EF\u80FD\u5B58\u5728\u5FAA\u73AF\u4F9D\u8D56");
84
- }
85
- this.collectRunnable(this.dirtyEffects, this.normalBuffer);
86
- this.collectRunnable(this.lowPriorityEffects, this.lowBuffer);
87
- sortEffects(this.normalBuffer);
88
- sortEffects(this.lowBuffer);
89
- for (const effect2 of this.normalBuffer) {
90
- try {
91
- effect2.run();
92
- } catch (error) {
93
- if (!hasError) {
94
- firstError = error;
95
- hasError = true;
96
- }
97
- }
98
- }
99
- for (const effect2 of this.lowBuffer) {
100
- try {
101
- effect2.run();
102
- } catch (error) {
103
- if (!hasError) {
104
- firstError = error;
105
- hasError = true;
106
- }
107
- }
108
- }
109
- this.normalBuffer.length = 0;
110
- this.lowBuffer.length = 0;
111
- }
112
- } finally {
113
- this.normalBuffer.length = 0;
114
- this.lowBuffer.length = 0;
115
- this.flushing = false;
116
- }
117
- if (hasError) throw firstError;
118
- }
119
- /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */
120
- collectRunnable(source, target) {
121
- for (const effect2 of source) {
122
- if (!effect2.disposed) target.push(effect2);
123
- }
124
- source.clear();
125
- }
126
- };
127
- __name(_Scheduler, "Scheduler");
128
- function sortEffects(effects) {
129
- if (effects.length > 1) {
130
- effects.sort((a, b) => b.depth - a.depth || a.order - b.order);
131
- }
132
- }
133
- __name(sortEffects, "sortEffects");
134
-
135
- // packages/runtime/src/hmr.ts
136
- var globalTarget = globalThis;
137
- var hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: /* @__PURE__ */ new Map() };
138
- globalTarget.__VOBS_HMR__ = hmrGlobal;
139
-
140
- // packages/vobs/src/context.ts
141
- var ownerProviders = /* @__PURE__ */ new WeakMap();
142
- function inject(key, fallback) {
143
- const owner = getCurrentOwner();
144
- const value = owner ? injectFromOwner(owner, key) : void 0;
145
- return value === void 0 ? fallback : value;
146
- }
147
- __name(inject, "inject");
148
- function injectFromOwner(owner, key) {
149
- let current = owner;
150
- while (current) {
151
- const providers = ownerProviders.get(current);
152
- if (providers?.has(key)) return providers.get(key);
153
- current = current.parent;
154
- }
155
- return void 0;
156
- }
157
- __name(injectFromOwner, "injectFromOwner");
158
-
159
- // packages/vobs/src/app.ts
160
- function createInjectionKey(description) {
161
- return Symbol(description);
162
- }
163
- __name(createInjectionKey, "createInjectionKey");
164
-
165
4
  // packages/logger/src/index.ts
5
+ import { getCurrentOwner, onDispose } from "@vobs/reactivity";
6
+ import { createInjectionKey, inject } from "@vobs/vobs";
166
7
  var _LoggerError = class _LoggerError extends Error {
167
8
  constructor(code, message) {
168
9
  super(message);
@@ -191,7 +32,7 @@ function createLogger(options = {}) {
191
32
  if (transports.some((transport) => !transport || typeof transport.write !== "function")) {
192
33
  throw new LoggerError("INVALID_TRANSPORT", "Vobs Logger: transport \u5FC5\u987B\u63D0\u4F9B write(entry)");
193
34
  }
194
- const state2 = {
35
+ const state = {
195
36
  level,
196
37
  transports,
197
38
  redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map((key) => key.toLowerCase())),
@@ -201,7 +42,8 @@ function createLogger(options = {}) {
201
42
  pending: /* @__PURE__ */ new Set(),
202
43
  disposed: false
203
44
  };
204
- const logger = createLoggerScope(state2, options.context ?? {}, true);
45
+ const logger = createLoggerScope(state, options.context ?? {}, true);
46
+ if (getCurrentOwner()) onDispose(logger.dispose);
205
47
  return logger;
206
48
  }
207
49
  __name(createLogger, "createLogger");
@@ -251,20 +93,20 @@ function useLogger() {
251
93
  return logger;
252
94
  }
253
95
  __name(useLogger, "useLogger");
254
- function createLoggerScope(state2, baseContext, ownsTransports = false) {
96
+ function createLoggerScope(state, baseContext, ownsTransports = false) {
255
97
  const context = { ...baseContext };
256
98
  let disposed = false;
257
99
  return {
258
- level: state2.level,
100
+ level: state.level,
259
101
  log(level, message, details = {}) {
260
- if (state2.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state2.level]) return;
102
+ if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return;
261
103
  const entry = freezeEntry({
262
- timestamp: state2.clock().toISOString(),
104
+ timestamp: state.clock().toISOString(),
263
105
  level,
264
106
  message,
265
- context: sanitizeContext({ ...context, ...details }, state2.redactKeys, state2.maxDepth)
107
+ context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)
266
108
  });
267
- for (const transport of state2.transports) writeToTransport(state2, transport, entry);
109
+ for (const transport of state.transports) writeToTransport(state, transport, entry);
268
110
  },
269
111
  debug(message, details) {
270
112
  this.log("debug", message, details);
@@ -279,51 +121,51 @@ function createLoggerScope(state2, baseContext, ownsTransports = false) {
279
121
  this.log("error", message, details);
280
122
  },
281
123
  child(details) {
282
- return createLoggerScope(state2, { ...context, ...details });
124
+ return createLoggerScope(state, { ...context, ...details });
283
125
  },
284
126
  async flush() {
285
- while (state2.pending.size > 0) await Promise.all([...state2.pending]);
286
- for (const transport of state2.transports) {
127
+ while (state.pending.size > 0) await Promise.all([...state.pending]);
128
+ for (const transport of state.transports) {
287
129
  try {
288
130
  await transport.flush?.();
289
131
  } catch (error) {
290
- reportTransportError(state2, error, transport);
132
+ reportTransportError(state, error, transport);
291
133
  }
292
134
  }
293
135
  },
294
136
  dispose() {
295
137
  if (disposed) return;
296
138
  disposed = true;
297
- if (!ownsTransports || state2.disposed) return;
298
- state2.disposed = true;
299
- for (const transport of state2.transports) {
139
+ if (!ownsTransports || state.disposed) return;
140
+ state.disposed = true;
141
+ for (const transport of state.transports) {
300
142
  try {
301
143
  transport.dispose?.();
302
144
  } catch (error) {
303
- reportTransportError(state2, error, transport);
145
+ reportTransportError(state, error, transport);
304
146
  }
305
147
  }
306
148
  }
307
149
  };
308
150
  }
309
151
  __name(createLoggerScope, "createLoggerScope");
310
- function writeToTransport(state2, transport, entry) {
152
+ function writeToTransport(state, transport, entry) {
311
153
  try {
312
154
  const result = transport.write(entry);
313
155
  if (!isPromiseLike(result)) return;
314
156
  const pending = Promise.resolve(result).catch((error) => {
315
- reportTransportError(state2, error, transport, entry);
157
+ reportTransportError(state, error, transport, entry);
316
158
  });
317
- state2.pending.add(pending);
318
- void pending.then(() => state2.pending.delete(pending));
159
+ state.pending.add(pending);
160
+ void pending.then(() => state.pending.delete(pending));
319
161
  } catch (error) {
320
- reportTransportError(state2, error, transport, entry);
162
+ reportTransportError(state, error, transport, entry);
321
163
  }
322
164
  }
323
165
  __name(writeToTransport, "writeToTransport");
324
- function reportTransportError(state2, error, transport, entry) {
166
+ function reportTransportError(state, error, transport, entry) {
325
167
  try {
326
- state2.onTransportError?.(error, transport, entry);
168
+ state.onTransportError?.(error, transport, entry);
327
169
  } catch {
328
170
  }
329
171
  }
@@ -375,7 +217,13 @@ function isLogLevel(value) {
375
217
  return typeof value === "string" && value in levels;
376
218
  }
377
219
  __name(isLogLevel, "isLogLevel");
378
-
379
- export { LOGGER_KEY, LoggerError, createConsoleTransport, createLogger, createMemoryTransport, loggerPlugin, useLogger };
380
- //# sourceMappingURL=index.js.map
220
+ export {
221
+ LOGGER_KEY,
222
+ LoggerError,
223
+ createConsoleTransport,
224
+ createLogger,
225
+ createMemoryTransport,
226
+ loggerPlugin,
227
+ useLogger
228
+ };
381
229
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../reactivity/src/debug.ts","../../reactivity/src/owner.ts","../../reactivity/src/scheduler.ts","../../runtime/src/hmr.ts","../../vobs/src/context.ts","../../vobs/src/app.ts","../src/index.ts"],"names":["effect","state"],"mappings":"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","file":"index.js","sourcesContent":["import type { Effect } from './effect'\nimport type { Owner } from './owner'\nimport type { Dependency, ReadableSignal, Subscriber } from './signal'\n\nexport interface ReactivityDebugHooks {\n ownerCreated?(owner: Owner): void\n ownerNamed?(owner: Owner, name: string): void\n ownerDisposed?(owner: Owner): void\n signalCreated?(signal: ReadableSignal<unknown>, owner: Owner | null): void\n signalNamed?(signal: ReadableSignal<unknown>, name: string): void\n signalRead?(signal: ReadableSignal<unknown>, subscriber: Subscriber): void\n signalChanged?(signal: ReadableSignal<unknown>, previousValue: unknown, nextValue: unknown): void\n signalDisposed?(signal: ReadableSignal<unknown>): void\n dependencyTracked?(dependency: Dependency, subscriber: Subscriber): void\n dependencyUntracked?(dependency: Dependency, subscriber: Subscriber): void\n effectCreated?(effect: Effect, owner: Owner | null): void\n effectInvalidated?(effect: Effect): void\n effectRunStart?(effect: Effect): void\n effectRunEnd?(effect: Effect, error?: unknown, handled?: boolean): void\n effectDisposed?(effect: Effect): void\n memoCreated?(signal: ReadableSignal<unknown>, subscriber: Subscriber, owner: Owner | null): void\n memoInvalidated?(signal: ReadableSignal<unknown>): void\n flushStart?(): void\n flushEnd?(): void\n}\n\nlet activeDebugHooks: ReactivityDebugHooks | null = null\nconst signalNames = new WeakMap<object, string>()\n\nexport function setDebugHooks(hooks: ReactivityDebugHooks | null): ReactivityDebugHooks | null {\n const previous = activeDebugHooks\n activeDebugHooks = hooks\n return previous\n}\n\nexport function getDebugHooks(): ReactivityDebugHooks | null {\n return activeDebugHooks\n}\n\n/** 热路径守卫:无 hooks 时跳过 invokeDebug 调用,避免 rest 参数数组分配。 */\nexport function hasDebugHooks(): boolean {\n return activeDebugHooks !== null\n}\n\nexport function setSignalDebugName(signal: ReadableSignal<unknown>, name: string): void {\n signalNames.set(signal, name)\n invokeDebug('signalNamed', signal, name)\n}\n\nexport function getSignalDebugName(signal: ReadableSignal<unknown>): string | undefined {\n return signalNames.get(signal)\n}\n\nexport function invokeDebug<K extends keyof ReactivityDebugHooks>(\n name: K,\n ...args: Parameters<NonNullable<ReactivityDebugHooks[K]>>\n): void {\n const callback = activeDebugHooks?.[name] as ((...values: unknown[]) => void) | undefined\n if (!callback) return\n try {\n callback(...args)\n } catch {\n // Debug tooling must never change application behavior.\n }\n}\n","import { invokeDebug, hasDebugHooks } from './debug'\n\nexport interface Owner {\n readonly id: string\n readonly parent: Owner | null\n readonly children: readonly Owner[]\n readonly depth: number\n readonly disposed: boolean\n run<T>(fn: () => T): T\n addCleanup(cleanup: () => void): void\n onDispose(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n handleError(error: unknown): boolean\n dispose(): void\n}\n\nlet currentOwner: Owner | null = null\nlet nextOwnerId = 1\nconst ownerNames = new WeakMap<Owner, string>()\n\nexport function createOwner(): Owner {\n const parent = currentOwner\n let disposed = parent?.disposed ?? false\n const children: Owner[] = []\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n\n const owner: Owner = {\n id: `owner-${nextOwnerId++}`,\n parent,\n children,\n depth: (parent?.depth ?? -1) + 1,\n\n get disposed(): boolean {\n return disposed\n },\n\n run<T>(fn: () => T): T {\n if (disposed) throw new Error('Vobs: 已销毁的 Owner 不能继续运行')\n const previous = currentOwner\n currentOwner = owner\n try {\n return fn()\n } finally {\n currentOwner = previous\n }\n },\n\n addCleanup(cleanup: () => void): void {\n if (disposed) {\n cleanup()\n return\n }\n cleanups.push(cleanup)\n },\n\n onDispose(cleanup: () => void): void {\n owner.addCleanup(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n owner.addCleanup(remove)\n return remove\n },\n\n handleError(error: unknown): boolean {\n for (const handler of [...errorHandlers].reverse()) {\n try {\n handler(error)\n return true\n } catch (handlerError) {\n return parent?.handleError(handlerError) ?? false\n }\n }\n return parent?.handleError(error) ?? false\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n for (const child of [...children]) child.dispose()\n children.length = 0\n\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n if (parent) {\n const index = parent.children.indexOf(owner)\n if (index >= 0) (parent.children as Owner[]).splice(index, 1)\n }\n if (hasDebugHooks()) invokeDebug('ownerDisposed', owner)\n if (firstError) throw firstError\n }\n }\n\n if (parent && !parent.disposed) (parent.children as Owner[]).push(owner)\n if (hasDebugHooks()) invokeDebug('ownerCreated', owner)\n return owner\n}\n\nexport function setOwnerDebugName(owner: Owner, name: string): void {\n ownerNames.set(owner, name)\n if (hasDebugHooks()) invokeDebug('ownerNamed', owner, name)\n}\n\nexport function getOwnerDebugName(owner: Owner): string | undefined {\n return ownerNames.get(owner)\n}\n\nexport function getCurrentOwner(): Owner | null {\n return currentOwner\n}\n\n/** Re-enter an Owner for an explicitly captured asynchronous continuation. */\nexport function runWithOwner<T>(owner: Owner, fn: () => T): T {\n return owner.run(fn)\n}\n\nexport function onDispose(cleanup: () => void): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: onDispose 必须在 Owner 作用域内调用')\n owner.onDispose(cleanup)\n}\n","import type { Effect } from './effect'\nimport { hasDebugHooks, invokeDebug } from './debug'\n\nexport class Scheduler {\n private readonly dirtyEffects = new Set<Effect>()\n private readonly lowPriorityEffects = new Set<Effect>()\n // flush 不可重入(flushing 标志保证),缓冲数组可在轮次间安全复用,避免每轮分配。\n private readonly normalBuffer: Effect[] = []\n private readonly lowBuffer: Effect[] = []\n private flushing = false\n private scheduled = false\n private batchDepth = 0\n\n schedule(effect: Effect): void {\n if (effect.disposed) return\n this.dirtyEffects.add(effect)\n this.lowPriorityEffects.delete(effect)\n this.ensureScheduled()\n }\n\n /** Queue an effect behind normal updates while preserving deterministic order. */\n scheduleLow(effect: Effect): void {\n if (effect.disposed) return\n if (!this.dirtyEffects.has(effect)) this.lowPriorityEffects.add(effect)\n this.ensureScheduled()\n }\n\n private ensureScheduled(): void {\n if (this.batchDepth === 0 && !this.flushing && !this.scheduled) {\n this.scheduled = true\n queueMicrotask(() => {\n this.scheduled = false\n this.flush()\n })\n }\n }\n\n remove(effect: Effect): void {\n this.dirtyEffects.delete(effect)\n this.lowPriorityEffects.delete(effect)\n }\n\n batch<T>(fn: () => T): T {\n this.batchDepth++\n try {\n return fn()\n } finally {\n this.batchDepth--\n if (this.batchDepth === 0) this.flush()\n }\n }\n\n flush(): void {\n if (this.flushing || this.batchDepth > 0) return\n this.flushing = true\n const debugEnabled = hasDebugHooks()\n if (debugEnabled) invokeDebug('flushStart')\n let rounds = 0\n let firstError: unknown\n let hasError = false\n try {\n while (this.dirtyEffects.size > 0 || this.lowPriorityEffects.size > 0) {\n if (++rounds > 100) {\n this.dirtyEffects.clear()\n this.lowPriorityEffects.clear()\n throw new Error('Vobs: 响应式更新超过 100 轮,可能存在循环依赖')\n }\n\n // normal 先、low 后,两组分别排序:与旧的合并排序语义一致\n // (旧比较器里 low 优先级本就高于 depth),但消除了比较器内的 Set 查找。\n this.collectRunnable(this.dirtyEffects, this.normalBuffer)\n this.collectRunnable(this.lowPriorityEffects, this.lowBuffer)\n sortEffects(this.normalBuffer)\n sortEffects(this.lowBuffer)\n for (const effect of this.normalBuffer) {\n try {\n effect.run()\n } catch (error) {\n // Isolate one failed effect from the rest of the flush. Re-throw\n // the first error after all runnable effects have had a chance.\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n for (const effect of this.lowBuffer) {\n try {\n effect.run()\n } catch (error) {\n if (!hasError) {\n firstError = error\n hasError = true\n }\n }\n }\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n }\n } finally {\n this.normalBuffer.length = 0\n this.lowBuffer.length = 0\n this.flushing = false\n if (debugEnabled) invokeDebug('flushEnd')\n }\n if (hasError) throw firstError\n }\n\n /** 收集未 disposed 的 effect 并清空源集合;run() 期间新调度的 effect 留给下一轮。 */\n private collectRunnable(source: Set<Effect>, target: Effect[]): void {\n for (const effect of source) {\n if (!effect.disposed) target.push(effect)\n }\n source.clear()\n }\n}\n\n/** depth 深的先跑(子 effect 先于父),同深度按创建顺序。 */\nfunction sortEffects(effects: Effect[]): void {\n if (effects.length > 1) {\n effects.sort((a, b) => b.depth - a.depth || a.order - b.order)\n }\n}\n\nexport const scheduler = new Scheduler()\n\nexport function batch<T>(fn: () => T): T {\n return scheduler.batch(fn)\n}\n\n/** Schedule a low-priority effect explicitly. */\nexport function scheduleLow(effect: Effect): void {\n effect.scheduleLow()\n}\n","import type { VobsNode } from './fragment'\n\nexport type HmrComponent<Props extends object = Record<string, unknown>> =\n (props: Props) => VobsNode\n\nexport interface HmrStateStore {\n get<T>(key: string, initial: T | (() => T)): T\n set<T>(key: string, value: T): void\n has(key: string): boolean\n delete(key: string): void\n clear(): void\n}\n\nexport interface HmrInstance {\n node: VobsNode\n parent: Node | null\n refresh(): void\n}\n\ninterface HmrModuleState {\n readonly components: Map<string, HmrComponent>\n readonly state: Map<string, unknown>\n readonly instances: Set<HmrInstance>\n}\n\ninterface HmrGlobal {\n modules: Map<string, HmrModuleState>\n}\n\nconst globalTarget = globalThis as typeof globalThis & { __VOBS_HMR__?: HmrGlobal }\nconst hmrGlobal = globalTarget.__VOBS_HMR__ ?? { modules: new Map<string, HmrModuleState>() }\nglobalTarget.__VOBS_HMR__ = hmrGlobal\n\nexport function resolveComponent<Props extends object>(\n component: HmrComponent<Props>,\n moduleId: string,\n exportName: string\n): HmrComponent<Props> {\n const module = getModule(moduleId)\n const existing = module.components.get(exportName)\n if (existing) return existing as HmrComponent<Props>\n\n const proxy = ((props: Props) => {\n const current = (proxy as HmrComponent<Props> & { current: HmrComponent<Props> }).current\n return current(props)\n }) as HmrComponent<Props> & { current: HmrComponent<Props> }\n proxy.current = component\n Object.defineProperties(proxy, {\n displayName: { configurable: true, value: component.name || exportName },\n hmrKey: { configurable: false, value: `${moduleId}:${exportName}` }\n })\n module.components.set(exportName, proxy as HmrComponent)\n return proxy\n}\n\nexport function updateHmrModule(_moduleId: string, nextModule: Record<string, unknown>): void {\n const modules = [...hmrGlobal.modules.values()]\n for (const module of modules) {\n let changed = false\n for (const [name, proxy] of module.components) {\n const next = nextModule[name]\n if (typeof next !== 'function') continue\n const hmrProxy = proxy as HmrComponent & { current: HmrComponent; displayName?: string }\n hmrProxy.current = next as HmrComponent\n Object.defineProperty(hmrProxy, 'displayName', { configurable: true, value: next.name || name })\n changed = true\n }\n if (!changed) continue\n for (const instance of module.instances) {\n try {\n instance.refresh()\n } catch {\n // HMR failures remain application errors on the next normal render.\n }\n }\n }\n}\n\nexport function disposeHmrModule(_moduleId: string): void {\n // State and component proxies intentionally survive module disposal.\n}\n\nexport function createHmrStateStore(moduleId: string): HmrStateStore {\n const state = getModule(moduleId).state\n return {\n get<T>(key: string, initial: T | (() => T)): T {\n if (!state.has(key)) state.set(key, typeof initial === 'function' ? (initial as () => T)() : initial)\n return state.get(key) as T\n },\n set<T>(key: string, value: T): void {\n state.set(key, value)\n },\n has: key => state.has(key),\n delete: key => { state.delete(key) },\n clear: () => { state.clear() }\n }\n}\n\nexport function registerHmrInstance(moduleId: string, instance: HmrInstance): () => void {\n const instances = getModule(moduleId).instances\n instances.add(instance)\n return () => instances.delete(instance)\n}\n\nexport function markHmrInstanceMounted(node: VobsNode, parent: Node): void {\n const instance = hmrInstances.get(node as object)\n if (instance) instance.parent = parent\n}\n\nfunction getModule(moduleId: string): HmrModuleState {\n let module = hmrGlobal.modules.get(moduleId)\n if (!module) {\n module = { components: new Map(), state: new Map(), instances: new Set() }\n hmrGlobal.modules.set(moduleId, module)\n }\n return module\n}\n\nconst hmrInstances = new WeakMap<object, HmrInstance>()\n\nexport function associateHmrInstance(node: VobsNode, instance: HmrInstance): void {\n hmrInstances.set(node as object, instance)\n}\n","import { getCurrentOwner, type Owner } from '@vobs/reactivity'\nimport type { InjectionKey, ProvideOptions } from './app'\n\nconst ownerProviders = new WeakMap<Owner, Map<InjectionKey<unknown>, unknown>>()\n\nexport function provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n const owner = getCurrentOwner()\n if (!owner) throw new Error('Vobs: provide 必须在组件或 Owner 作用域内调用')\n provideToOwner(owner, key, value, options)\n}\n\nexport function inject<T>(key: InjectionKey<T>): T | undefined\nexport function inject<T>(key: InjectionKey<T>, fallback: T): T\nexport function inject<T>(key: InjectionKey<T>, fallback?: T): T | undefined {\n const owner = getCurrentOwner()\n const value = owner ? injectFromOwner(owner, key) : undefined\n return value === undefined ? fallback : value\n}\n\nexport function injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = inject(key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n}\n\nexport function provideToOwner<T>(\n owner: Owner,\n key: InjectionKey<T>,\n value: T,\n options: ProvideOptions = {}\n): void {\n let providers = ownerProviders.get(owner)\n if (!providers) {\n providers = new Map<InjectionKey<unknown>, unknown>()\n ownerProviders.set(owner, providers)\n owner.onDispose(() => ownerProviders.delete(owner))\n }\n if (providers.has(key) && !options.override) {\n throw new Error(`Vobs: 注入项 ${String(key)} 已存在;如需覆盖请传入 override: true`)\n }\n providers.set(key, value)\n}\n\nexport function injectFromOwner<T>(owner: Owner, key: InjectionKey<T>): T | undefined {\n let current: Owner | null = owner\n while (current) {\n const providers = ownerProviders.get(current)\n if (providers?.has(key)) return providers.get(key) as T\n current = current.parent\n }\n return undefined\n}\n","import { createOwner, scheduler, setOwnerDebugName, type Owner } from '@vobs/reactivity'\nimport { createDOMRenderer } from '@vobs/dom'\nimport { insertBefore as insertRuntimeNode, setRenderer, type VobsFragment, type VobsRenderer } from '@vobs/runtime'\nimport { injectFromOwner, provideToOwner } from './context'\n\nexport type InjectionKey<T> = symbol & {\n readonly __vobsType?: T\n}\n\nexport interface ProvideOptions {\n override?: boolean\n}\n\nexport interface VobsPlugin {\n name: string\n version?: string\n requires?: readonly VobsPlugin[]\n optional?: readonly VobsPlugin[]\n install?: (ctx: VobsContext) => void | (() => void)\n}\n\nexport interface VobsContext {\n readonly app: VobsApp\n provide<T>(key: InjectionKey<T>, value: T, options?: ProvideOptions): void\n inject<T>(key: InjectionKey<T>): T | undefined\n injectRequired<T>(key: InjectionKey<T>, description?: string): T\n onDestroy(cleanup: () => void): void\n onError(handler: (error: unknown) => void): () => void\n}\n\nexport interface VobsConfig<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n> {\n render: () => NodeType | VobsFragment | Node | null | undefined\n renderer?: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n plugins?: VobsPlugin[]\n /** Optional application-level error observer. Observers are isolated from the app. */\n onError?: (error: unknown) => void\n}\n\nexport interface VobsApp<NodeType = Node> {\n readonly mounted: boolean\n readonly destroyed: boolean\n use(plugin: VobsPlugin): VobsApp<NodeType>\n mount(target: string | NodeType): void\n hydrate(target: string | NodeType): void\n update(): void\n destroy(): void\n}\n\nexport function createInjectionKey<T>(description: string): InjectionKey<T> {\n return Symbol(description) as InjectionKey<T>\n}\n\nexport function createVobs(\n config: VobsConfig<Node, Text, Element, Comment>\n): VobsApp<Node>\nexport function createVobs<\n NodeType = Node,\n TextNode extends NodeType = NodeType,\n ElementNode extends NodeType = NodeType,\n CommentNode extends NodeType = NodeType\n>(\n config: VobsConfig<NodeType, TextNode, ElementNode, CommentNode> & {\n renderer: VobsRenderer<NodeType, TextNode, ElementNode, CommentNode>\n }\n): VobsApp<NodeType>\nexport function createVobs(\n config: VobsConfig<any, any, any, any>\n): VobsApp<any> {\n if (!config.render) throw new Error('createVobs: render 不能为空')\n\n const renderer = config.renderer ?? createDOMRenderer()\n const rootOwner: Owner = createOwner()\n setOwnerDebugName(rootOwner, 'App')\n const cleanups: Array<() => void> = []\n const errorHandlers = new Set<(error: unknown) => void>()\n const installed = new Set<string>()\n const installing = new Set<string>()\n let mounted = false\n let destroyed = false\n let container: any = null\n let app!: VobsApp<any>\n\n if (config.onError) {\n errorHandlers.add(config.onError)\n cleanups.push(() => errorHandlers.delete(config.onError!))\n }\n\n const context: VobsContext = {\n get app(): VobsApp<any> {\n return app\n },\n\n provide<T>(key: InjectionKey<T>, value: T, options: ProvideOptions = {}): void {\n provideToOwner(rootOwner, key, value, options)\n },\n\n inject<T>(key: InjectionKey<T>): T | undefined {\n return injectFromOwner(rootOwner, key)\n },\n\n injectRequired<T>(key: InjectionKey<T>, description?: string): T {\n const value = injectFromOwner(rootOwner, key)\n if (value === undefined) {\n throw new Error(`Vobs: 找不到必需注入项${description ? ` ${description}` : ''}`)\n }\n return value\n },\n\n onDestroy(cleanup: () => void): void {\n cleanups.push(cleanup)\n },\n\n onError(handler: (error: unknown) => void): () => void {\n errorHandlers.add(handler)\n const remove = () => errorHandlers.delete(handler)\n cleanups.push(remove)\n return remove\n }\n }\n\n function notifyError(error: unknown): void {\n for (const handler of [...errorHandlers]) {\n try {\n handler(error)\n } catch {\n // 错误处理器不能覆盖触发它的原始错误。\n }\n }\n }\n\n function installPlugin(plugin: VobsPlugin): void {\n if (installed.has(plugin.name)) return\n if (installing.has(plugin.name)) {\n throw new Error(`Vobs: 插件依赖存在循环:${plugin.name}`)\n }\n\n installing.add(plugin.name)\n try {\n for (const dependency of plugin.requires ?? []) installPlugin(dependency)\n const cleanup = plugin.install?.(context)\n if (cleanup) cleanups.push(cleanup)\n installed.add(plugin.name)\n } finally {\n installing.delete(plugin.name)\n }\n }\n\n function cleanup(clearContainer = true): unknown {\n let firstError: unknown\n for (let index = cleanups.length - 1; index >= 0; index--) {\n try {\n cleanups[index]()\n } catch (error) {\n firstError ??= error\n }\n }\n cleanups.length = 0\n\n try {\n rootOwner.dispose()\n } catch (error) {\n firstError ??= error\n }\n\n if (container && clearContainer) {\n try {\n renderer.clear(container)\n } catch (error) {\n firstError ??= error\n }\n }\n return firstError\n }\n\n function start(target: string | any, hydrating: boolean): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能挂载')\n if (mounted) return\n\n container = typeof target === 'string' ? document.querySelector(target) : target\n if (!container) throw new Error(`mount: 目标不存在: ${target}`)\n if (hydrating && !renderer.beginHydration) {\n throw new Error('Vobs: 当前渲染器不支持 Hydration')\n }\n\n setRenderer(renderer)\n try {\n if (hydrating) renderer.beginHydration?.()\n const rootNode = rootOwner.run(config.render)\n if (!hydrating) renderer.clear(container)\n if (rootNode) insertRuntimeNode(container, rootNode as any, null)\n if (hydrating) renderer.completeHydration?.()\n mounted = true\n } catch (error) {\n notifyError(error)\n const cleanupError = cleanup(!hydrating)\n destroyed = true\n throw cleanupError ?? error\n }\n }\n\n app = {\n get mounted(): boolean {\n return mounted\n },\n\n get destroyed(): boolean {\n return destroyed\n },\n\n use(plugin: VobsPlugin): VobsApp<any> {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能安装插件')\n installPlugin(plugin)\n return app\n },\n\n mount(target: string | any): void {\n start(target, false)\n },\n\n hydrate(target: string | any): void {\n start(target, true)\n },\n\n update(): void {\n if (destroyed) throw new Error('Vobs: 已销毁的应用不能更新')\n try {\n scheduler.flush()\n } catch (error) {\n notifyError(error)\n throw error\n }\n },\n\n destroy(): void {\n if (destroyed) return\n try {\n const cleanupError = cleanup()\n if (cleanupError) {\n notifyError(cleanupError)\n throw cleanupError\n }\n } finally {\n mounted = false\n destroyed = true\n }\n }\n }\n\n try {\n for (const plugin of config.plugins ?? []) app.use(plugin)\n } catch (error) {\n notifyError(error)\n cleanup()\n destroyed = true\n throw error\n }\n\n return app\n}\n","import { getCurrentOwner, onDispose } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\nexport type LogValue = string | number | boolean | null | Readonly<LogObject> | readonly LogValue[]\n\nexport interface LogObject {\n readonly [key: string]: LogValue\n}\n\nexport type LogContext = Readonly<Record<string, unknown>>\n\nexport interface LogEntry {\n readonly timestamp: string\n readonly level: LogLevel\n readonly message: string\n readonly context: Readonly<LogObject>\n}\n\nexport interface LogTransport {\n write(entry: LogEntry): void | PromiseLike<void>\n flush?(): void | PromiseLike<void>\n dispose?(): void\n}\n\nexport interface Logger {\n readonly level: LogLevel\n log(level: LogLevel, message: string, context?: LogContext): void\n debug(message: string, context?: LogContext): void\n info(message: string, context?: LogContext): void\n warn(message: string, context?: LogContext): void\n error(message: string, context?: LogContext): void\n child(context: LogContext): Logger\n flush(): Promise<void>\n dispose(): void\n}\n\nexport interface LoggerOptions {\n readonly level?: LogLevel\n readonly context?: LogContext\n readonly transports?: readonly LogTransport[]\n readonly redactKeys?: readonly string[]\n readonly maxDepth?: number\n readonly clock?: () => Date\n readonly onTransportError?: (error: unknown, transport: LogTransport, entry?: LogEntry) => void\n}\n\nexport interface LoggerPluginOptions extends LoggerOptions {\n readonly logger?: Logger\n}\n\nexport interface ConsoleLike {\n debug?: (...data: unknown[]) => void\n info?: (...data: unknown[]) => void\n warn?: (...data: unknown[]) => void\n error?: (...data: unknown[]) => void\n log?: (...data: unknown[]) => void\n}\n\nexport interface MemoryLogTransport extends LogTransport {\n readonly entries: readonly LogEntry[]\n clear(): void\n}\n\nexport type LoggerErrorCode = 'LOGGER_CONTEXT_MISSING' | 'INVALID_LEVEL' | 'INVALID_TRANSPORT' | 'INVALID_MAX_DEPTH'\n\nexport class LoggerError extends Error {\n readonly code: LoggerErrorCode\n\n constructor(code: LoggerErrorCode, message: string) {\n super(message)\n this.name = 'LoggerError'\n this.code = code\n }\n}\n\nexport const LOGGER_KEY: InjectionKey<Logger> = createInjectionKey<Logger>('vobs.logger')\n\nconst levels: Readonly<Record<LogLevel, number>> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40\n}\n\nconst defaultRedactKeys = ['password', 'passwd', 'secret', 'token', 'authorization', 'cookie']\n\ninterface LoggerState {\n readonly level: LogLevel\n readonly transports: readonly LogTransport[]\n readonly redactKeys: ReadonlySet<string>\n readonly maxDepth: number\n readonly clock: () => Date\n readonly onTransportError: LoggerOptions['onTransportError']\n readonly pending: Set<Promise<void>>\n disposed: boolean\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const level = options.level ?? 'info'\n if (!isLogLevel(level)) throw new LoggerError('INVALID_LEVEL', `Vobs Logger: 不支持日志级别 ${String(level)}`)\n\n const maxDepth = options.maxDepth ?? 8\n if (!Number.isInteger(maxDepth) || maxDepth < 0) {\n throw new LoggerError('INVALID_MAX_DEPTH', 'Vobs Logger: maxDepth 必须是大于等于 0 的整数')\n }\n\n const transports = options.transports ?? [createConsoleTransport()]\n if (transports.some(transport => !transport || typeof transport.write !== 'function')) {\n throw new LoggerError('INVALID_TRANSPORT', 'Vobs Logger: transport 必须提供 write(entry)')\n }\n\n const state: LoggerState = {\n level,\n transports,\n redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map(key => key.toLowerCase())),\n maxDepth,\n clock: options.clock ?? (() => new Date()),\n onTransportError: options.onTransportError,\n pending: new Set(),\n disposed: false\n }\n const logger = createLoggerScope(state, options.context ?? {}, true)\n if (getCurrentOwner()) onDispose(logger.dispose)\n return logger\n}\n\nexport function createConsoleTransport(target: ConsoleLike | undefined = globalThis.console): LogTransport {\n return {\n write(entry): void {\n const output = target?.[entry.level] ?? target?.log\n output?.call(target, `[${entry.level}] ${entry.message}`, entry.context)\n }\n }\n}\n\nexport function createMemoryTransport(limit = Infinity): MemoryLogTransport {\n if ((!Number.isInteger(limit) && limit !== Infinity) || limit <= 0) {\n throw new RangeError('Vobs Logger: memory transport 的 limit 必须是正整数或 Infinity')\n }\n\n const entries: LogEntry[] = []\n return {\n get entries(): readonly LogEntry[] {\n return entries\n },\n write(entry): void {\n entries.push(entry)\n if (entries.length > limit) entries.splice(0, entries.length - limit)\n },\n clear(): void {\n entries.length = 0\n }\n }\n}\n\nexport function loggerPlugin(options: LoggerPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/logger',\n version: '0.1.0',\n install(context) {\n const ownedLogger = options.logger ? undefined : createLogger(options)\n context.provide(LOGGER_KEY, options.logger ?? ownedLogger!)\n return () => ownedLogger?.dispose()\n }\n }\n}\n\nexport function useLogger(): Logger {\n const logger = inject(LOGGER_KEY)\n if (!logger) throw new LoggerError('LOGGER_CONTEXT_MISSING', 'Vobs Logger: 找不到上下文,请安装 loggerPlugin')\n return logger\n}\n\nfunction createLoggerScope(state: LoggerState, baseContext: LogContext, ownsTransports = false): Logger {\n const context = { ...baseContext }\n let disposed = false\n return {\n level: state.level,\n\n log(level, message, details = {}): void {\n if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return\n const entry = freezeEntry({\n timestamp: state.clock().toISOString(),\n level,\n message,\n context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)\n })\n for (const transport of state.transports) writeToTransport(state, transport, entry)\n },\n\n debug(message, details): void {\n this.log('debug', message, details)\n },\n\n info(message, details): void {\n this.log('info', message, details)\n },\n\n warn(message, details): void {\n this.log('warn', message, details)\n },\n\n error(message, details): void {\n this.log('error', message, details)\n },\n\n child(details): Logger {\n return createLoggerScope(state, { ...context, ...details })\n },\n\n async flush(): Promise<void> {\n while (state.pending.size > 0) await Promise.all([...state.pending])\n for (const transport of state.transports) {\n try {\n await transport.flush?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n if (!ownsTransports || state.disposed) return\n state.disposed = true\n for (const transport of state.transports) {\n try {\n transport.dispose?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n }\n }\n}\n\nfunction writeToTransport(state: LoggerState, transport: LogTransport, entry: LogEntry): void {\n try {\n const result = transport.write(entry)\n if (!isPromiseLike(result)) return\n const pending = Promise.resolve(result).catch(error => {\n reportTransportError(state, error, transport, entry)\n })\n state.pending.add(pending)\n void pending.then(() => state.pending.delete(pending))\n } catch (error) {\n reportTransportError(state, error, transport, entry)\n }\n}\n\nfunction reportTransportError(\n state: LoggerState,\n error: unknown,\n transport: LogTransport,\n entry?: LogEntry\n): void {\n try {\n state.onTransportError?.(error, transport, entry)\n } catch {\n // Transport error reporting must never make application logging throw.\n }\n}\n\nfunction sanitizeContext(input: LogContext, redactKeys: ReadonlySet<string>, maxDepth: number): LogObject {\n const seen = new WeakSet<object>()\n return Object.freeze(sanitizeObject(input, redactKeys, maxDepth, seen))\n}\n\nfunction sanitizeObject(\n input: LogContext,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogObject {\n const output: Record<string, LogValue> = {}\n for (const [key, value] of Object.entries(input)) {\n output[key] = redactKeys.has(key.toLowerCase())\n ? '[REDACTED]'\n : sanitizeValue(value, redactKeys, depth, seen)\n }\n return Object.freeze(output)\n}\n\nfunction sanitizeValue(\n value: unknown,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value)\n if (typeof value === 'bigint' || typeof value === 'symbol' || typeof value === 'undefined') return String(value)\n if (typeof value === 'function') return `[Function ${value.name || 'anonymous'}]`\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString()\n if (value instanceof Error) {\n return Object.freeze({\n name: value.name,\n message: value.message,\n ...(value.stack ? { stack: value.stack } : {})\n })\n }\n if (depth === 0) return '[MaxDepth]'\n if (seen.has(value as object)) return '[Circular]'\n seen.add(value as object)\n if (Array.isArray(value)) {\n return Object.freeze(value.map(item => sanitizeValue(item, redactKeys, depth - 1, seen)))\n }\n return sanitizeObject(value as LogContext, redactKeys, depth - 1, seen)\n}\n\nfunction freezeEntry(entry: LogEntry): LogEntry {\n return Object.freeze(entry)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<void> {\n return Boolean(value) && typeof (value as PromiseLike<void>).then === 'function'\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === 'string' && value in levels\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { getCurrentOwner, onDispose } from '@vobs/reactivity'\nimport { createInjectionKey, inject, type InjectionKey, type VobsPlugin } from '@vobs/vobs'\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error'\n\nexport type LogValue = string | number | boolean | null | Readonly<LogObject> | readonly LogValue[]\n\nexport interface LogObject {\n readonly [key: string]: LogValue\n}\n\nexport type LogContext = Readonly<Record<string, unknown>>\n\nexport interface LogEntry {\n readonly timestamp: string\n readonly level: LogLevel\n readonly message: string\n readonly context: Readonly<LogObject>\n}\n\nexport interface LogTransport {\n write(entry: LogEntry): void | PromiseLike<void>\n flush?(): void | PromiseLike<void>\n dispose?(): void\n}\n\nexport interface Logger {\n readonly level: LogLevel\n log(level: LogLevel, message: string, context?: LogContext): void\n debug(message: string, context?: LogContext): void\n info(message: string, context?: LogContext): void\n warn(message: string, context?: LogContext): void\n error(message: string, context?: LogContext): void\n child(context: LogContext): Logger\n flush(): Promise<void>\n dispose(): void\n}\n\nexport interface LoggerOptions {\n readonly level?: LogLevel\n readonly context?: LogContext\n readonly transports?: readonly LogTransport[]\n readonly redactKeys?: readonly string[]\n readonly maxDepth?: number\n readonly clock?: () => Date\n readonly onTransportError?: (error: unknown, transport: LogTransport, entry?: LogEntry) => void\n}\n\nexport interface LoggerPluginOptions extends LoggerOptions {\n readonly logger?: Logger\n}\n\nexport interface ConsoleLike {\n debug?: (...data: unknown[]) => void\n info?: (...data: unknown[]) => void\n warn?: (...data: unknown[]) => void\n error?: (...data: unknown[]) => void\n log?: (...data: unknown[]) => void\n}\n\nexport interface MemoryLogTransport extends LogTransport {\n readonly entries: readonly LogEntry[]\n clear(): void\n}\n\nexport type LoggerErrorCode = 'LOGGER_CONTEXT_MISSING' | 'INVALID_LEVEL' | 'INVALID_TRANSPORT' | 'INVALID_MAX_DEPTH'\n\nexport class LoggerError extends Error {\n readonly code: LoggerErrorCode\n\n constructor(code: LoggerErrorCode, message: string) {\n super(message)\n this.name = 'LoggerError'\n this.code = code\n }\n}\n\nexport const LOGGER_KEY: InjectionKey<Logger> = createInjectionKey<Logger>('vobs.logger')\n\nconst levels: Readonly<Record<LogLevel, number>> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40\n}\n\nconst defaultRedactKeys = ['password', 'passwd', 'secret', 'token', 'authorization', 'cookie']\n\ninterface LoggerState {\n readonly level: LogLevel\n readonly transports: readonly LogTransport[]\n readonly redactKeys: ReadonlySet<string>\n readonly maxDepth: number\n readonly clock: () => Date\n readonly onTransportError: LoggerOptions['onTransportError']\n readonly pending: Set<Promise<void>>\n disposed: boolean\n}\n\nexport function createLogger(options: LoggerOptions = {}): Logger {\n const level = options.level ?? 'info'\n if (!isLogLevel(level)) throw new LoggerError('INVALID_LEVEL', `Vobs Logger: 不支持日志级别 ${String(level)}`)\n\n const maxDepth = options.maxDepth ?? 8\n if (!Number.isInteger(maxDepth) || maxDepth < 0) {\n throw new LoggerError('INVALID_MAX_DEPTH', 'Vobs Logger: maxDepth 必须是大于等于 0 的整数')\n }\n\n const transports = options.transports ?? [createConsoleTransport()]\n if (transports.some(transport => !transport || typeof transport.write !== 'function')) {\n throw new LoggerError('INVALID_TRANSPORT', 'Vobs Logger: transport 必须提供 write(entry)')\n }\n\n const state: LoggerState = {\n level,\n transports,\n redactKeys: new Set((options.redactKeys ?? defaultRedactKeys).map(key => key.toLowerCase())),\n maxDepth,\n clock: options.clock ?? (() => new Date()),\n onTransportError: options.onTransportError,\n pending: new Set(),\n disposed: false\n }\n const logger = createLoggerScope(state, options.context ?? {}, true)\n if (getCurrentOwner()) onDispose(logger.dispose)\n return logger\n}\n\nexport function createConsoleTransport(target: ConsoleLike | undefined = globalThis.console): LogTransport {\n return {\n write(entry): void {\n const output = target?.[entry.level] ?? target?.log\n output?.call(target, `[${entry.level}] ${entry.message}`, entry.context)\n }\n }\n}\n\nexport function createMemoryTransport(limit = Infinity): MemoryLogTransport {\n if ((!Number.isInteger(limit) && limit !== Infinity) || limit <= 0) {\n throw new RangeError('Vobs Logger: memory transport 的 limit 必须是正整数或 Infinity')\n }\n\n const entries: LogEntry[] = []\n return {\n get entries(): readonly LogEntry[] {\n return entries\n },\n write(entry): void {\n entries.push(entry)\n if (entries.length > limit) entries.splice(0, entries.length - limit)\n },\n clear(): void {\n entries.length = 0\n }\n }\n}\n\nexport function loggerPlugin(options: LoggerPluginOptions = {}): VobsPlugin {\n return {\n name: '@vobs/logger',\n version: '0.1.0',\n install(context) {\n const ownedLogger = options.logger ? undefined : createLogger(options)\n context.provide(LOGGER_KEY, options.logger ?? ownedLogger!)\n return () => ownedLogger?.dispose()\n }\n }\n}\n\nexport function useLogger(): Logger {\n const logger = inject(LOGGER_KEY)\n if (!logger) throw new LoggerError('LOGGER_CONTEXT_MISSING', 'Vobs Logger: 找不到上下文,请安装 loggerPlugin')\n return logger\n}\n\nfunction createLoggerScope(state: LoggerState, baseContext: LogContext, ownsTransports = false): Logger {\n const context = { ...baseContext }\n let disposed = false\n return {\n level: state.level,\n\n log(level, message, details = {}): void {\n if (state.disposed || disposed || !isLogLevel(level) || levels[level] < levels[state.level]) return\n const entry = freezeEntry({\n timestamp: state.clock().toISOString(),\n level,\n message,\n context: sanitizeContext({ ...context, ...details }, state.redactKeys, state.maxDepth)\n })\n for (const transport of state.transports) writeToTransport(state, transport, entry)\n },\n\n debug(message, details): void {\n this.log('debug', message, details)\n },\n\n info(message, details): void {\n this.log('info', message, details)\n },\n\n warn(message, details): void {\n this.log('warn', message, details)\n },\n\n error(message, details): void {\n this.log('error', message, details)\n },\n\n child(details): Logger {\n return createLoggerScope(state, { ...context, ...details })\n },\n\n async flush(): Promise<void> {\n while (state.pending.size > 0) await Promise.all([...state.pending])\n for (const transport of state.transports) {\n try {\n await transport.flush?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n },\n\n dispose(): void {\n if (disposed) return\n disposed = true\n if (!ownsTransports || state.disposed) return\n state.disposed = true\n for (const transport of state.transports) {\n try {\n transport.dispose?.()\n } catch (error) {\n reportTransportError(state, error, transport)\n }\n }\n }\n }\n}\n\nfunction writeToTransport(state: LoggerState, transport: LogTransport, entry: LogEntry): void {\n try {\n const result = transport.write(entry)\n if (!isPromiseLike(result)) return\n const pending = Promise.resolve(result).catch(error => {\n reportTransportError(state, error, transport, entry)\n })\n state.pending.add(pending)\n void pending.then(() => state.pending.delete(pending))\n } catch (error) {\n reportTransportError(state, error, transport, entry)\n }\n}\n\nfunction reportTransportError(\n state: LoggerState,\n error: unknown,\n transport: LogTransport,\n entry?: LogEntry\n): void {\n try {\n state.onTransportError?.(error, transport, entry)\n } catch {\n // Transport error reporting must never make application logging throw.\n }\n}\n\nfunction sanitizeContext(input: LogContext, redactKeys: ReadonlySet<string>, maxDepth: number): LogObject {\n const seen = new WeakSet<object>()\n return Object.freeze(sanitizeObject(input, redactKeys, maxDepth, seen))\n}\n\nfunction sanitizeObject(\n input: LogContext,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogObject {\n const output: Record<string, LogValue> = {}\n for (const [key, value] of Object.entries(input)) {\n output[key] = redactKeys.has(key.toLowerCase())\n ? '[REDACTED]'\n : sanitizeValue(value, redactKeys, depth, seen)\n }\n return Object.freeze(output)\n}\n\nfunction sanitizeValue(\n value: unknown,\n redactKeys: ReadonlySet<string>,\n depth: number,\n seen: WeakSet<object>\n): LogValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value\n if (typeof value === 'number') return Number.isFinite(value) ? value : String(value)\n if (typeof value === 'bigint' || typeof value === 'symbol' || typeof value === 'undefined') return String(value)\n if (typeof value === 'function') return `[Function ${value.name || 'anonymous'}]`\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? 'Invalid Date' : value.toISOString()\n if (value instanceof Error) {\n return Object.freeze({\n name: value.name,\n message: value.message,\n ...(value.stack ? { stack: value.stack } : {})\n })\n }\n if (depth === 0) return '[MaxDepth]'\n if (seen.has(value as object)) return '[Circular]'\n seen.add(value as object)\n if (Array.isArray(value)) {\n return Object.freeze(value.map(item => sanitizeValue(item, redactKeys, depth - 1, seen)))\n }\n return sanitizeObject(value as LogContext, redactKeys, depth - 1, seen)\n}\n\nfunction freezeEntry(entry: LogEntry): LogEntry {\n return Object.freeze(entry)\n}\n\nfunction isPromiseLike(value: unknown): value is PromiseLike<void> {\n return Boolean(value) && typeof (value as PromiseLike<void>).then === 'function'\n}\n\nfunction isLogLevel(value: unknown): value is LogLevel {\n return typeof value === 'string' && value in levels\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "git+https://github.com/vobsjs/vobs.git"
13
13
  },
14
- "version": "1.2.1",
14
+ "version": "1.2.2",
15
15
  "publishConfig": {
16
16
  "access": "public"
17
17
  },
@@ -35,8 +35,8 @@
35
35
  "./source/*": "./src/*"
36
36
  },
37
37
  "dependencies": {
38
- "@vobs/reactivity": "1.2.1",
39
- "@vobs/vobs": "1.2.1"
38
+ "@vobs/reactivity": "1.2.2",
39
+ "@vobs/vobs": "1.2.2"
40
40
  },
41
41
  "scripts": {
42
42
  "test": "vitest --environment jsdom"