@glubean/sdk 0.2.0 → 0.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.
Files changed (104) hide show
  1. package/dist/configure/http.d.ts +25 -0
  2. package/dist/configure/http.d.ts.map +1 -0
  3. package/dist/configure/http.js +88 -0
  4. package/dist/configure/http.js.map +1 -0
  5. package/dist/configure/index.d.ts +78 -0
  6. package/dist/configure/index.d.ts.map +1 -0
  7. package/dist/configure/index.js +78 -0
  8. package/dist/configure/index.js.map +1 -0
  9. package/dist/configure/plugin.d.ts +23 -0
  10. package/dist/configure/plugin.d.ts.map +1 -0
  11. package/dist/configure/plugin.js +81 -0
  12. package/dist/configure/plugin.js.map +1 -0
  13. package/dist/configure/runtime.d.ts +24 -0
  14. package/dist/configure/runtime.d.ts.map +1 -0
  15. package/dist/configure/runtime.js +45 -0
  16. package/dist/configure/runtime.js.map +1 -0
  17. package/dist/configure/template.d.ts +22 -0
  18. package/dist/configure/template.d.ts.map +1 -0
  19. package/dist/configure/template.js +34 -0
  20. package/dist/configure/template.js.map +1 -0
  21. package/dist/configure/vars.d.ts +20 -0
  22. package/dist/configure/vars.d.ts.map +1 -0
  23. package/dist/configure/vars.js +48 -0
  24. package/dist/configure/vars.js.map +1 -0
  25. package/dist/configure.d.ts +2 -150
  26. package/dist/configure.d.ts.map +1 -1
  27. package/dist/configure.js +2 -562
  28. package/dist/configure.js.map +1 -1
  29. package/dist/contract-artifacts.d.ts +268 -0
  30. package/dist/contract-artifacts.d.ts.map +1 -0
  31. package/dist/contract-artifacts.js +402 -0
  32. package/dist/contract-artifacts.js.map +1 -0
  33. package/dist/contract-core.d.ts +33 -1
  34. package/dist/contract-core.d.ts.map +1 -1
  35. package/dist/contract-core.js +51 -2
  36. package/dist/contract-core.js.map +1 -1
  37. package/dist/contract-http/adapter.d.ts.map +1 -1
  38. package/dist/contract-http/adapter.js +22 -7
  39. package/dist/contract-http/adapter.js.map +1 -1
  40. package/dist/contract-http/factory.d.ts.map +1 -1
  41. package/dist/contract-http/factory.js +13 -14
  42. package/dist/contract-http/factory.js.map +1 -1
  43. package/dist/contract-http/index.d.ts +4 -3
  44. package/dist/contract-http/index.d.ts.map +1 -1
  45. package/dist/contract-http/index.js +4 -3
  46. package/dist/contract-http/index.js.map +1 -1
  47. package/dist/contract-http/openapi.d.ts +56 -7
  48. package/dist/contract-http/openapi.d.ts.map +1 -1
  49. package/dist/contract-http/openapi.js +371 -21
  50. package/dist/contract-http/openapi.js.map +1 -1
  51. package/dist/contract-http/types.d.ts +2 -13
  52. package/dist/contract-http/types.d.ts.map +1 -1
  53. package/dist/contract-types.d.ts +59 -10
  54. package/dist/contract-types.d.ts.map +1 -1
  55. package/dist/expect.d.ts +13 -0
  56. package/dist/expect.d.ts.map +1 -1
  57. package/dist/expect.js +18 -0
  58. package/dist/expect.js.map +1 -1
  59. package/dist/index.d.ts +61 -518
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +26 -835
  62. package/dist/index.js.map +1 -1
  63. package/dist/install-plugin.d.ts +94 -0
  64. package/dist/install-plugin.d.ts.map +1 -0
  65. package/dist/install-plugin.js +222 -0
  66. package/dist/install-plugin.js.map +1 -0
  67. package/dist/internal.d.ts +2 -0
  68. package/dist/internal.d.ts.map +1 -1
  69. package/dist/internal.js +6 -0
  70. package/dist/internal.js.map +1 -1
  71. package/dist/plugin.d.ts +45 -34
  72. package/dist/plugin.d.ts.map +1 -1
  73. package/dist/plugin.js +47 -34
  74. package/dist/plugin.js.map +1 -1
  75. package/dist/runtime-carrier.d.ts +142 -0
  76. package/dist/runtime-carrier.d.ts.map +1 -0
  77. package/dist/runtime-carrier.js +148 -0
  78. package/dist/runtime-carrier.js.map +1 -0
  79. package/dist/session.d.ts.map +1 -1
  80. package/dist/session.js +2 -1
  81. package/dist/session.js.map +1 -1
  82. package/dist/test/builder.d.ts +249 -0
  83. package/dist/test/builder.d.ts.map +1 -0
  84. package/dist/test/builder.js +265 -0
  85. package/dist/test/builder.js.map +1 -0
  86. package/dist/test/each-builder.d.ts +244 -0
  87. package/dist/test/each-builder.d.ts.map +1 -0
  88. package/dist/test/each-builder.js +268 -0
  89. package/dist/test/each-builder.js.map +1 -0
  90. package/dist/test/extend.d.ts +59 -0
  91. package/dist/test/extend.d.ts.map +1 -0
  92. package/dist/test/extend.js +111 -0
  93. package/dist/test/extend.js.map +1 -0
  94. package/dist/test/utils.d.ts +39 -0
  95. package/dist/test/utils.d.ts.map +1 -0
  96. package/dist/test/utils.js +91 -0
  97. package/dist/test/utils.js.map +1 -0
  98. package/dist/types.d.ts +89 -111
  99. package/dist/types.d.ts.map +1 -1
  100. package/package.json +1 -1
  101. package/dist/contract-http/markdown.d.ts +0 -10
  102. package/dist/contract-http/markdown.d.ts.map +0 -1
  103. package/dist/contract-http/markdown.js +0 -21
  104. package/dist/contract-http/markdown.js.map +0 -1
