deepline 0.2.53 → 0.2.55
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/bundling-sources/sdk/src/client.ts +17 -1
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +43 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +30 -1
- package/dist/bundling-sources/shared_libs/play-runtime/cell-provenance.ts +231 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1094 -128
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +178 -9
- package/dist/bundling-sources/shared_libs/play-runtime/docflow-node-io.ts +634 -0
- package/dist/bundling-sources/shared_libs/play-runtime/docflow-observation.ts +64 -0
- package/dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +18 -0
- package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +33 -0
- package/dist/bundling-sources/shared_libs/play-runtime/log-provenance.ts +251 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-node-scope.ts +160 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +27 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +43 -5
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +12 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +26 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +6 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +83 -0
- package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +49 -1
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +375 -29
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +636 -0
- package/dist/bundling-sources/shared_libs/plays/docflow-binding.ts +598 -0
- package/dist/bundling-sources/shared_libs/plays/docflow.ts +1645 -0
- package/dist/bundling-sources/shared_libs/plays/play-exports.ts +202 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +16 -1
- package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +48 -0
- package/dist/cli/index.js +994 -312
- package/dist/cli/index.mjs +994 -312
- package/dist/{compiler-manifest-Cj3--4ZJ.d.mts → compiler-manifest-Bl8kmLx9.d.mts} +118 -0
- package/dist/{compiler-manifest-Cj3--4ZJ.d.ts → compiler-manifest-Bl8kmLx9.d.ts} +118 -0
- package/dist/index.d.mts +47 -2
- package/dist/index.d.ts +47 -2
- package/dist/index.js +419 -59
- package/dist/index.mjs +419 -59
- package/dist/install-integrity.json +12 -2
- package/dist/plays/bundle-play-file.d.mts +2 -2
- package/dist/plays/bundle-play-file.d.ts +2 -2
- package/dist/plays/bundle-play-file.mjs +1361 -45
- package/package.json +1 -1
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which plays a source file exports, esbuild-free.
|
|
3
|
+
*
|
|
4
|
+
* A `.play.ts` file may export more than one play — the shipped prebuilts pair
|
|
5
|
+
* `export const scalar` with `export const batch` and end `export default
|
|
6
|
+
* scalar`. Two callers need that list and neither can reach esbuild:
|
|
7
|
+
* `plays check` (which must check every exported play, not only the default)
|
|
8
|
+
* and the docflow parser (which must decide which `@mermaid` block belongs to
|
|
9
|
+
* which export). The bundler owns the same knowledge behind its esbuild
|
|
10
|
+
* fallback parse; this is the acorn-only subset both can share.
|
|
11
|
+
*
|
|
12
|
+
* Abstains (returns `null`) rather than guessing: source acorn cannot parse, or
|
|
13
|
+
* a file with no recognizable `definePlay` export, leaves the caller on its
|
|
14
|
+
* existing default-export behaviour.
|
|
15
|
+
*/
|
|
16
|
+
import {
|
|
17
|
+
astArray,
|
|
18
|
+
isAstNode,
|
|
19
|
+
parsePlaySourceForAnalysis,
|
|
20
|
+
type AstNode,
|
|
21
|
+
} from './ts-ast';
|
|
22
|
+
|
|
23
|
+
/** The export name the runtime, the registry and the CLI all use for a file's
|
|
24
|
+
* default play. Aliases resolve to it, never the other way round. */
|
|
25
|
+
export const PLAY_DEFAULT_EXPORT = 'default';
|
|
26
|
+
|
|
27
|
+
export type PlayFileExport = {
|
|
28
|
+
/**
|
|
29
|
+
* The canonical name this play is addressed by. `default` wins whenever the
|
|
30
|
+
* play is the file's default export, even when the same value also has a
|
|
31
|
+
* named export — `export const scalar = definePlay(…); export default scalar`
|
|
32
|
+
* is ONE play, canonically `default`.
|
|
33
|
+
*/
|
|
34
|
+
name: string;
|
|
35
|
+
/** Other export names that resolve to the same `definePlay` call. */
|
|
36
|
+
aliases: string[];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function getIdentifierName(node: unknown): string | null {
|
|
40
|
+
return isAstNode(node) && node.type === 'Identifier'
|
|
41
|
+
? typeof node.name === 'string'
|
|
42
|
+
? node.name
|
|
43
|
+
: null
|
|
44
|
+
: null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function unwrapStaticExpression(node: AstNode | null): AstNode | null {
|
|
48
|
+
let current = node;
|
|
49
|
+
while (
|
|
50
|
+
current &&
|
|
51
|
+
(current.type === 'TSAsExpression' ||
|
|
52
|
+
current.type === 'TSSatisfiesExpression' ||
|
|
53
|
+
current.type === 'TSTypeAssertion' ||
|
|
54
|
+
current.type === 'TSNonNullExpression' ||
|
|
55
|
+
current.type === 'ParenthesizedExpression')
|
|
56
|
+
) {
|
|
57
|
+
current = isAstNode(current.expression) ? current.expression : null;
|
|
58
|
+
}
|
|
59
|
+
return current;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** `definePlay(…)` / `defineWorkflow(…)`, bare or as a member call. Mirrors the
|
|
63
|
+
* bundler's recognizer so both agree on what counts as a play. */
|
|
64
|
+
export function isDefinePlayCall(node: AstNode | null): boolean {
|
|
65
|
+
const expression = unwrapStaticExpression(node);
|
|
66
|
+
if (!expression || expression.type !== 'CallExpression') return false;
|
|
67
|
+
const callee = isAstNode(expression.callee) ? expression.callee : null;
|
|
68
|
+
if (!callee) return false;
|
|
69
|
+
if (callee.type === 'Identifier') {
|
|
70
|
+
return callee.name === 'definePlay' || callee.name === 'defineWorkflow';
|
|
71
|
+
}
|
|
72
|
+
if (
|
|
73
|
+
callee.type === 'MemberExpression' &&
|
|
74
|
+
!callee.computed &&
|
|
75
|
+
isAstNode(callee.property) &&
|
|
76
|
+
callee.property.type === 'Identifier'
|
|
77
|
+
) {
|
|
78
|
+
return (
|
|
79
|
+
callee.property.name === 'definePlay' ||
|
|
80
|
+
callee.property.name === 'defineWorkflow'
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The plays `sourceCode` exports, default first, then named exports in source
|
|
88
|
+
* order. `null` means acorn could not parse the file — the caller abstains and
|
|
89
|
+
* the TypeScript diagnostics own the syntax error. An EMPTY array is a real
|
|
90
|
+
* answer: the file parses and exports no `definePlay`.
|
|
91
|
+
*/
|
|
92
|
+
export function listPlayFileExports(
|
|
93
|
+
sourceCode: string,
|
|
94
|
+
): PlayFileExport[] | null {
|
|
95
|
+
const ast = parsePlaySourceForAnalysis(sourceCode);
|
|
96
|
+
if (!ast) return null;
|
|
97
|
+
|
|
98
|
+
/** Local const/let/var name -> its initializer, for resolving `export { x }`
|
|
99
|
+
* and `export default x` back to the `definePlay` call they name. */
|
|
100
|
+
const declarations = new Map<string, AstNode | null>();
|
|
101
|
+
/** Exported name -> local name, in source order. */
|
|
102
|
+
const namedExports = new Map<string, string>();
|
|
103
|
+
let defaultExpression: AstNode | null = null;
|
|
104
|
+
|
|
105
|
+
const recordDeclarations = (declaration: AstNode, exported: boolean) => {
|
|
106
|
+
for (const declarator of astArray(declaration.declarations)) {
|
|
107
|
+
const name = getIdentifierName(declarator.id);
|
|
108
|
+
if (!name) continue;
|
|
109
|
+
declarations.set(
|
|
110
|
+
name,
|
|
111
|
+
isAstNode(declarator.init) ? declarator.init : null,
|
|
112
|
+
);
|
|
113
|
+
if (exported) namedExports.set(name, name);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
for (const statement of astArray(ast.body)) {
|
|
118
|
+
if (statement.type === 'VariableDeclaration') {
|
|
119
|
+
recordDeclarations(statement, false);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
123
|
+
defaultExpression = isAstNode(statement.declaration)
|
|
124
|
+
? statement.declaration
|
|
125
|
+
: null;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (statement.type === 'TSExportAssignment') {
|
|
129
|
+
defaultExpression = isAstNode(statement.expression)
|
|
130
|
+
? statement.expression
|
|
131
|
+
: null;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (statement.type !== 'ExportNamedDeclaration') continue;
|
|
135
|
+
if (
|
|
136
|
+
isAstNode(statement.declaration) &&
|
|
137
|
+
statement.declaration.type === 'VariableDeclaration'
|
|
138
|
+
) {
|
|
139
|
+
recordDeclarations(statement.declaration, true);
|
|
140
|
+
}
|
|
141
|
+
for (const specifier of astArray(statement.specifiers)) {
|
|
142
|
+
const localName = getIdentifierName(specifier.local);
|
|
143
|
+
const exportedName = getIdentifierName(specifier.exported);
|
|
144
|
+
if (localName && exportedName) namedExports.set(exportedName, localName);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// The default export's local name, when it is `export default <identifier>`.
|
|
149
|
+
// That identifier is an ALIAS of `default`, not a second play.
|
|
150
|
+
const defaultLocalName = getIdentifierName(
|
|
151
|
+
unwrapStaticExpression(defaultExpression),
|
|
152
|
+
);
|
|
153
|
+
const defaultIsPlay = defaultLocalName
|
|
154
|
+
? isDefinePlayCall(declarations.get(defaultLocalName) ?? null)
|
|
155
|
+
: isDefinePlayCall(defaultExpression);
|
|
156
|
+
|
|
157
|
+
const exports: PlayFileExport[] = [];
|
|
158
|
+
const aliasedLocals = new Set<string>();
|
|
159
|
+
if (defaultIsPlay) {
|
|
160
|
+
const aliases = defaultLocalName
|
|
161
|
+
? [...namedExports.entries()]
|
|
162
|
+
.filter(([, local]) => local === defaultLocalName)
|
|
163
|
+
.map(([exported]) => exported)
|
|
164
|
+
: [];
|
|
165
|
+
if (defaultLocalName) aliasedLocals.add(defaultLocalName);
|
|
166
|
+
exports.push({ name: PLAY_DEFAULT_EXPORT, aliases });
|
|
167
|
+
}
|
|
168
|
+
for (const [exportedName, localName] of namedExports) {
|
|
169
|
+
if (exportedName === PLAY_DEFAULT_EXPORT) continue;
|
|
170
|
+
if (aliasedLocals.has(localName)) continue;
|
|
171
|
+
if (!isDefinePlayCall(declarations.get(localName) ?? null)) continue;
|
|
172
|
+
exports.push({ name: exportedName, aliases: [] });
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return exports;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Resolves an export name a caller or an `@mermaid <name>` header wrote to its
|
|
180
|
+
* canonical name. `scalar` in `export default scalar` resolves to `default`;
|
|
181
|
+
* an unknown name resolves to `null` so the caller can fail loudly with the
|
|
182
|
+
* available set rather than silently binding nothing.
|
|
183
|
+
*/
|
|
184
|
+
export function canonicalPlayExportName(
|
|
185
|
+
exportName: string | null | undefined,
|
|
186
|
+
exports: readonly PlayFileExport[],
|
|
187
|
+
): string | null {
|
|
188
|
+
const requested = exportName?.trim() || PLAY_DEFAULT_EXPORT;
|
|
189
|
+
for (const entry of exports) {
|
|
190
|
+
if (entry.name === requested || entry.aliases.includes(requested)) {
|
|
191
|
+
return entry.name;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Every name an author may legally write, for a "valid names are …" message. */
|
|
198
|
+
export function playExportNamesForMessage(
|
|
199
|
+
exports: readonly PlayFileExport[],
|
|
200
|
+
): string[] {
|
|
201
|
+
return exports.flatMap((entry) => [entry.name, ...entry.aliases]);
|
|
202
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeTableNamespace } from './row-identity';
|
|
2
2
|
import { sqlSafePlayColumnName } from '../play-data-plane/column-names';
|
|
3
|
+
import type { PlayDocflow } from './docflow';
|
|
3
4
|
|
|
4
5
|
export { sqlSafePlayColumnName };
|
|
5
6
|
|
|
@@ -23,6 +24,8 @@ export interface PlayStaticReturnField {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export interface PlayStaticPipeline {
|
|
27
|
+
/** Authored business flow. Static analysis is used only when this is absent. */
|
|
28
|
+
docflow?: PlayDocflow;
|
|
26
29
|
tableNamespace?: string;
|
|
27
30
|
inputFields?: string[];
|
|
28
31
|
rowKeyFields?: string[];
|
|
@@ -138,7 +141,10 @@ export function deriveStaticPipelineEntryInputFields(
|
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
export type PlaySheetColumnSource =
|
|
141
|
-
|
|
144
|
+
| 'input'
|
|
145
|
+
| 'datasetColumn'
|
|
146
|
+
| 'waterfallStep'
|
|
147
|
+
| 'childPlayColumn';
|
|
142
148
|
|
|
143
149
|
export interface PlaySheetColumnContract {
|
|
144
150
|
id: string;
|
|
@@ -444,6 +450,9 @@ function truncateStaticSubstepsForStorage(
|
|
|
444
450
|
}))
|
|
445
451
|
: undefined,
|
|
446
452
|
waterfallIds: base.waterfallIds ? [...base.waterfallIds] : undefined,
|
|
453
|
+
undrawnColumns: base.undrawnColumns
|
|
454
|
+
? [...base.undrawnColumns]
|
|
455
|
+
: undefined,
|
|
447
456
|
steps: truncateStaticSubstepsForStorage(base.steps, nestedInput),
|
|
448
457
|
sheetContract: cloneStorageSafeSheetContract(base.sheetContract),
|
|
449
458
|
});
|
|
@@ -1146,6 +1155,12 @@ export type PlayStaticSubstep = PlayStaticSubstepMetadata &
|
|
|
1146
1155
|
waterfallIds?: string[];
|
|
1147
1156
|
steps?: PlayStaticSubstep[];
|
|
1148
1157
|
sheetContract?: PlaySheetContract | null;
|
|
1158
|
+
/**
|
|
1159
|
+
* Columns the author declared as deliberately absent from the `@mermaid`
|
|
1160
|
+
* diagram via `.run({ undrawnColumns: [...] })`. The docflow column
|
|
1161
|
+
* coverage gate reads this; nothing about execution does.
|
|
1162
|
+
*/
|
|
1163
|
+
undrawnColumns?: string[];
|
|
1149
1164
|
description?: string;
|
|
1150
1165
|
sourceRange?: PlayStaticSourceRange;
|
|
1151
1166
|
callDepth?: number;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The acorn TypeScript parser and the two guards every play-source analyzer
|
|
3
|
+
* needs, in one dependency-free module.
|
|
4
|
+
*
|
|
5
|
+
* Extracted so modules that must not import each other can still share one
|
|
6
|
+
* parser configuration: `docflow-binding` (binding resolution) and
|
|
7
|
+
* `play-exports` (which plays a file exports) both parse the same source, and
|
|
8
|
+
* a second parser config would be a silent divergence rather than a loud one.
|
|
9
|
+
*/
|
|
10
|
+
import { Parser } from 'acorn';
|
|
11
|
+
import { tsPlugin } from 'acorn-typescript';
|
|
12
|
+
|
|
13
|
+
export type AstNode = {
|
|
14
|
+
type: string;
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const TypeScriptParser = Parser.extend(
|
|
19
|
+
tsPlugin({
|
|
20
|
+
allowSatisfies: true,
|
|
21
|
+
jsx: {
|
|
22
|
+
allowNamespaces: true,
|
|
23
|
+
allowNamespacedObjects: true,
|
|
24
|
+
},
|
|
25
|
+
}) as unknown as (BaseParser: typeof Parser) => typeof Parser,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export function isAstNode(value: unknown): value is AstNode {
|
|
29
|
+
return value !== null && typeof value === 'object' && 'type' in value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function astArray(value: unknown): AstNode[] {
|
|
33
|
+
return Array.isArray(value) ? value.filter(isAstNode) : [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Parses play source for analysis. `null` when acorn cannot: the caller
|
|
37
|
+
* abstains, and the TypeScript diagnostics own the syntax error. */
|
|
38
|
+
export function parsePlaySourceForAnalysis(sourceCode: string): AstNode | null {
|
|
39
|
+
try {
|
|
40
|
+
return TypeScriptParser.parse(sourceCode, {
|
|
41
|
+
ecmaVersion: 'latest',
|
|
42
|
+
sourceType: 'module',
|
|
43
|
+
allowHashBang: true,
|
|
44
|
+
}) as unknown as AstNode;
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|