deepline 0.1.12 → 0.1.19
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/README.md +14 -6
- package/dist/cli/index.js +1298 -711
- package/dist/cli/index.mjs +1294 -707
- package/dist/index.d.mts +199 -23
- package/dist/index.d.ts +199 -23
- package/dist/index.js +219 -13
- package/dist/index.mjs +219 -13
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +68 -12
- package/dist/repo/apps/play-runner-workers/src/entry.ts +241 -51
- package/dist/repo/sdk/src/client.ts +237 -0
- package/dist/repo/sdk/src/config.ts +125 -8
- package/dist/repo/sdk/src/http.ts +10 -2
- package/dist/repo/sdk/src/play.ts +19 -36
- package/dist/repo/sdk/src/plays/bundle-play-file.ts +22 -8
- package/dist/repo/sdk/src/plays/local-file-discovery.ts +207 -160
- package/dist/repo/sdk/src/types.ts +25 -0
- package/dist/repo/sdk/src/version.ts +2 -2
- package/dist/repo/shared_libs/play-runtime/tool-result.ts +237 -145
- package/dist/repo/shared_libs/plays/bundling/index.ts +206 -229
- package/dist/repo/shared_libs/plays/dataset.ts +28 -0
- package/package.json +5 -4
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/index.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/repo/apps/play-runner-workers/src/runtime/README.md +0 -21
- package/dist/repo/apps/play-runner-workers/src/runtime/batching.ts +0 -177
- package/dist/repo/apps/play-runner-workers/src/runtime/execution-plan.ts +0 -52
- package/dist/repo/apps/play-runner-workers/src/runtime/tool-batch.ts +0 -100
- package/dist/repo/sdk/src/cli/commands/auth.ts +0 -500
- package/dist/repo/sdk/src/cli/commands/billing.ts +0 -188
- package/dist/repo/sdk/src/cli/commands/csv.ts +0 -123
- package/dist/repo/sdk/src/cli/commands/db.ts +0 -119
- package/dist/repo/sdk/src/cli/commands/feedback.ts +0 -40
- package/dist/repo/sdk/src/cli/commands/org.ts +0 -117
- package/dist/repo/sdk/src/cli/commands/play.ts +0 -3441
- package/dist/repo/sdk/src/cli/commands/tools.ts +0 -687
- package/dist/repo/sdk/src/cli/dataset-stats.ts +0 -415
- package/dist/repo/sdk/src/cli/index.ts +0 -148
- package/dist/repo/sdk/src/cli/progress.ts +0 -149
- package/dist/repo/sdk/src/cli/skills-sync.ts +0 -141
- package/dist/repo/sdk/src/cli/trace.ts +0 -61
- package/dist/repo/sdk/src/cli/utils.ts +0 -145
- package/dist/repo/sdk/src/compat.ts +0 -77
- package/dist/repo/shared_libs/observability/node-tracing.ts +0 -129
- package/dist/repo/shared_libs/observability/tracing.ts +0 -98
- package/dist/repo/shared_libs/play-runtime/context.ts +0 -4242
- package/dist/repo/shared_libs/play-runtime/ctx-contract.ts +0 -250
- package/dist/repo/shared_libs/play-runtime/ctx-types.ts +0 -725
- package/dist/repo/shared_libs/play-runtime/dataset-id.ts +0 -10
- package/dist/repo/shared_libs/play-runtime/db-session-crypto.ts +0 -304
- package/dist/repo/shared_libs/play-runtime/db-session.ts +0 -462
- package/dist/repo/shared_libs/play-runtime/live-events.ts +0 -214
- package/dist/repo/shared_libs/play-runtime/live-state-contract.ts +0 -50
- package/dist/repo/shared_libs/play-runtime/map-execution-frame.ts +0 -114
- package/dist/repo/shared_libs/play-runtime/map-row-identity.ts +0 -158
- package/dist/repo/shared_libs/play-runtime/progress-emitter.ts +0 -172
- package/dist/repo/shared_libs/play-runtime/protocol.ts +0 -121
- package/dist/repo/shared_libs/play-runtime/public-play-contract.ts +0 -42
- package/dist/repo/shared_libs/play-runtime/result-normalization.ts +0 -33
- package/dist/repo/shared_libs/play-runtime/runtime-api.ts +0 -1873
- package/dist/repo/shared_libs/play-runtime/runtime-constraints.ts +0 -2
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +0 -201
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-pg.ts +0 -48
- package/dist/repo/shared_libs/play-runtime/runtime-pg-driver.ts +0 -84
- package/dist/repo/shared_libs/play-runtime/static-pipeline-types.ts +0 -147
- package/dist/repo/shared_libs/play-runtime/suspension.ts +0 -68
- package/dist/repo/shared_libs/play-runtime/tracing.ts +0 -31
- package/dist/repo/shared_libs/play-runtime/waterfall-replay.ts +0 -75
- package/dist/repo/shared_libs/play-runtime/worker-api-types.ts +0 -140
- package/dist/repo/shared_libs/plays/artifact-transport.ts +0 -14
- package/dist/repo/shared_libs/plays/artifact-types.ts +0 -49
- package/dist/repo/shared_libs/plays/compiler-manifest.ts +0 -186
- package/dist/repo/shared_libs/plays/definition.ts +0 -264
- package/dist/repo/shared_libs/plays/file-refs.ts +0 -11
- package/dist/repo/shared_libs/plays/rate-limit-scheduler.ts +0 -206
- package/dist/repo/shared_libs/plays/resolve-static-pipeline.ts +0 -164
- package/dist/repo/shared_libs/plays/runtime-validation.ts +0 -395
- package/dist/repo/shared_libs/temporal/constants.ts +0 -39
- package/dist/repo/shared_libs/temporal/preview-config.ts +0 -153
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `@neondatabase/serverless` Pool factory. Installed at boot by the
|
|
3
|
-
* workers_edge dynamic Worker harness. The serverless driver speaks the
|
|
4
|
-
* same Postgres wire protocol as `pg` but uses Neon's WebSocket proxy
|
|
5
|
-
* (or HTTP endpoint) so it works inside the workerd V8 isolate where raw
|
|
6
|
-
* TCP is unavailable.
|
|
7
|
-
*
|
|
8
|
-
* ## Lazy loading (the actual implementation)
|
|
9
|
-
*
|
|
10
|
-
* `@neondatabase/serverless` is ~143 KB minified — a non-trivial fraction
|
|
11
|
-
* of every per-graphHash play Worker bundle. The harness's
|
|
12
|
-
* `installNeonServerlessRuntimePoolDriver()` fires unconditionally at
|
|
13
|
-
* isolate startup, but the heavy module is loaded ON FIRST `pool.connect()`
|
|
14
|
-
* via dynamic `import('@neondatabase/serverless')`. Plays that never open
|
|
15
|
-
* a Postgres pool (csv-only, computation-only, tool-only plays) skip the
|
|
16
|
-
* import entirely, even though the driver registration ran at boot.
|
|
17
|
-
*
|
|
18
|
-
* Concretely:
|
|
19
|
-
* - Bundle still contains the dynamic-import path → `@neondatabase/serverless`
|
|
20
|
-
* is still in the per-play bundle (esbuild emits it as a deferred chunk
|
|
21
|
-
* in `format: 'esm'`, but workerd inlines all chunks for a Worker —
|
|
22
|
-
* so the bytes are still in the worker's compiled code).
|
|
23
|
-
* - V8 PARSE / COMPILE for those bytes is also deferred until the first
|
|
24
|
-
* `import()` call resolves; modern V8 does parse-on-demand for ESM
|
|
25
|
-
* dynamic imports. So plays that never connect skip the parse cost.
|
|
26
|
-
* - Plays that DO connect pay the import cost once per isolate, then
|
|
27
|
-
* reuse the cached module + pool for the rest of the run.
|
|
28
|
-
*
|
|
29
|
-
* If you change this file, double-check by:
|
|
30
|
-
* 1. Bundling a play that doesn't use `ctx.dataset` / postgres ops
|
|
31
|
-
* (e.g. tests/v2-plays/plays/03-tool-basic.play.ts).
|
|
32
|
-
* 2. Confirm the resulting bundle still references
|
|
33
|
-
* `@neondatabase/serverless` (the dynamic import path is preserved
|
|
34
|
-
* as a string), but no top-level `Pool` symbol is constructed.
|
|
35
|
-
* 3. Confirm that creating an actual pool via `createRuntimePool` in
|
|
36
|
-
* a test still resolves and returns a working client.
|
|
37
|
-
*
|
|
38
|
-
* Why we don't just `external: ['@neondatabase/serverless']` in
|
|
39
|
-
* bundle-play-file.ts:
|
|
40
|
-
* The `@neondatabase/serverless` package isn't provided by the
|
|
41
|
-
* workerd runtime — marking it external would crash the Worker on
|
|
42
|
-
* first import lookup. The lazy dynamic import is the right pattern:
|
|
43
|
-
* esbuild bundles the module, but its CODE STARTUP COST (parse +
|
|
44
|
-
* compile) is paid only when the import resolves.
|
|
45
|
-
*/
|
|
46
|
-
|
|
47
|
-
import {
|
|
48
|
-
registerRuntimePoolFactory,
|
|
49
|
-
type RuntimePool,
|
|
50
|
-
type RuntimePoolClient,
|
|
51
|
-
} from './runtime-pg-driver';
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Minimal local types for the Neon module's runtime surface.
|
|
55
|
-
*
|
|
56
|
-
* We INTENTIONALLY don't `import type { Pool, PoolClient } from
|
|
57
|
-
* '@neondatabase/serverless'` here — that would force tsc to read the
|
|
58
|
-
* package's full type tree on every typecheck, slowing the build, and
|
|
59
|
-
* the package's overloaded `connect()` resolves through types in a way
|
|
60
|
-
* that surfaces as `void` in some TS configurations.
|
|
61
|
-
*
|
|
62
|
-
* The minimal shape is just:
|
|
63
|
-
* - Pool ctor takes a config bag
|
|
64
|
-
* - Pool instance has connect() / end()
|
|
65
|
-
* - PoolClient instance has query() / release()
|
|
66
|
-
*
|
|
67
|
-
* If Neon ever changes this surface, the runtime cast will fail loudly
|
|
68
|
-
* the first time a play tries to use Postgres — which is exactly when
|
|
69
|
-
* we want to find out.
|
|
70
|
-
*/
|
|
71
|
-
interface NeonPoolClient {
|
|
72
|
-
query<R = Record<string, unknown>>(
|
|
73
|
-
text: string,
|
|
74
|
-
params?: unknown[],
|
|
75
|
-
): Promise<{ rows: R[] }>;
|
|
76
|
-
release(): void;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
interface NeonPoolInstance {
|
|
80
|
-
connect(): Promise<NeonPoolClient>;
|
|
81
|
-
end(): Promise<void>;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface NeonPoolConfig {
|
|
85
|
-
connectionString: string;
|
|
86
|
-
max?: number;
|
|
87
|
-
idleTimeoutMillis?: number;
|
|
88
|
-
connectionTimeoutMillis?: number;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
interface NeonModule {
|
|
92
|
-
Pool: new (config: NeonPoolConfig) => NeonPoolInstance;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Cached promise of the loaded Neon module. Once the first connect()
|
|
97
|
-
* resolves, every subsequent connect on the same isolate hits this
|
|
98
|
-
* cache instead of re-importing.
|
|
99
|
-
*
|
|
100
|
-
* We cache the PROMISE rather than the resolved module so concurrent
|
|
101
|
-
* first-connect calls coalesce onto a single import — V8's module
|
|
102
|
-
* loader is already idempotent for the same specifier, but caching at
|
|
103
|
-
* this layer makes the contract obvious to readers.
|
|
104
|
-
*/
|
|
105
|
-
let neonModulePromise: Promise<NeonModule> | null = null;
|
|
106
|
-
function loadNeonModule(): Promise<NeonModule> {
|
|
107
|
-
if (!neonModulePromise) {
|
|
108
|
-
neonModulePromise = import('@neondatabase/serverless') as unknown as Promise<NeonModule>;
|
|
109
|
-
}
|
|
110
|
-
return neonModulePromise;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function wrapNeonClient(client: NeonPoolClient): RuntimePoolClient {
|
|
114
|
-
return {
|
|
115
|
-
query: <R extends Record<string, unknown> = Record<string, unknown>>(
|
|
116
|
-
text: string,
|
|
117
|
-
params?: unknown[],
|
|
118
|
-
) =>
|
|
119
|
-
(client.query as unknown as (
|
|
120
|
-
t: string,
|
|
121
|
-
p?: unknown[],
|
|
122
|
-
) => Promise<{ rows: R[] }>)(text, params),
|
|
123
|
-
release: () => {
|
|
124
|
-
client.release();
|
|
125
|
-
},
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Wrap a Neon `Pool` instance as our internal `RuntimePool` shape.
|
|
131
|
-
* `connect()` and `end()` are async on both sides, so this is a thin
|
|
132
|
-
* adapter — no logic, just type marshaling.
|
|
133
|
-
*/
|
|
134
|
-
function wrapNeonPool(pool: NeonPoolInstance): RuntimePool {
|
|
135
|
-
return {
|
|
136
|
-
connect: async () =>
|
|
137
|
-
wrapNeonClient((await pool.connect()) as unknown as NeonPoolClient),
|
|
138
|
-
end: async () => {
|
|
139
|
-
await pool.end();
|
|
140
|
-
},
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Install the Neon-backed pool factory. Called once at Worker isolate
|
|
146
|
-
* boot — `registerRuntimePoolFactory` is idempotent and throws if a
|
|
147
|
-
* different factory was already registered (build-config bug).
|
|
148
|
-
*
|
|
149
|
-
* The factory itself is SYNCHRONOUS (returns a `RuntimePool`) but the
|
|
150
|
-
* underlying Neon Pool is created LAZILY: we capture the connection
|
|
151
|
-
* config in a closure and instantiate the real `Pool` on first
|
|
152
|
-
* `connect()`. Until then, no `@neondatabase/serverless` runtime code
|
|
153
|
-
* runs in the isolate — V8 doesn't parse the dynamic-imported chunk
|
|
154
|
-
* until the import() resolves.
|
|
155
|
-
*/
|
|
156
|
-
export function installNeonServerlessRuntimePoolDriver(): void {
|
|
157
|
-
registerRuntimePoolFactory((input) => {
|
|
158
|
-
// Captured lazily so a Pool is only constructed if the play actually
|
|
159
|
-
// connects. Most plays that don't touch Postgres directly never even
|
|
160
|
-
// reach this branch — the factory is registered but never invoked.
|
|
161
|
-
let lazyPool: NeonPoolInstance | null = null;
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Resolve the lazy Pool, creating it on first call.
|
|
165
|
-
*
|
|
166
|
-
* Race safety: workerd executes within a single JS event loop, so
|
|
167
|
-
* two concurrent `connect()` calls on the SAME wrapper run their
|
|
168
|
-
* "lazyPool == null" checks in turn — the first creates the Pool,
|
|
169
|
-
* the second sees it. No locking needed.
|
|
170
|
-
*
|
|
171
|
-
* If pool creation fails (e.g. DNS, bad connection string), the
|
|
172
|
-
* error propagates out of connect() to the caller. We don't cache
|
|
173
|
-
* a failed pool so retries can succeed on transient failures.
|
|
174
|
-
*/
|
|
175
|
-
async function ensurePool(): Promise<NeonPoolInstance> {
|
|
176
|
-
if (lazyPool) return lazyPool;
|
|
177
|
-
const neon = await loadNeonModule();
|
|
178
|
-
const pool = new neon.Pool({
|
|
179
|
-
connectionString: input.connectionString,
|
|
180
|
-
max: input.maxConnections ?? 4,
|
|
181
|
-
idleTimeoutMillis: input.idleTimeoutMs ?? 15_000,
|
|
182
|
-
connectionTimeoutMillis: input.connectTimeoutMs ?? 10_000,
|
|
183
|
-
});
|
|
184
|
-
lazyPool = pool;
|
|
185
|
-
return pool;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return {
|
|
189
|
-
connect: async () => {
|
|
190
|
-
const pool = await ensurePool();
|
|
191
|
-
return wrapNeonClient(await pool.connect());
|
|
192
|
-
},
|
|
193
|
-
end: async () => {
|
|
194
|
-
if (lazyPool) {
|
|
195
|
-
await lazyPool.end();
|
|
196
|
-
lazyPool = null;
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
});
|
|
201
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* pg-backed Pool factory. Installed at boot by the Node-runtime
|
|
3
|
-
* play-runner (Daytona/local). NOT used by the workers_edge harness — pg's
|
|
4
|
-
* raw TCP socket usage is banned in workerd.
|
|
5
|
-
*/
|
|
6
|
-
import { Pool, type PoolClient } from 'pg';
|
|
7
|
-
import {
|
|
8
|
-
registerRuntimePoolFactory,
|
|
9
|
-
type RuntimePool,
|
|
10
|
-
type RuntimePoolClient,
|
|
11
|
-
} from './runtime-pg-driver';
|
|
12
|
-
|
|
13
|
-
function wrapPgClient(client: PoolClient): RuntimePoolClient {
|
|
14
|
-
return {
|
|
15
|
-
query: <R extends Record<string, unknown> = Record<string, unknown>>(
|
|
16
|
-
text: string,
|
|
17
|
-
params?: unknown[],
|
|
18
|
-
) =>
|
|
19
|
-
(client.query as unknown as (
|
|
20
|
-
t: string,
|
|
21
|
-
p?: unknown[],
|
|
22
|
-
) => Promise<{ rows: R[] }>)(text, params).then((result) => ({
|
|
23
|
-
rows: result.rows,
|
|
24
|
-
})),
|
|
25
|
-
release: () => {
|
|
26
|
-
client.release();
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function wrapPgPool(pool: Pool): RuntimePool {
|
|
32
|
-
return {
|
|
33
|
-
connect: async () => wrapPgClient(await pool.connect()),
|
|
34
|
-
end: () => pool.end(),
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function installPgRuntimePoolDriver(): void {
|
|
39
|
-
registerRuntimePoolFactory((input) => {
|
|
40
|
-
const pool = new Pool({
|
|
41
|
-
connectionString: input.connectionString,
|
|
42
|
-
max: input.maxConnections ?? 4,
|
|
43
|
-
idleTimeoutMillis: input.idleTimeoutMs ?? 15_000,
|
|
44
|
-
connectionTimeoutMillis: input.connectTimeoutMs ?? 10_000,
|
|
45
|
-
});
|
|
46
|
-
return wrapPgPool(pool);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Driver-agnostic Postgres pool/client surface used by the runtime data plane.
|
|
3
|
-
*
|
|
4
|
-
* The runtime data plane (`runtime-api.ts` direct-Neon writes) needs to run in
|
|
5
|
-
* two very different environments:
|
|
6
|
-
*
|
|
7
|
-
* - Node (Daytona/local play-runner) — uses the `pg` library, raw TCP to Neon.
|
|
8
|
-
* - Cloudflare Workers (workers_edge harness) — `pg` cannot bundle (raw TCP
|
|
9
|
-
* is banned at workerd boundary), so we use `@neondatabase/serverless`
|
|
10
|
-
* which speaks the same Postgres wire protocol over a WebSocket proxy.
|
|
11
|
-
*
|
|
12
|
-
* Rather than `if-platform` branches inside runtime-api.ts, each runtime
|
|
13
|
-
* registers its driver once at boot and the rest of the code uses the
|
|
14
|
-
* abstract `RuntimePool` / `RuntimePoolClient` types. Both `pg` and
|
|
15
|
-
* `@neondatabase/serverless` already expose the relevant subset of the
|
|
16
|
-
* `pg` API surface (`pool.connect()` → `client.query() / .release()`), so
|
|
17
|
-
* the wrappers are thin.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
export interface RuntimePoolClient {
|
|
21
|
-
query<R extends Record<string, unknown> = Record<string, unknown>>(
|
|
22
|
-
text: string,
|
|
23
|
-
params?: unknown[],
|
|
24
|
-
): Promise<{ rows: R[] }>;
|
|
25
|
-
release(): void;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface RuntimePool {
|
|
29
|
-
connect(): Promise<RuntimePoolClient>;
|
|
30
|
-
end(): Promise<void>;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export type RuntimePoolFactory = (input: {
|
|
34
|
-
connectionString: string;
|
|
35
|
-
/** Soft cap on simultaneous connections; defaults to 4. */
|
|
36
|
-
maxConnections?: number;
|
|
37
|
-
/** Idle timeout in ms before pool tears down a connection; defaults to 15000. */
|
|
38
|
-
idleTimeoutMs?: number;
|
|
39
|
-
/** Connect timeout in ms; defaults to 10000. */
|
|
40
|
-
connectTimeoutMs?: number;
|
|
41
|
-
}) => RuntimePool;
|
|
42
|
-
|
|
43
|
-
let registeredFactory: RuntimePoolFactory | null = null;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Install a Pool factory at process / Worker boot. Idempotent — calling twice
|
|
47
|
-
* with different factories will throw to prevent silent driver swaps that
|
|
48
|
-
* would otherwise drop in-flight pooled connections.
|
|
49
|
-
*/
|
|
50
|
-
export function registerRuntimePoolFactory(factory: RuntimePoolFactory): void {
|
|
51
|
-
if (registeredFactory && registeredFactory !== factory) {
|
|
52
|
-
throw new Error(
|
|
53
|
-
'A different runtime Postgres pool factory is already registered. ' +
|
|
54
|
-
'This is a build-config bug — only one driver should be installed per process.',
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
registeredFactory = factory;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function isRuntimePoolFactoryRegistered(): boolean {
|
|
61
|
-
return registeredFactory !== null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function createRuntimePool(input: {
|
|
65
|
-
connectionString: string;
|
|
66
|
-
maxConnections?: number;
|
|
67
|
-
idleTimeoutMs?: number;
|
|
68
|
-
connectTimeoutMs?: number;
|
|
69
|
-
}): RuntimePool {
|
|
70
|
-
if (!registeredFactory) {
|
|
71
|
-
throw new Error(
|
|
72
|
-
'No runtime Postgres pool factory registered. Call ' +
|
|
73
|
-
'installPgRuntimePoolDriver() (Node) or ' +
|
|
74
|
-
'installNeonServerlessRuntimePoolDriver() (Workers) at boot before ' +
|
|
75
|
-
'using runtime-api Postgres helpers.',
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
return registeredFactory(input);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/** Test seam — clears the registered factory so a test can swap drivers. */
|
|
82
|
-
export function __resetRuntimePoolFactoryForTests(): void {
|
|
83
|
-
registeredFactory = null;
|
|
84
|
-
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
export interface PlayStaticPipeline {
|
|
2
|
-
tableNamespace?: string;
|
|
3
|
-
inputFields?: string[];
|
|
4
|
-
csvArg?: string;
|
|
5
|
-
hasInlineData?: boolean;
|
|
6
|
-
csvDescription?: string;
|
|
7
|
-
mapDescription?: string;
|
|
8
|
-
fields: string[];
|
|
9
|
-
stages?: PlayStaticSubstep[];
|
|
10
|
-
substeps: PlayStaticSubstep[];
|
|
11
|
-
sheetContract?: PlaySheetContract | null;
|
|
12
|
-
sheetContractErrors?: string[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type PlaySheetColumnSource =
|
|
16
|
-
| 'input'
|
|
17
|
-
| 'mapField'
|
|
18
|
-
| 'waterfallStep'
|
|
19
|
-
| 'childPlayColumn';
|
|
20
|
-
|
|
21
|
-
export interface PlaySheetColumnContract {
|
|
22
|
-
id: string;
|
|
23
|
-
sqlName: string;
|
|
24
|
-
source: PlaySheetColumnSource;
|
|
25
|
-
field?: string;
|
|
26
|
-
parentField?: string;
|
|
27
|
-
playId?: string;
|
|
28
|
-
waterfallId?: string;
|
|
29
|
-
outputField?: string;
|
|
30
|
-
outputSqlName?: string;
|
|
31
|
-
stepId?: string;
|
|
32
|
-
toolId?: string;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface PlaySheetContract {
|
|
36
|
-
tableNamespace: string;
|
|
37
|
-
columns: PlaySheetColumnContract[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface PlayStaticSourceRange {
|
|
41
|
-
sourcePath?: string;
|
|
42
|
-
startLine: number;
|
|
43
|
-
endLine: number;
|
|
44
|
-
startColumn: number;
|
|
45
|
-
endColumn: number;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
type PlayStaticSubstepMetadata = {
|
|
49
|
-
conditional?: boolean;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
export type PlayStaticSubstep = PlayStaticSubstepMetadata &
|
|
53
|
-
(
|
|
54
|
-
| {
|
|
55
|
-
type: 'csv';
|
|
56
|
-
field: string;
|
|
57
|
-
path?: string;
|
|
58
|
-
description?: string;
|
|
59
|
-
sourceRange?: PlayStaticSourceRange;
|
|
60
|
-
callDepth?: number;
|
|
61
|
-
callPath?: string[];
|
|
62
|
-
}
|
|
63
|
-
| {
|
|
64
|
-
type: 'map';
|
|
65
|
-
field: string;
|
|
66
|
-
name?: string;
|
|
67
|
-
tableNamespace?: string;
|
|
68
|
-
inputFields?: string[];
|
|
69
|
-
outputFields?: string[];
|
|
70
|
-
waterfallIds?: string[];
|
|
71
|
-
sheetContract?: PlaySheetContract | null;
|
|
72
|
-
description?: string;
|
|
73
|
-
sourceRange?: PlayStaticSourceRange;
|
|
74
|
-
callDepth?: number;
|
|
75
|
-
callPath?: string[];
|
|
76
|
-
}
|
|
77
|
-
| {
|
|
78
|
-
type: 'tool';
|
|
79
|
-
toolId: string;
|
|
80
|
-
field: string;
|
|
81
|
-
description?: string;
|
|
82
|
-
inLoop?: boolean;
|
|
83
|
-
isEventWait?: boolean;
|
|
84
|
-
sourceRange?: PlayStaticSourceRange;
|
|
85
|
-
callDepth?: number;
|
|
86
|
-
callPath?: string[];
|
|
87
|
-
}
|
|
88
|
-
| {
|
|
89
|
-
type: 'waterfall';
|
|
90
|
-
tool?: string;
|
|
91
|
-
field: string;
|
|
92
|
-
inLoop?: boolean;
|
|
93
|
-
id?: string;
|
|
94
|
-
output?: string;
|
|
95
|
-
minResults?: number;
|
|
96
|
-
sourceText?: string;
|
|
97
|
-
steps?: Array<{
|
|
98
|
-
id: string;
|
|
99
|
-
kind?: 'tool' | 'code';
|
|
100
|
-
toolId?: string;
|
|
101
|
-
paramsSource?: string;
|
|
102
|
-
}>;
|
|
103
|
-
description?: string;
|
|
104
|
-
sourceRange?: PlayStaticSourceRange;
|
|
105
|
-
callDepth?: number;
|
|
106
|
-
callPath?: string[];
|
|
107
|
-
}
|
|
108
|
-
| {
|
|
109
|
-
type: 'step_suite';
|
|
110
|
-
field: string;
|
|
111
|
-
steps: PlayStaticSubstep[];
|
|
112
|
-
returnSource?: string;
|
|
113
|
-
description?: string;
|
|
114
|
-
sourceRange?: PlayStaticSourceRange;
|
|
115
|
-
callDepth?: number;
|
|
116
|
-
callPath?: string[];
|
|
117
|
-
}
|
|
118
|
-
| {
|
|
119
|
-
type: 'play_call';
|
|
120
|
-
playId: string;
|
|
121
|
-
field: string;
|
|
122
|
-
inLoop?: boolean;
|
|
123
|
-
pipeline?: PlayStaticPipeline | null;
|
|
124
|
-
cycleDetected?: boolean;
|
|
125
|
-
resolutionError?: string;
|
|
126
|
-
description?: string;
|
|
127
|
-
sourceRange?: PlayStaticSourceRange;
|
|
128
|
-
callDepth?: number;
|
|
129
|
-
callPath?: string[];
|
|
130
|
-
}
|
|
131
|
-
| {
|
|
132
|
-
type: 'run_javascript';
|
|
133
|
-
alias: string;
|
|
134
|
-
description?: string;
|
|
135
|
-
sourceRange?: PlayStaticSourceRange;
|
|
136
|
-
callDepth?: number;
|
|
137
|
-
callPath?: string[];
|
|
138
|
-
}
|
|
139
|
-
| {
|
|
140
|
-
type: 'code';
|
|
141
|
-
field: string;
|
|
142
|
-
description?: string;
|
|
143
|
-
sourceRange?: PlayStaticSourceRange;
|
|
144
|
-
callDepth?: number;
|
|
145
|
-
callPath?: string[];
|
|
146
|
-
}
|
|
147
|
-
);
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
export type PlayExecutionSuspension =
|
|
2
|
-
| {
|
|
3
|
-
kind: 'sleep';
|
|
4
|
-
boundaryId: string;
|
|
5
|
-
delayMs: number;
|
|
6
|
-
}
|
|
7
|
-
| {
|
|
8
|
-
kind: 'integration_event';
|
|
9
|
-
boundaryId: string;
|
|
10
|
-
eventKey: string;
|
|
11
|
-
timeoutMs: number;
|
|
12
|
-
}
|
|
13
|
-
| {
|
|
14
|
-
kind: 'integration_event_batch';
|
|
15
|
-
boundaries: Array<{
|
|
16
|
-
boundaryId: string;
|
|
17
|
-
eventKey: string;
|
|
18
|
-
timeoutMs: number;
|
|
19
|
-
}>;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export class PlayExecutionSuspendedError extends Error {
|
|
23
|
-
readonly suspension: PlayExecutionSuspension;
|
|
24
|
-
|
|
25
|
-
constructor(suspension: PlayExecutionSuspension) {
|
|
26
|
-
super(
|
|
27
|
-
suspension.kind === 'sleep'
|
|
28
|
-
? `Play execution suspended for durable sleep (${suspension.delayMs}ms).`
|
|
29
|
-
: suspension.kind === 'integration_event_batch'
|
|
30
|
-
? `Play execution suspended waiting for ${suspension.boundaries.length} integration events.`
|
|
31
|
-
: `Play execution suspended waiting for integration event ${JSON.stringify(suspension.eventKey)}.`,
|
|
32
|
-
);
|
|
33
|
-
this.name = 'PlayExecutionSuspendedError';
|
|
34
|
-
this.suspension = suspension;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export class PlayRowExecutionSuspendedError extends Error {
|
|
39
|
-
readonly boundary: {
|
|
40
|
-
boundaryId: string;
|
|
41
|
-
eventKey: string;
|
|
42
|
-
timeoutMs: number;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
constructor(boundary: {
|
|
46
|
-
boundaryId: string;
|
|
47
|
-
eventKey: string;
|
|
48
|
-
timeoutMs: number;
|
|
49
|
-
}) {
|
|
50
|
-
super(
|
|
51
|
-
`Play row execution suspended waiting for integration event ${JSON.stringify(boundary.eventKey)}.`,
|
|
52
|
-
);
|
|
53
|
-
this.name = 'PlayRowExecutionSuspendedError';
|
|
54
|
-
this.boundary = boundary;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function isPlayRowExecutionSuspendedError(
|
|
59
|
-
value: unknown,
|
|
60
|
-
): value is PlayRowExecutionSuspendedError {
|
|
61
|
-
return value instanceof PlayRowExecutionSuspendedError;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export function isPlayExecutionSuspendedError(
|
|
65
|
-
value: unknown,
|
|
66
|
-
): value is PlayExecutionSuspendedError {
|
|
67
|
-
return value instanceof PlayExecutionSuspendedError;
|
|
68
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
type SpanLike = {
|
|
2
|
-
setAttribute: (key: string, value: unknown) => void;
|
|
3
|
-
};
|
|
4
|
-
|
|
5
|
-
type SpanOptions = {
|
|
6
|
-
tracer?: string;
|
|
7
|
-
attributes?: Record<string, unknown>;
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function setSpanAttributes(
|
|
11
|
-
span: SpanLike | null | undefined,
|
|
12
|
-
attributes: Record<string, unknown>,
|
|
13
|
-
): void {
|
|
14
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
15
|
-
span?.setAttribute?.(key, value);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export async function withActiveSpan<T>(
|
|
20
|
-
_name: string,
|
|
21
|
-
options: SpanOptions,
|
|
22
|
-
fn: (span: SpanLike) => Promise<T>,
|
|
23
|
-
): Promise<T> {
|
|
24
|
-
const attributes = new Map<string, unknown>(Object.entries(options.attributes ?? {}));
|
|
25
|
-
const span: SpanLike = {
|
|
26
|
-
setAttribute(key, value) {
|
|
27
|
-
attributes.set(key, value);
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
return await fn(span);
|
|
31
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { BatchResult, PlayCheckpoint, WaterfallRequest } from './ctx-types';
|
|
2
|
-
|
|
3
|
-
export class WaterfallReplayStore {
|
|
4
|
-
constructor(private readonly checkpoint: PlayCheckpoint) {}
|
|
5
|
-
|
|
6
|
-
checkpointKey(input: { rowId: number; rowKey?: string | null }): string {
|
|
7
|
-
return input.rowKey?.trim() || String(input.rowId);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
getResolved(
|
|
11
|
-
queueKey: string,
|
|
12
|
-
input: {
|
|
13
|
-
rowId: number;
|
|
14
|
-
rowKey?: string | null;
|
|
15
|
-
},
|
|
16
|
-
): { found: boolean; value: unknown } {
|
|
17
|
-
const resolved = this.checkpoint.resolvedWaterfalls[queueKey];
|
|
18
|
-
if (!resolved) {
|
|
19
|
-
return { found: false, value: undefined };
|
|
20
|
-
}
|
|
21
|
-
const durableKey = this.checkpointKey(input);
|
|
22
|
-
if (Object.prototype.hasOwnProperty.call(resolved, durableKey)) {
|
|
23
|
-
return { found: true, value: resolved[durableKey] };
|
|
24
|
-
}
|
|
25
|
-
return { found: false, value: undefined };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
setResolved(
|
|
29
|
-
queueKey: string,
|
|
30
|
-
input: {
|
|
31
|
-
rowId: number;
|
|
32
|
-
rowKey?: string | null;
|
|
33
|
-
},
|
|
34
|
-
value: unknown,
|
|
35
|
-
): void {
|
|
36
|
-
this.checkpoint.resolvedWaterfalls[queueKey] ??= {};
|
|
37
|
-
this.checkpoint.resolvedWaterfalls[queueKey]![this.checkpointKey(input)] =
|
|
38
|
-
value;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
readProviderBatch(input: {
|
|
42
|
-
batchKey: string;
|
|
43
|
-
requests: readonly WaterfallRequest[];
|
|
44
|
-
}): Array<{ request: WaterfallRequest; result: unknown | null }> | null {
|
|
45
|
-
const cached = this.checkpoint.completedBatches[input.batchKey];
|
|
46
|
-
if (!cached) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const recovered = cached.flatMap((entry) => {
|
|
50
|
-
const request = input.requests.find((candidate) =>
|
|
51
|
-
entry.rowKey
|
|
52
|
-
? candidate.rowKey === entry.rowKey
|
|
53
|
-
: candidate.rowId === entry.rowId,
|
|
54
|
-
);
|
|
55
|
-
return request ? [{ request, result: entry.result }] : [];
|
|
56
|
-
});
|
|
57
|
-
return recovered.length > 0 ? recovered : null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
writeProviderBatch(
|
|
61
|
-
batchKey: string,
|
|
62
|
-
results: ReadonlyArray<{
|
|
63
|
-
request: WaterfallRequest;
|
|
64
|
-
result: unknown | null;
|
|
65
|
-
}>,
|
|
66
|
-
): void {
|
|
67
|
-
this.checkpoint.completedBatches[batchKey] = results.map(
|
|
68
|
-
(entry): BatchResult => ({
|
|
69
|
-
rowId: entry.request.rowId,
|
|
70
|
-
rowKey: entry.request.rowKey ?? null,
|
|
71
|
-
result: entry.result,
|
|
72
|
-
}),
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
}
|