package/dist/plugin.js CHANGED
@@ -1,57 +1,70 @@
1
1
  /**
2
- * Plugin definition helper for Glubean SDK.
2
+ * Plugin authoring helpers.
3
3
  *
4
- * Plugin authors use `definePlugin()` to create plugin factories that
5
- * integrate with `configure({ plugins: { ... } })`. This is the recommended
6
- * way to define plugins — it handles the `PluginFactory` phantom type trick
7
- * so plugin authors don't need to understand it.
4
+ * Two APIs live here, one per concept:
8
5
  *
9
- * @example
10
- * ```ts
11
- * import { definePlugin } from "@glubean/sdk";
6
+ * 1. **`definePlugin(manifest)`** — declare a plugin manifest for global
7
+ * registration (matchers, protocol adapters, one-time setup). Consumed by
8
+ * {@link installPlugin} in `./install-plugin.js`. This is the primary API
9
+ * for plugin packages like `@glubean/graphql` and `@glubean/grpc`.
12
10
  *
13
- * export const myPlugin = (opts: MyOptions) =>
14
- * definePlugin((runtime) => {
15
- * const baseUrl = runtime.requireVar(opts.baseUrlKey);
16
- * return new MyClient(baseUrl);
17
- * });
18
- * ```
11
+ * 2. **`defineClientFactory(create)`** declare a lazy client factory for
12
+ * per-file injection via `configure({ plugins })`. This is what the
13
+ * legacy `definePlugin((runtime) => T)` signature used to do; the name
14
+ * has been corrected to describe what it actually is (a client factory,
15
+ * not a plugin).
16
+ *
17
+ * The legacy `definePlugin((runtime) => T)` overload was removed in Phase 3.
18
+ * Migrate call sites to `defineClientFactory((runtime) => T)` for the same
19
+ * behavior and better naming.
19
20
  *
20
21
  * @module plugin
21
22
  */
