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.
Files changed (44) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +17 -1
  2. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  3. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  4. package/dist/bundling-sources/sdk/src/types.ts +43 -1
  5. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +30 -1
  6. package/dist/bundling-sources/shared_libs/play-runtime/cell-provenance.ts +231 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1094 -128
  8. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +178 -9
  9. package/dist/bundling-sources/shared_libs/play-runtime/docflow-node-io.ts +634 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/docflow-observation.ts +64 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts +1 -1
  12. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +18 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +33 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/log-provenance.ts +251 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/play-node-scope.ts +160 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +6 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +27 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +43 -5
  19. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +12 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +26 -4
  21. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +6 -1
  22. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +83 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +3 -0
  24. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +49 -1
  25. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +375 -29
  26. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +636 -0
  27. package/dist/bundling-sources/shared_libs/plays/docflow-binding.ts +598 -0
  28. package/dist/bundling-sources/shared_libs/plays/docflow.ts +1645 -0
  29. package/dist/bundling-sources/shared_libs/plays/play-exports.ts +202 -0
  30. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +16 -1
  31. package/dist/bundling-sources/shared_libs/plays/ts-ast.ts +48 -0
  32. package/dist/cli/index.js +994 -312
  33. package/dist/cli/index.mjs +994 -312
  34. package/dist/{compiler-manifest-Cj3--4ZJ.d.mts → compiler-manifest-Bl8kmLx9.d.mts} +118 -0
  35. package/dist/{compiler-manifest-Cj3--4ZJ.d.ts → compiler-manifest-Bl8kmLx9.d.ts} +118 -0
  36. package/dist/index.d.mts +47 -2
  37. package/dist/index.d.ts +47 -2
  38. package/dist/index.js +419 -59
  39. package/dist/index.mjs +419 -59
  40. package/dist/install-integrity.json +12 -2
  41. package/dist/plays/bundle-play-file.d.mts +2 -2
  42. package/dist/plays/bundle-play-file.d.ts +2 -2
  43. package/dist/plays/bundle-play-file.mjs +1361 -45
  44. 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
- 'input' | 'datasetColumn' | 'waterfallStep' | 'childPlayColumn';
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
+ }