@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.
- package/dist/configure/http.d.ts +25 -0
- package/dist/configure/http.d.ts.map +1 -0
- package/dist/configure/http.js +88 -0
- package/dist/configure/http.js.map +1 -0
- package/dist/configure/index.d.ts +78 -0
- package/dist/configure/index.d.ts.map +1 -0
- package/dist/configure/index.js +78 -0
- package/dist/configure/index.js.map +1 -0
- package/dist/configure/plugin.d.ts +23 -0
- package/dist/configure/plugin.d.ts.map +1 -0
- package/dist/configure/plugin.js +81 -0
- package/dist/configure/plugin.js.map +1 -0
- package/dist/configure/runtime.d.ts +24 -0
- package/dist/configure/runtime.d.ts.map +1 -0
- package/dist/configure/runtime.js +45 -0
- package/dist/configure/runtime.js.map +1 -0
- package/dist/configure/template.d.ts +22 -0
- package/dist/configure/template.d.ts.map +1 -0
- package/dist/configure/template.js +34 -0
- package/dist/configure/template.js.map +1 -0
- package/dist/configure/vars.d.ts +20 -0
- package/dist/configure/vars.d.ts.map +1 -0
- package/dist/configure/vars.js +48 -0
- package/dist/configure/vars.js.map +1 -0
- package/dist/configure.d.ts +2 -150
- package/dist/configure.d.ts.map +1 -1
- package/dist/configure.js +2 -562
- package/dist/configure.js.map +1 -1
- package/dist/contract-artifacts.d.ts +268 -0
- package/dist/contract-artifacts.d.ts.map +1 -0
- package/dist/contract-artifacts.js +402 -0
- package/dist/contract-artifacts.js.map +1 -0
- package/dist/contract-core.d.ts +33 -1
- package/dist/contract-core.d.ts.map +1 -1
- package/dist/contract-core.js +51 -2
- package/dist/contract-core.js.map +1 -1
- package/dist/contract-http/adapter.d.ts.map +1 -1
- package/dist/contract-http/adapter.js +22 -7
- package/dist/contract-http/adapter.js.map +1 -1
- package/dist/contract-http/factory.d.ts.map +1 -1
- package/dist/contract-http/factory.js +13 -14
- package/dist/contract-http/factory.js.map +1 -1
- package/dist/contract-http/index.d.ts +4 -3
- package/dist/contract-http/index.d.ts.map +1 -1
- package/dist/contract-http/index.js +4 -3
- package/dist/contract-http/index.js.map +1 -1
- package/dist/contract-http/openapi.d.ts +56 -7
- package/dist/contract-http/openapi.d.ts.map +1 -1
- package/dist/contract-http/openapi.js +371 -21
- package/dist/contract-http/openapi.js.map +1 -1
- package/dist/contract-http/types.d.ts +2 -13
- package/dist/contract-http/types.d.ts.map +1 -1
- package/dist/contract-types.d.ts +59 -10
- package/dist/contract-types.d.ts.map +1 -1
- package/dist/expect.d.ts +13 -0
- package/dist/expect.d.ts.map +1 -1
- package/dist/expect.js +18 -0
- package/dist/expect.js.map +1 -1
- package/dist/index.d.ts +61 -518
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -835
- package/dist/index.js.map +1 -1
- package/dist/install-plugin.d.ts +94 -0
- package/dist/install-plugin.d.ts.map +1 -0
- package/dist/install-plugin.js +222 -0
- package/dist/install-plugin.js.map +1 -0
- package/dist/internal.d.ts +2 -0
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +6 -0
- package/dist/internal.js.map +1 -1
- package/dist/plugin.d.ts +45 -34
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +47 -34
- package/dist/plugin.js.map +1 -1
- package/dist/runtime-carrier.d.ts +142 -0
- package/dist/runtime-carrier.d.ts.map +1 -0
- package/dist/runtime-carrier.js +148 -0
- package/dist/runtime-carrier.js.map +1 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +2 -1
- package/dist/session.js.map +1 -1
- package/dist/test/builder.d.ts +249 -0
- package/dist/test/builder.d.ts.map +1 -0
- package/dist/test/builder.js +265 -0
- package/dist/test/builder.js.map +1 -0
- package/dist/test/each-builder.d.ts +244 -0
- package/dist/test/each-builder.d.ts.map +1 -0
- package/dist/test/each-builder.js +268 -0
- package/dist/test/each-builder.js.map +1 -0
- package/dist/test/extend.d.ts +59 -0
- package/dist/test/extend.d.ts.map +1 -0
- package/dist/test/extend.js +111 -0
- package/dist/test/extend.js.map +1 -0
- package/dist/test/utils.d.ts +39 -0
- package/dist/test/utils.d.ts.map +1 -0
- package/dist/test/utils.js +91 -0
- package/dist/test/utils.js.map +1 -0
- package/dist/types.d.ts +89 -111
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/contract-http/markdown.d.ts +0 -10
- package/dist/contract-http/markdown.d.ts.map +0 -1
- package/dist/contract-http/markdown.js +0 -21
- package/dist/contract-http/markdown.js.map +0 -1
package/dist/plugin.js
CHANGED
|
@@ -1,57 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Plugin
|
|
2
|
+
* Plugin authoring helpers.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
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
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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
|
-
*
|
|
24
|
+
* Declare a lazy client factory.
|
|
24
25
|
*
|
|
25
|
-
* The factory function receives a `GlubeanRuntime`
|
|
26
|
-
*
|
|
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
|
-
*
|
|
30
|
-
*
|
|
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
|
|
36
|
+
* @example Simple client
|
|
33
37
|
* ```ts
|
|
34
|
-
* export const
|
|
35
|
-
*
|
|
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
|
-
*
|
|
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
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
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(
|
|
55
|
-
return
|
|
67
|
+
export function definePlugin(manifest) {
|
|
68
|
+
return manifest;
|
|
56
69
|
}
|
|
57
70
|
//# sourceMappingURL=plugin.js.map
|
package/dist/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA
|
|
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"}
|
package/dist/session.d.ts.map
CHANGED
|
@@ -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;
|
|
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 =
|
|
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? " +
|
package/dist/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"
|
|
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"}
|