22
23
  /**
23
- * Create a plugin factory. This is the recommended way to define plugins.
24
+ * Declare a lazy client factory.
24
25
  *
25
- * The factory function receives a `GlubeanRuntime` with access to vars,
26
- * secrets, HTTP client, and template resolution. It is called lazily on
26
+ * The factory function receives a `GlubeanRuntime` (vars / secrets / http /
27
+ * template resolution) and returns a client instance. It is invoked lazily on
27
28
  * first property access during test execution, not at module load time.
28
29
  *
29
- * @param create Factory function that receives the runtime and returns the plugin instance
30
- * @returns A `PluginFactory<T>` suitable for use in `configure({ plugins: { ... } })`
30
+ * Output is consumed by `configure({ plugins: { name: factory } })` for
31
+ * per-file client injection.
32
+ *
33
+ * @param create Factory function receiving the runtime; returns the client.
34
+ * @returns A `ClientFactory<T>` suitable for `configure({ plugins })`.
31
35
  *
32
- * @example Simple plugin
36
+ * @example Simple client
33
37
  * ```ts
34
- * export const myPlugin = (opts: { baseUrlKey: string }) =>
35
- * definePlugin((runtime) => {
38
+ * export const myClient = (opts: { baseUrlKey: string }) =>
39
+ * defineClientFactory((runtime) => {
36
40
  * const baseUrl = runtime.requireVar(opts.baseUrlKey);
37
41
  * return new MyClient(baseUrl);
38
42
  * });
39
43
  * ```
44
+ */
45
+ export function defineClientFactory(create) {
46
+ return { __type: undefined, create };
47
+ }
48
+ /**
49
+ * Declare a plugin manifest for global registration.
40
50
  *
41
- * @example Plugin with auth headers
51
+ * The returned manifest is consumed by `installPlugin(...manifests)` at
52
+ * bootstrap time. A manifest can declare custom matchers, protocol adapters,
53
+ * and a one-time `setup()` hook. See {@link PluginManifest}.
54
+ *
55
+ * @example Plugin manifest
42
56
  * ```ts
43
- * export const graphql = (opts: { endpoint: string; headers?: Record<string, string> }) =>
44
- * definePlugin((runtime) => {
45
- * const url = runtime.requireVar(opts.endpoint);
46
- * const headers: Record<string, string> = {};
47
- * for (const [k, v] of Object.entries(opts.headers ?? {})) {
48
- * headers[k] = runtime.resolveTemplate(v);
49
- * }
50
- * return createGraphQLClient(runtime.http, { endpoint: url, headers });
51
- * });
57
+ * export default definePlugin({
58
+ * name: "@glubean/graphql",
59
+ * matchers: { toHaveGraphqlData, toHaveGraphqlErrorCode },
60
+ * contracts: { graphql: graphqlAdapter },
61
+ * setup() {
62
+ * // Optional one-time registration work
63
+ * },
64
+ * });
52
65
  * ```
53
66
  */
