@btravstack/core 0.29.0 → 0.30.1

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
@@ -124,14 +124,18 @@ const noObserver = () => () => {};
124
124
  * matters because the settling call sites are error paths, where a `tap` and a
125
125
  * `tapFailure` on the same chain, or a retry, is exactly the shape that fires
126
126
  * twice and doubles a failure count.
127
+ *
128
+ * A broken observer is dropped independently, on startup and settlement. No
129
+ * recursive reporting is attempted: telemetry must never alter the operation
130
+ * or prevent another observer from settling.
127
131
  */
128
132
  const observe = (observers, operation) => {
129
- const settlers = observers.map((observer) => observer(operation));
133
+ const settlers = observers.map((observer) => (0, unthrown.fromSafeThrowable)(observer)(operation).recoverDefect(() => (0, unthrown.Ok)(noObserver())).get());
130
134
  let done = false;
131
135
  return (settled) => {
132
136
  if (done) return;
133
137
  done = true;
134
- for (const settle of settlers) settle(settled);
138
+ for (const settle of settlers) (0, unthrown.fromSafeThrowable)(settle)(settled).recoverDefect(() => (0, unthrown.Ok)()).get();
135
139
  };
136
140
  };
137
141
  /**
@@ -143,14 +147,21 @@ const observe = (observers, operation) => {
143
147
  *
144
148
  * `settled` replaces either default where a starter has more to say: `ok`
145
149
  * receives the value (a cache reports a hit or a miss), `failure` the
146
- * `FailureView` (a store reports a missing object as an ordinary answer).
150
+ * `FailureView` (a store reports a missing object as an ordinary answer). A
151
+ * throwing shaping hook is dropped and the ordinary settlement is used.
147
152
  */
148
153
  const observed = (observers, operation, call, settled = {}) => {
149
154
  const settle = observe(observers, operation);
150
- return call().tap((value) => settle(settled.ok?.(value) ?? { outcome: "ok" })).tapFailure((failure) => settle(settled.failure?.(failure) ?? {
151
- outcome: "error",
152
- cause: failure.tag === "Err" ? failure.error : failure.cause
153
- }));
155
+ return (0, unthrown.OkAsync)().flatMap(call).tap((value) => {
156
+ const rendered = (0, unthrown.fromSafeThrowable)(() => settled.ok?.(value))().recoverDefect(() => (0, unthrown.Ok)(void 0)).get();
157
+ settle(rendered ?? { outcome: "ok" });
158
+ }).tapFailure((failure) => {
159
+ const rendered = (0, unthrown.fromSafeThrowable)(() => settled.failure?.(failure))().recoverDefect(() => (0, unthrown.Ok)(void 0)).get();
160
+ settle(rendered ?? {
161
+ outcome: "error",
162
+ cause: failure.tag === "Err" ? failure.error : failure.cause
163
+ });
164
+ });
154
165
  };
155
166
  //#endregion
156
167
  //#region src/clock.ts
package/dist/index.d.cts CHANGED
@@ -309,6 +309,10 @@ export declare const noObserver: () => Settle;
309
309
  * matters because the settling call sites are error paths, where a `tap` and a
310
310
  * `tapFailure` on the same chain, or a retry, is exactly the shape that fires
311
311
  * twice and doubles a failure count.
312
+ *
313
+ * A broken observer is dropped independently, on startup and settlement. No
314
+ * recursive reporting is attempted: telemetry must never alter the operation
315
+ * or prevent another observer from settling.
312
316
  */
313
317
  export declare const observe: (observers: readonly ((operation: Operation) => Settle)[], operation: Operation) => Settle;
314
318
  /**
@@ -320,7 +324,8 @@ export declare const observe: (observers: readonly ((operation: Operation) => Se
320
324
  *
321
325
  * `settled` replaces either default where a starter has more to say: `ok`
322
326
  * receives the value (a cache reports a hit or a miss), `failure` the
323
- * `FailureView` (a store reports a missing object as an ordinary answer).
327
+ * `FailureView` (a store reports a missing object as an ordinary answer). A
328
+ * throwing shaping hook is dropped and the ordinary settlement is used.
324
329
  */
