@actuallab/core 12.3.29 → 12.3.33

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
@@ -25,6 +25,9 @@ __export(index_exports, {
25
25
  AsyncLock: () => AsyncLock,
26
26
  DisposableBag: () => DisposableBag,
27
27
  EventHandlerSet: () => EventHandlerSet,
28
+ Log: () => Log,
29
+ LogLevel: () => LogLevel,
30
+ LogLevelController: () => LogLevelController,
28
31
  PromiseSource: () => PromiseSource,
29
32
  Result: () => Result,
30
33
  RetryDelayLimitExceeded: () => RetryDelayLimitExceeded,
@@ -33,7 +36,9 @@ __export(index_exports, {
33
36
  RetryDelayer: () => RetryDelayer,
34
37
  RingBuffer: () => RingBuffer,
35
38
  abortSignalKey: () => abortSignalKey,
39
+ createLogProvider: () => createLogProvider,
36
40
  errorResult: () => errorResult,
41
+ initLogging: () => initLogging,
37
42
  resolvedVoidPromise: () => resolvedVoidPromise,
38
43
  result: () => result,
39
44
  resultFrom: () => resultFrom,
@@ -44,6 +49,354 @@ module.exports = __toCommonJS(index_exports);
44
49
  // src/polyfills.ts
45
50
  Symbol.metadata ??= /* @__PURE__ */ Symbol("Symbol.metadata");
46
51
 
52
+ // src/disposable.ts
53
+ var DisposableBag = class {
54
+ _items = [];
55
+ _disposed = false;
56
+ get isDisposed() {
57
+ return this._disposed;
58
+ }
59
+ add(item) {
60
+ if (this._disposed)
61
+ throw new Error("DisposableBag is already disposed.");
62
+ this._items.push(item);
63
+ }
64
+ dispose() {
65
+ if (this._disposed) return;
66
+ this._disposed = true;
67
+ const items = this._items;
68
+ this._items = [];
69
+ for (let i = items.length - 1; i >= 0; i--) {
70
+ const item = items[i];
71
+ if ("dispose" in item) item.dispose();
72
+ }
73
+ }
74
+ async disposeAsync() {
75
+ if (this._disposed) return;
76
+ this._disposed = true;
77
+ const items = this._items;
78
+ this._items = [];
79
+ for (let i = items.length - 1; i >= 0; i--) {
80
+ const item = items[i];
81
+ if ("disposeAsync" in item) await item.disposeAsync();
82
+ else if ("dispose" in item) item.dispose();
83
+ }
84
+ }
85
+ };
86
+
87
+ // src/logging-init.ts
88
+ var GlobalThisKey = "logLevels";
89
+ var StorageKey = "logLevels";
90
+ var DateStorageKey = `${StorageKey}.date`;
91
+ var MaxStorageAge = 864e5 * 3;
92
+ var sessionStorage = typeof globalThis !== "undefined" && "sessionStorage" in globalThis ? globalThis.sessionStorage : null;
93
+ var isMainThread = typeof window !== "undefined";
94
+ function initLogging() {
95
+ Log.defaultMinLevel = 3 /* Warn */;
96
+ const minLevels = Log.minLevels;
97
+ const g = globalThis;
98
+ const existing = g[GlobalThisKey];
99
+ if (existing !== void 0) {
100
+ for (const [k, v] of existing.getMinLevels())
101
+ minLevels.set(k, v);
102
+ return;
103
+ }
104
+ g[GlobalThisKey] = new LogLevelController(minLevels);
105
+ const wasRestored = restore(minLevels);
106
+ if (wasRestored) {
107
+ if (isMainThread)
108
+ console.log("Logging: logLevels are restored");
109
+ } else {
110
+ if (isMainThread)
111
+ console.log("Logging: logLevels are reset");
112
+ reset(minLevels);
113
+ }
114
+ }
115
+ var LogLevelController = class {
116
+ constructor(minLevels) {
117
+ this.minLevels = minLevels;
118
+ }
119
+ /** Internal: used by initLogging() in secondary bundles to share the
120
+ * primary bundle's minLevels map. */
121
+ getMinLevels() {
122
+ return this.minLevels;
123
+ }
124
+ /** List the current set of overrides. */
125
+ list() {
126
+ return Object.fromEntries(this.minLevels);
127
+ }
128
+ /** Print every known scope's effective level to the console as a table.
129
+ * Shows: scope, effective level, the source ('override' / 'default-key' /
130
+ * 'package-default' / 'baseline'), and the package default for reference.
131
+ * Use this from the dev console to discover what to pass to override(). */
132
+ dump() {
133
+ const baseline = Log.defaultMinLevel;
134
+ const globalOverride = this.minLevels.get("default");
135
+ const allScopes = /* @__PURE__ */ new Set([
136
+ ...Log.knownScopes,
137
+ ...Log.scopeDefaults.keys(),
138
+ ...this.minLevels.keys()
139
+ ]);
140
+ allScopes.delete("default");
141
+ const rows = {};
142
+ const sorted = [...allScopes].sort();
143
+ for (const scope of sorted) {
144
+ const override = this.minLevels.get(scope);
145
+ const pkgDefault = Log.scopeDefaults.get(scope);
146
+ let level;
147
+ let source;
148
+ if (override !== void 0) {
149
+ level = override;
150
+ source = "override";
151
+ } else if (globalOverride !== void 0) {
152
+ level = globalOverride;
153
+ source = "minLevels.get('default')";
154
+ } else if (pkgDefault !== void 0) {
155
+ level = pkgDefault;
156
+ source = "package-default";
157
+ } else {
158
+ level = baseline;
159
+ source = "baseline";
160
+ }
161
+ rows[scope] = {
162
+ level: LogLevel[level],
163
+ source,
164
+ packageDefault: pkgDefault === void 0 ? "-" : LogLevel[pkgDefault]
165
+ };
166
+ }
167
+ console.table(rows);
168
+ console.log(
169
+ `Baseline: ${LogLevel[baseline]}` + (globalOverride === void 0 ? "" : `, default override: ${LogLevel[globalOverride]}`)
170
+ );
171
+ }
172
+ /** Override the level for a single scope. Persisted to sessionStorage. */
173
+ override(scope, newLevel) {
174
+ this.minLevels.set(scope, newLevel);
175
+ persist(this.minLevels);
176
+ }
177
+ /** Override the level for every scope whose name starts with scopePrefix
178
+ * (e.g. 'rpc.' to enable verbose RPC logging). Persisted. */
179
+ overrideAll(scopePrefix, newLevel) {
180
+ const matched = /* @__PURE__ */ new Set();
181
+ for (const [scope] of this.minLevels)
182
+ if (scope.startsWith(scopePrefix)) matched.add(scope);
183
+ for (const [scope] of Log.scopeDefaults)
184
+ if (scope.startsWith(scopePrefix)) matched.add(scope);
185
+ for (const scope of matched)
186
+ this.minLevels.set(scope, newLevel);
187
+ persist(this.minLevels);
188
+ }
189
+ /** Reset all overrides; package defaults take effect again. Persisted. */
190
+ reset() {
191
+ reset(this.minLevels);
192
+ persist(this.minLevels);
193
+ }
194
+ /** Clear all overrides (no global default unless `defaultLevel` is given). */
195
+ clear(defaultLevel) {
196
+ this.minLevels.clear();
197
+ if (defaultLevel !== void 0)
198
+ this.minLevels.set("default", defaultLevel);
199
+ persist(this.minLevels);
200
+ }
201
+ };
202
+ function restore(minLevels) {
203
+ if (!sessionStorage)
204
+ return false;
205
+ const dateJson = sessionStorage.getItem(DateStorageKey);
206
+ if (!dateJson)
207
+ return false;
208
+ if (Date.now() - JSON.parse(dateJson) > MaxStorageAge)
209
+ return false;
210
+ const readJson = sessionStorage.getItem(StorageKey);
211
+ if (!readJson)
212
+ return false;
213
+ const readMinLevels = new Map(JSON.parse(readJson));
214
+ if (typeof readMinLevels.size !== "number")
215
+ return false;
216
+ minLevels.clear();
217
+ readMinLevels.forEach((value, key) => minLevels.set(key, value));
218
+ return true;
219
+ }
220
+ function persist(minLevels) {
221
+ if (!sessionStorage)
222
+ return false;
223
+ sessionStorage.setItem(DateStorageKey, JSON.stringify(Date.now()));
224
+ sessionStorage.setItem(StorageKey, JSON.stringify(Array.from(minLevels.entries())));
225
+ return true;
226
+ }
227
+ function reset(minLevels) {
228
+ minLevels.clear();
229
+ persist(minLevels);
230
+ }
231
+
232
+ // src/logging.ts
233
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
234
+ LogLevel2[LogLevel2["Debug"] = 1] = "Debug";
235
+ LogLevel2[LogLevel2["Info"] = 2] = "Info";
236
+ LogLevel2[LogLevel2["Warn"] = 3] = "Warn";
237
+ LogLevel2[LogLevel2["Error"] = 4] = "Error";
238
+ LogLevel2[LogLevel2["None"] = 1e3] = "None";
239
+ return LogLevel2;
240
+ })(LogLevel || {});
241
+ var LogRefSet = class {
242
+ constructor(capacity) {
243
+ this.capacity = capacity;
244
+ }
245
+ items = [];
246
+ idSeed = 0;
247
+ ref(data) {
248
+ const itemIndex = this.items.findIndex((el) => el.ref.target === data);
249
+ if (itemIndex >= 0) {
250
+ const existing = this.items[itemIndex];
251
+ existing.touchedAt = Date.now();
252
+ return existing.ref;
253
+ }
254
+ const id = data.__logRefId ?? this.idSeed++;
255
+ const newRef = { target: data, id };
256
+ data.__logRefId = id;
257
+ if (this.items.length >= this.capacity)
258
+ this.removeOldest();
259
+ this.items.push({ ref: newRef, touchedAt: Date.now() });
260
+ return newRef;
261
+ }
262
+ removeOldest() {
263
+ let indexToEvict = 0;
264
+ let itemToEvict = this.items[0];
265
+ for (let i = 1; i < this.items.length; i++) {
266
+ const item = this.items[i];
267
+ if (item.touchedAt < itemToEvict.touchedAt) {
268
+ itemToEvict = item;
269
+ indexToEvict = i;
270
+ }
271
+ }
272
+ this.items.splice(indexToEvict, 1);
273
+ const ref = itemToEvict.ref;
274
+ ref.target = ref.target?.toString();
275
+ }
276
+ };
277
+ var Log = class _Log {
278
+ constructor(scope, level) {
279
+ this.scope = scope;
280
+ this.level = level;
281
+ const prefix = `[${scope}]`;
282
+ switch (level) {
283
+ case 1 /* Debug */:
284
+ this.log = (...data) => console.debug(prefix, ...data);
285
+ break;
286
+ case 2 /* Info */:
287
+ this.log = (...data) => console.log(prefix, ...data);
288
+ break;
289
+ case 3 /* Warn */:
290
+ this.log = (...data) => console.warn(prefix, ...data);
291
+ break;
292
+ case 4 /* Error */:
293
+ this.log = (...data) => console.error(prefix, ...data);
294
+ break;
295
+ case 1e3 /* None */:
296
+ throw new Error("LogLevel.None cannot be used here");
297
+ }
298
+ this.trace = (...data) => console.trace(prefix, ...data);
299
+ }
300
+ static isInitialized = false;
301
+ static logRefs = new LogRefSet(10);
302
+ /** User-set overrides (persisted to sessionStorage). Empty by default. */
303
+ static minLevels = /* @__PURE__ */ new Map();
304
+ /** Per-scope defaults registered by packages via createLogProvider(). */
305
+ static scopeDefaults = /* @__PURE__ */ new Map();
306
+ /** Every scope ever requested via Log.get(). Used by logLevels.dump()
307
+ * so devs can discover what's available to override at runtime. */
308
+ static knownScopes = /* @__PURE__ */ new Set();
309
+ /** Global baseline for any scope without a default or override. */
310
+ static defaultMinLevel = 3 /* Warn */;
311
+ static loggerFactory = (scope, level) => new _Log(scope, level);
312
+ log;
313
+ trace;
314
+ static get(scope) {
315
+ if (!this.isInitialized) {
316
+ this.isInitialized = true;
317
+ initLogging();
318
+ }
319
+ this.knownScopes.add(scope);
320
+ const minLevels = this.minLevels;
321
+ const minLevel = minLevels.get(scope) ?? minLevels.get("default") ?? this.scopeDefaults.get(scope) ?? this.defaultMinLevel;
322
+ const getLogger = (level) => level >= minLevel ? this.loggerFactory(scope, level) : null;
323
+ return {
324
+ logScope: scope,
325
+ debugLog: getLogger(1 /* Debug */),
326
+ infoLog: getLogger(2 /* Info */),
327
+ warnLog: getLogger(3 /* Warn */),
328
+ errorLog: getLogger(4 /* Error */)
329
+ };
330
+ }
331
+ static ref(data) {
332
+ if (!data)
333
+ return data;
334
+ return this.logRefs.ref(data);
335
+ }
336
+ assert(predicate, ...data) {
337
+ if (!predicate)
338
+ this.log(...data);
339
+ }
340
+ };
341
+ function createLogProvider(prefix, defaults) {
342
+ for (const [scope, level] of Object.entries(defaults)) {
343
+ const fullName = prefix + scope;
344
+ Log.scopeDefaults.set(fullName, level);
345
+ Log.knownScopes.add(fullName);
346
+ }
347
+ return (scope) => Log.get(prefix + scope);
348
+ }
349
+
350
+ // src/result.ts
351
+ var Result = class _Result {
352
+ hasValue;
353
+ hasError;
354
+ _value;
355
+ _error;
356
+ constructor(value, error) {
357
+ this.hasValue = error === void 0;
358
+ this.hasError = !this.hasValue;
359
+ this._value = value;
360
+ this._error = error;
361
+ }
362
+ get value() {
363
+ if (this.hasError) throw this._error;
364
+ return this._value;
365
+ }
366
+ get error() {
367
+ return this._error;
368
+ }
369
+ get valueOrUndefined() {
370
+ return this.hasValue ? this._value : void 0;
371
+ }
372
+ static ok(value) {
373
+ return new _Result(value);
374
+ }
375
+ static error(error) {
376
+ return new _Result(void 0, error);
377
+ }
378
+ };
379
+ function result(value, error) {
380
+ return new Result(value, error);
381
+ }
382
+ function errorResult(error) {
383
+ return Result.error(error);
384
+ }
385
+ function resultFrom(fn) {
386
+ try {
387
+ return result(fn());
388
+ } catch (e) {
389
+ return errorResult(e);
390
+ }
391
+ }
392
+ async function resultFromAsync(fn) {
393
+ try {
394
+ return result(await fn());
395
+ } catch (e) {
396
+ return errorResult(e);
397
+ }
398
+ }
399
+
47
400
  // src/async-context.ts
48
401
  var AsyncContextKey = class {
49
402
  id;
@@ -151,41 +504,6 @@ var AsyncLock = class {
151
504
  }
152
505
  };
153
506
 
154
- // src/disposable.ts
155
- var DisposableBag = class {
156
- _items = [];
157
- _disposed = false;
158
- get isDisposed() {
159
- return this._disposed;
160
- }
161
- add(item) {
162
- if (this._disposed)
163
- throw new Error("DisposableBag is already disposed.");
164
- this._items.push(item);
165
- }
166
- dispose() {
167
- if (this._disposed) return;
168
- this._disposed = true;
169
- const items = this._items;
170
- this._items = [];
171
- for (let i = items.length - 1; i >= 0; i--) {
172
- const item = items[i];
173
- if ("dispose" in item) item.dispose();
174
- }
175
- }
176
- async disposeAsync() {
177
- if (this._disposed) return;
178
- this._disposed = true;
179
- const items = this._items;
180
- this._items = [];
181
- for (let i = items.length - 1; i >= 0; i--) {
182
- const item = items[i];
183
- if ("disposeAsync" in item) await item.disposeAsync();
184
- else if ("dispose" in item) item.dispose();
185
- }
186
- }
187
- };
188
-
189
507
  // src/promise-source.ts
190
508
  var PromiseSource = class {
191
509
  promise;
@@ -337,56 +655,6 @@ var RingBuffer = class {
337
655
  }
338
656
  };
339
657
 
340
- // src/result.ts
341
- var Result = class _Result {
342
- hasValue;
343
- hasError;
344
- _value;
345
- _error;
346
- constructor(value, error) {
347
- this.hasValue = error === void 0;
348
- this.hasError = !this.hasValue;
349
- this._value = value;
350
- this._error = error;
351
- }
352
- get value() {
353
- if (this.hasError) throw this._error;
354
- return this._value;
355
- }
356
- get error() {
357
- return this._error;
358
- }
359
- get valueOrUndefined() {
360
- return this.hasValue ? this._value : void 0;
361
- }
362
- static ok(value) {
363
- return new _Result(value);
364
- }
365
- static error(error) {
366
- return new _Result(void 0, error);
367
- }
368
- };
369
- function result(value, error) {
370
- return new Result(value, error);
371
- }
372
- function errorResult(error) {
373
- return Result.error(error);
374
- }
375
- function resultFrom(fn) {
376
- try {
377
- return result(fn());
378
- } catch (e) {
379
- return errorResult(e);
380
- }
381
- }
382
- async function resultFromAsync(fn) {
383
- try {
384
- return result(await fn());
385
- } catch (e) {
386
- return errorResult(e);
387
- }
388
- }
389
-
390
658
  // src/retry-delay-seq.ts
391
659
  var DefaultSpread = 0.1;
392
660
  var DefaultMultiplier = 1.41421356237;
@@ -492,6 +760,9 @@ var RetryDelayer = class {
492
760
  AsyncLock,
493
761
  DisposableBag,
494
762
  EventHandlerSet,
763
+ Log,
764
+ LogLevel,
765
+ LogLevelController,
495
766
  PromiseSource,
496
767
  Result,
497
768
  RetryDelayLimitExceeded,
@@ -500,7 +771,9 @@ var RetryDelayer = class {
500
771
  RetryDelayer,
501
772
  RingBuffer,
502
773
  abortSignalKey,
774
+ createLogProvider,
503
775
  errorResult,
776
+ initLogging,
504
777
  resolvedVoidPromise,
505
778
  result,
506
779
  resultFrom,