54
- export function definePlugin(create) {
55
- return { __type: undefined, create };
67
+ export function definePlugin(manifest) {
68
+ return manifest;
56
69
  }
57
70
  //# sourceMappingURL=plugin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,YAAY,CAC1B,MAAsC;IAEtC,OAAO,EAAE,MAAM,EAAE,SAAyB,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC"}
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAsC;IAEtC,OAAO,EAAE,MAAM,EAAE,SAAyB,EAAE,MAAM,EAAE,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,YAAY,CAAC,QAAwB;IACnD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * RuntimeCarrier — internal abstraction over how the SDK reaches the current
3
+ * per-test runtime context (vars / secrets / session / http / trace hooks).
4
+ *
5
+ * **Public API is zero-change.** All user-facing surfaces (`ctx.http`,
6
+ * `ctx.vars`, `ctx.secrets`, `ctx.session`) continue to work exactly as
7
+ * before.
8
+ *
9
+ * ## Default impl
10
+ *
11
+ * {@link createAlsCarrier} — `AsyncLocalStorage`-backed with a closure-level
12
+ * module slot fallback. Concurrent `runWithRuntime()` callers are isolated
13
+ * (each sees their own runtime across async boundaries). All first-party
14
+ * packages (`runner` harness, `browser` plugin) read/write the carrier via
15
+ * `@glubean/sdk/internal`, never through `globalThis`.
16
+ *
17
+ * ## Retained alternate: {@link createGlobalThisCarrier}
18
+ *
19
+ * Historical R1 impl backed by `globalThis.__glubeanRuntime`. Not the default
20
+ * any longer — kept in source as a revert target and test fixture. Can be
21
+ * reinstalled via {@link installCarrier} if an ALS regression ever needs a
22
+ * one-line rollback.
23
+ *
24
+ * ## Audience
25
+ *
26
+ * Exported via `@glubean/sdk/internal`. Consumed by:
27
+ * - `@glubean/runner` (harness) — sets the runtime before user code runs.
28
+ * - `@glubean/browser`, other first-party plugins — read test metadata.
29
+ *
30
+ * User test code must **not** import from this module.
31
+ *
32
+ * @internal
33
+ */
34
+ import type { GlubeanAction, GlubeanEvent, GlubeanRuntime as PublicGlubeanRuntime, HttpClient, Trace } from "./types.js";
35
+ /**
36
+ * Shape of the runtime context injected by the harness before test execution.
37
+ *
38
+ * This is the **internal** shape — the public `GlubeanRuntime` exported from
39
+ * the top-level SDK adds helper methods (`requireVar`, `requireSecret`,
40
+ * `resolveTemplate`) for plugin authors. The carrier transports this internal
41
+ * shape; `configure()` augments it before handing to plugins.
42
+ *
43
+ * @internal
44
+ */
45
+ export interface InternalRuntime {
46
+ vars: Record<string, string>;
47
+ secrets: Record<string, string>;
48
+ /** Session key-value store. Set during session setup, available to all tests. */
49
+ session: Record<string, unknown>;
50
+ http: HttpClient;
51
+ test?: PublicGlubeanRuntime["test"];
52
+ trace?(t: Trace): void;
53
+ action?(a: GlubeanAction): void;
54
+ event?(ev: GlubeanEvent): void;
55
+ log?(message: string, data?: unknown): void;
56
+ }
57
+ /**
58
+ * Abstraction over where the current runtime lives.
59
+ *
60
+ * Implementations:
61
+ * - {@link createAlsCarrier} — current default. Concurrent isolation via
62
+ * AsyncLocalStorage.
63
+ * - {@link createGlobalThisCarrier} — retained revert target.
64
+ *
65
+ * @internal
66
+ */
67
+ export interface RuntimeCarrier {
68
+ get(): InternalRuntime | undefined;
69
+ set(rt: InternalRuntime | undefined): void;
70
+ /**
71
+ * Run `fn` with `rt` as the active runtime, restoring the previous value
72
+ * afterwards.
73
+ *
74
+ * **Async contract:** if `fn()` returns a `Promise`, the previous runtime
75
+ * is restored only after that Promise settles (resolve or reject). Code
76
+ * after `await` points inside `fn` therefore observes `rt`, not the
77
+ * restored value.
78
+ *
79
+ * **Concurrency:**
80
+ * - ALS impl (default): true isolation — concurrent `runWith()` callers
81
+ * each see their own `rt` via AsyncLocalStorage across all async
82
+ * boundaries.
83
+ * - globalThis impl: single shared slot — two *concurrent* `runWith()`
84
+ * calls race the slot. Sequential / single-in-flight safe.
85
+ */
86
+ runWith<T>(rt: InternalRuntime, fn: () => T): T;
87
+ }
88
+ /**
89
+ * globalThis-backed carrier. **Not the default** — retained in source as a
90
+ * revert target and test fixture. Uses `globalThis.__glubeanRuntime` as the
91
+ * single shared slot.
92
+ *
93
+ * @internal
94
+ */
95
+ export declare function createGlobalThisCarrier(): RuntimeCarrier;
96
+ /**
97
+ * Default carrier: AsyncLocalStorage-backed with a closure module slot.
98
+ *
99
+ * Storage:
100
+ * - **ALS store** — authoritative for code running inside a
101
+ * {@link RuntimeCarrier.runWith} scope. Propagates across all async
102
+ * boundaries. Concurrent callers are fully isolated.
103
+ * - **Module slot** — closure-scoped variable set by {@link RuntimeCarrier.set}
104
+ * for code running outside any `runWith()` scope (e.g. harness code after
105
+ * a subprocess-level `setRuntime()` but before any `runWith()` wrap).
106
+ *
107
+ * `get()` reads ALS first, falls back to the module slot. No `globalThis`
108
+ * access — external plugins must migrate to `@glubean/sdk/internal.getRuntime`.
109
+ *
110
+ * @internal
111
+ */
112
+ export declare function createAlsCarrier(): RuntimeCarrier;
113
+ /**
114
+ * Replace the active carrier. Used by tests and by the future R2 opt-in path.
115
+ *
116
+ * @internal
117
+ */
118
+ export declare function installCarrier(c: RuntimeCarrier): void;
119
+ /**
120
+ * Read the current runtime context. Returns `undefined` when called outside
121
+ * of test execution (e.g. at module load / scanner time). Callers that need
122
+ * the throw-on-missing contract should wrap with their own `requireRuntime()`.
123
+ *
124
+ * @internal
125
+ */
126
+ export declare function getRuntime(): InternalRuntime | undefined;
127
+ /**
128
+ * Install a runtime into the carrier. The harness calls this once per test
129
+ * subprocess before the user module is imported.
130
+ *
131
+ * @internal
132
+ */
133
+ export declare function setRuntime(rt: InternalRuntime | undefined): void;
134
+ /**
135
+ * Run `fn` with `rt` as the active runtime, restoring the previous value on
136
+ * exit. In R1 this is a synchronous swap of the globalThis slot; in R2 it
137
+ * becomes an ALS-scoped execution. Call sites do not change between rounds.
138
+ *
139
+ * @internal
140
+ */
141
+ export declare function runWithRuntime<T>(rt: InternalRuntime, fn: () => T): T;
142
+ //# sourceMappingURL=runtime-carrier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-carrier.d.ts","sourceRoot":"","sources":["../src/runtime-carrier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,cAAc,IAAI,oBAAoB,EACtC,UAAU,EACV,KAAK,EACN,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,CAAC,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACpC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/B,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC7C;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,IAAI,eAAe,GAAG,SAAS,CAAC;IACnC,GAAG,CAAC,EAAE,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3C;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;CACjD;AAID;;;;;;GAMG;AACH,wBAAgB,uBAAuB,IAAI,cAAc,CA8BxD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,CAkBjD;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,IAAI,CAEtD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,eAAe,GAAG,SAAS,CAExD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAEhE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAErE"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * RuntimeCarrier — internal abstraction over how the SDK reaches the current
3
+ * per-test runtime context (vars / secrets / session / http / trace hooks).
4
+ *
5
+ * **Public API is zero-change.** All user-facing surfaces (`ctx.http`,
6
+ * `ctx.vars`, `ctx.secrets`, `ctx.session`) continue to work exactly as
7
+ * before.
8
+ *
9
+ * ## Default impl
10
+ *
11
+ * {@link createAlsCarrier} — `AsyncLocalStorage`-backed with a closure-level
12
+ * module slot fallback. Concurrent `runWithRuntime()` callers are isolated
13
+ * (each sees their own runtime across async boundaries). All first-party
14
+ * packages (`runner` harness, `browser` plugin) read/write the carrier via
15
+ * `@glubean/sdk/internal`, never through `globalThis`.
16
+ *
17
+ * ## Retained alternate: {@link createGlobalThisCarrier}
18
+ *
19
+ * Historical R1 impl backed by `globalThis.__glubeanRuntime`. Not the default
20
+ * any longer — kept in source as a revert target and test fixture. Can be
21
+ * reinstalled via {@link installCarrier} if an ALS regression ever needs a
22
+ * one-line rollback.
23
+ *
24
+ * ## Audience
25
+ *
26
+ * Exported via `@glubean/sdk/internal`. Consumed by:
27
+ * - `@glubean/runner` (harness) — sets the runtime before user code runs.
28
+ * - `@glubean/browser`, other first-party plugins — read test metadata.
29
+ *
30
+ * User test code must **not** import from this module.
31
+ *
32
+ * @internal
33
+ */
34
+ import { AsyncLocalStorage } from "node:async_hooks";
35
+ const GLOBAL_SLOT = "__glubeanRuntime";
36
+ /**
37
+ * globalThis-backed carrier. **Not the default** — retained in source as a
38
+ * revert target and test fixture. Uses `globalThis.__glubeanRuntime` as the
39
+ * single shared slot.
40
+ *
41
+ * @internal
42
+ */
43
+ export function createGlobalThisCarrier() {
44
+ return {
45
+ get() {
46
+ return globalThis[GLOBAL_SLOT];
47
+ },
48
+ set(rt) {
49
+ globalThis[GLOBAL_SLOT] = rt;
50
+ },
51
+ runWith(rt, fn) {
52
+ const prev = globalThis[GLOBAL_SLOT];
53
+ globalThis[GLOBAL_SLOT] = rt;
54
+ let result;
55
+ try {
56
+ result = fn();
57
+ }
58
+ catch (err) {
59
+ globalThis[GLOBAL_SLOT] = prev;
60
+ throw err;
61
+ }
62
+ // Async path: defer restore until the promise settles so that
63
+ // continuations inside `fn` after `await` still observe `rt`.
64
+ if (result !== null && typeof result === "object" && typeof result.then === "function") {
65
+ return (Promise.resolve(result).finally(() => {
66
+ globalThis[GLOBAL_SLOT] = prev;
67
+ }));
68
+ }
69
+ // Sync path: restore immediately.
70
+ globalThis[GLOBAL_SLOT] = prev;
71
+ return result;
72
+ },
73
+ };
74
+ }
75
+ /**
76
+ * Default carrier: AsyncLocalStorage-backed with a closure module slot.
77
+ *
78
+ * Storage:
79
+ * - **ALS store** — authoritative for code running inside a
80
+ * {@link RuntimeCarrier.runWith} scope. Propagates across all async
81
+ * boundaries. Concurrent callers are fully isolated.
82
+ * - **Module slot** — closure-scoped variable set by {@link RuntimeCarrier.set}
83
+ * for code running outside any `runWith()` scope (e.g. harness code after
84
+ * a subprocess-level `setRuntime()` but before any `runWith()` wrap).
85
+ *
86
+ * `get()` reads ALS first, falls back to the module slot. No `globalThis`
87
+ * access — external plugins must migrate to `@glubean/sdk/internal.getRuntime`.
88
+ *
89
+ * @internal
90
+ */
91
+ export function createAlsCarrier() {
92
+ const als = new AsyncLocalStorage();
93
+ let moduleSlot;
94
+ return {
95
+ get() {
96
+ return als.getStore() ?? moduleSlot;
97
+ },
98
+ set(rt) {
99
+ moduleSlot = rt;
100
+ },
101
+ runWith(rt, fn) {
102
+ // ALS natively propagates `rt` across await boundaries — no manual
103
+ // save/restore of the module slot is needed. `als.run(rt, fn)` binds
104
+ // `rt` for the duration of `fn`'s continuation chain and unbinds
105
+ // automatically when the returned promise settles.
106
+ return als.run(rt, fn);
107
+ },
108
+ };
109
+ }
110
+ let _carrier = createAlsCarrier();
111
+ /**
112
+ * Replace the active carrier. Used by tests and by the future R2 opt-in path.
113
+ *
114
+ * @internal
115
+ */
116
+ export function installCarrier(c) {
117
+ _carrier = c;
118
+ }
119
+ /**
120
+ * Read the current runtime context. Returns `undefined` when called outside
121
+ * of test execution (e.g. at module load / scanner time). Callers that need
122
+ * the throw-on-missing contract should wrap with their own `requireRuntime()`.
123
+ *
124
+ * @internal
125
+ */
126
+ export function getRuntime() {
127
+ return _carrier.get();
128
+ }
129
+ /**
130
+ * Install a runtime into the carrier. The harness calls this once per test
131
+ * subprocess before the user module is imported.
132
+ *
133
+ * @internal
134
+ */
135
+ export function setRuntime(rt) {
136
+ _carrier.set(rt);
137
+ }
138
+ /**
139
+ * Run `fn` with `rt` as the active runtime, restoring the previous value on
140
+ * exit. In R1 this is a synchronous swap of the globalThis slot; in R2 it
141
+ * becomes an ALS-scoped execution. Call sites do not change between rounds.
142
+ *
143
+ * @internal
144
+ */
145
+ export function runWithRuntime(rt, fn) {
146
+ return _carrier.runWith(rt, fn);
147
+ }
148
+ //# sourceMappingURL=runtime-carrier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-carrier.js","sourceRoot":"","sources":["../src/runtime-carrier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAgErD,MAAM,WAAW,GAAG,kBAAkB,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,GAAG;YACD,OAAQ,UAAkB,CAAC,WAAW,CAAgC,CAAC;QACzE,CAAC;QACD,GAAG,CAAC,EAAE;YACH,UAAkB,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC;QACD,OAAO,CAAC,EAAE,EAAE,EAAE;YACZ,MAAM,IAAI,GAAI,UAAkB,CAAC,WAAW,CAAC,CAAC;YAC7C,UAAkB,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC;YACtC,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,GAAG,EAAE,EAAE,CAAC;YAChB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACZ,UAAkB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;gBACxC,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,8DAA8D;YAC9D,8DAA8D;YAC9D,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAQ,MAA+B,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACjH,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAA0B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;oBAC9D,UAAkB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;gBAC1C,CAAC,CAAC,CAA0B,CAAC;YAC/B,CAAC;YACD,kCAAkC;YACjC,UAAkB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC;YACxC,OAAO,MAA+B,CAAC;QACzC,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,IAAI,iBAAiB,EAAmB,CAAC;IACrD,IAAI,UAAuC,CAAC;IAC5C,OAAO;QACL,GAAG;YACD,OAAO,GAAG,CAAC,QAAQ,EAAE,IAAI,UAAU,CAAC;QACtC,CAAC;QACD,GAAG,CAAC,EAAE;YACJ,UAAU,GAAG,EAAE,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,EAAE,EAAE,EAAE;YACZ,mEAAmE;YACnE,qEAAqE;YACrE,iEAAiE;YACjE,mDAAmD;YACnD,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACzB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,QAAQ,GAAmB,gBAAgB,EAAE,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,CAAiB;IAC9C,QAAQ,GAAG,CAAC,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC,GAAG,EAAE,CAAC;AACxB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,EAA+B;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACnB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAI,EAAmB,EAAE,EAAW;IAChE,OAAO,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAClC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,iBAAiB,CAEvE;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO;IAClB,yDAAyD;mBACrD,CAAC,iBAAiB,MAAM,KAAG,CAAC,GAAG,SAAS;IAI5C,8CAA8C;uBACtC,CAAC,iBAAiB,MAAM,KAAG,CAAC;IAYpC;;;;;;OAMG;wBACM,MAAM,SAAS,OAAO,KAAG,IAAI;IAItC,kCAAkC;wBACzB,MAAM,KAAG,OAAO;IAIzB,yDAAyD;4BAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAG1B,CAAC"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,GAAG,iBAAiB,CAEvE;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,OAAO;IAClB,yDAAyD;mBACrD,CAAC,iBAAiB,MAAM,KAAG,CAAC,GAAG,SAAS;IAI5C,8CAA8C;uBACtC,CAAC,iBAAiB,MAAM,KAAG,CAAC;IAYpC;;;;;;OAMG;wBACM,MAAM,SAAS,OAAO,KAAG,IAAI;IAItC,kCAAkC;wBACzB,MAAM,KAAG,OAAO;IAIzB,yDAAyD;4BAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAG1B,CAAC"}
package/dist/session.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { getRuntime } from "./runtime-carrier.js";
1
2
  /**
2
3
  * Define a session setup/teardown lifecycle for cross-file state sharing.
3
4
  *
@@ -31,7 +32,7 @@ export function defineSession(def) {
31
32
  // Global session accessor — read-only, lazy, for use outside test functions
32
33
  // =============================================================================
33
34
  function getRuntimeSession() {
34
- const runtime = globalThis.__glubeanRuntime;
35
+ const runtime = getRuntime();
35
36
  if (!runtime) {
36
37
  throw new Error("session can only be accessed during test execution. " +
37
38
  "Did you try to read a session value at module load time? " +
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAEhF,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAI,UAAkB,CAAC,gBAAgB,CAAC;IACrD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,sDAAsD;YACpD,2DAA2D;YAC3D,oEAAoE,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,yDAAyD;IACzD,GAAG,CAAc,GAAW;QAC1B,OAAO,iBAAiB,EAAE,CAAC,GAAG,CAAkB,CAAC;IACnD,CAAC;IAED,8CAA8C;IAC9C,OAAO,CAAc,GAAW;QAC9B,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,kCAAkC,GAAG,KAAK;gBACxC,mEAAmE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,KAAU,CAAC;IACpB,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,GAAW,EAAE,KAAc;QAC7B,iBAAiB,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnC,CAAC;IAED,kCAAkC;IAClC,GAAG,CAAC,GAAW;QACb,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACpC,CAAC;IAED,yDAAyD;IACzD,OAAO;QACL,OAAO,EAAE,GAAG,iBAAiB,EAAE,EAAE,CAAC;IACpC,CAAC;CACO,CAAC"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gFAAgF;AAChF,4EAA4E;AAC5E,gFAAgF;AAEhF,SAAS,iBAAiB;IACxB,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,sDAAsD;YACpD,2DAA2D;YAC3D,oEAAoE,CACvE,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,yDAAyD;IACzD,GAAG,CAAc,GAAW;QAC1B,OAAO,iBAAiB,EAAE,CAAC,GAAG,CAAkB,CAAC;IACnD,CAAC;IAED,8CAA8C;IAC9C,OAAO,CAAc,GAAW;QAC9B,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,kCAAkC,GAAG,KAAK;gBACxC,mEAAmE,CACtE,CAAC;QACJ,CAAC;QACD,OAAO,KAAU,CAAC;IACpB,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,GAAW,EAAE,KAAc;QAC7B,iBAAiB,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnC,CAAC;IAED,kCAAkC;IAClC,GAAG,CAAC,GAAW;QACb,OAAO,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACpC,CAAC;IAED,yDAAyD;IACzD,OAAO;QACL,OAAO,EAAE,GAAG,iBAAiB,EAAE,EAAE,CAAC;IACpC,CAAC;CACO,CAAC"}