325
330
  export declare const observed: <T, E>(observers: readonly ((operation: Operation) => Settle)[], operation: Operation, call: () => AsyncResult<T, E>, settled?: {
326
331
  readonly ok?: (value: T) => Settled;
package/dist/index.d.mts CHANGED
@@ -309,6 +309,10 @@ export declare const noObserver: () => Settle;
309
309
  * matters because the settling call sites are error paths, where a `tap` and a
310
310
  * `tapFailure` on the same chain, or a retry, is exactly the shape that fires
311
311
  * twice and doubles a failure count.
312
+ *
313
+ * A broken observer is dropped independently, on startup and settlement. No
314
+ * recursive reporting is attempted: telemetry must never alter the operation
315
+ * or prevent another observer from settling.
312
316
  */
313
317
  export declare const observe: (observers: readonly ((operation: Operation) => Settle)[], operation: Operation) => Settle;
314
318
  /**
@@ -320,7 +324,8 @@ export declare const observe: (observers: readonly ((operation: Operation) => Se
320
324
  *
321
325
  * `settled` replaces either default where a starter has more to say: `ok`
322
326
  * receives the value (a cache reports a hit or a miss), `failure` the
323
- * `FailureView` (a store reports a missing object as an ordinary answer).
327
+ * `FailureView` (a store reports a missing object as an ordinary answer). A
328
+ * throwing shaping hook is dropped and the ordinary settlement is used.
324
329
  */
325
330
  export declare const observed: <T, E>(observers: readonly ((operation: Operation) => Settle)[], operation: Operation, call: () => AsyncResult<T, E>, settled?: {
326
331
  readonly ok?: (value: T) => Settled;
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Module, Port, Provider } from "@btravstack/di";
2
- import { Err, Ok, OkAsync, P, TaggedError, allAsync, fromSafePromise } from "unthrown";
2
+ import { Err, Ok, OkAsync, P, TaggedError, allAsync, fromSafePromise, fromSafeThrowable } from "unthrown";
3
3
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
4
4
  import { Config, ConfigInvalid, Env } from "@btravstack/config";
5
5
  import { createServer } from "node:http";
@@ -123,14 +123,18 @@ const noObserver = () => () => {};
123
123
  * matters because the settling call sites are error paths, where a `tap` and a
124
124
  * `tapFailure` on the same chain, or a retry, is exactly the shape that fires
125
125
  * twice and doubles a failure count.
126
+ *
127
+ * A broken observer is dropped independently, on startup and settlement. No
128
+ * recursive reporting is attempted: telemetry must never alter the operation
129
+ * or prevent another observer from settling.
126
130
  */
127
131
  const observe = (observers, operation) => {
128
- const settlers = observers.map((observer) => observer(operation));
132
+ const settlers = observers.map((observer) => fromSafeThrowable(observer)(operation).recoverDefect(() => Ok(noObserver())).get());
129
133
  let done = false;
130
134
  return (settled) => {
131
135
  if (done) return;
132
136
  done = true;
133
- for (const settle of settlers) settle(settled);
137
+ for (const settle of settlers) fromSafeThrowable(settle)(settled).recoverDefect(() => Ok()).get();
134
138
  };
135
139
  };
136
140
  /**
@@ -142,14 +146,21 @@ const observe = (observers, operation) => {
142
146
  *
143
147
  * `settled` replaces either default where a starter has more to say: `ok`
144
148
  * receives the value (a cache reports a hit or a miss), `failure` the
145
- * `FailureView` (a store reports a missing object as an ordinary answer).
149
+ * `FailureView` (a store reports a missing object as an ordinary answer). A
150
+ * throwing shaping hook is dropped and the ordinary settlement is used.
146
151
  */
147
152
  const observed = (observers, operation, call, settled = {}) => {
148
153
  const settle = observe(observers, operation);
149
- return call().tap((value) => settle(settled.ok?.(value) ?? { outcome: "ok" })).tapFailure((failure) => settle(settled.failure?.(failure) ?? {
150
- outcome: "error",
151
- cause: failure.tag === "Err" ? failure.error : failure.cause
152
- }));
154
+ return OkAsync().flatMap(call).tap((value) => {
155
+ const rendered = fromSafeThrowable(() => settled.ok?.(value))().recoverDefect(() => Ok(void 0)).get();
156
+ settle(rendered ?? { outcome: "ok" });
157
+ }).tapFailure((failure) => {
158
+ const rendered = fromSafeThrowable(() => settled.failure?.(failure))().recoverDefect(() => Ok(void 0)).get();
159
+ settle(rendered ?? {
160
+ outcome: "error",
161
+ cause: failure.tag === "Err" ? failure.error : failure.cause
162
+ });
163
+ });
153
164
  };
154
165
  //#endregion
155
166
  //#region src/clock.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btravstack/core",
3
- "version": "0.29.0",
3
+ "version": "0.30.1",
4
4
  "description": "The application kernel: boot a di module into a running process, and stop it without losing work",
5
5
  "keywords": [
6
6
  "application",
@@ -45,23 +45,23 @@
45
45
  "./package.json": "./package.json"
46
46
  },
47
47
  "devDependencies": {
48
- "@btravstack/config": "0.29.0",
49
- "@btravstack/di": "0.29.0",
48
+ "@btravstack/config": "0.30.1",
49
+ "@btravstack/di": "0.30.1",
50
50
  "@btravstack/tsconfig": "0.4.0",
51
51
  "@stryker-mutator/core": "10.0.0",
52
52
  "@stryker-mutator/vitest-runner": "10.0.0",
53
53
  "@types/node": "26.6.4",
54
- "@unthrown/vitest": "5.12.0",
54
+ "@unthrown/vitest": "5.12.1",
55
55
  "@vitest/coverage-v8": "5.0.3",
56
56
  "tsdown": "0.23.0",
57
57
  "typescript": "7.0.2",
58
58
  "typescript-consumer": "npm:typescript@5.9.3",
59
- "unthrown": "5.12.0",
59
+ "unthrown": "5.12.1",
60
60
  "vitest": "5.0.3"
61
61
  },
62
62
  "peerDependencies": {
63
- "@btravstack/config": "^0.29.0",
64
- "@btravstack/di": "^0.29.0",
63
+ "@btravstack/config": "^0.30.1",
64
+ "@btravstack/di": "^0.30.1",
65
65
  "unthrown": "^5.0.0"
66
66
  },
67
67
  "engines": {