@temporalio/workflow
Advanced tools
Comparing version 1.0.1 to 1.1.0
@@ -60,3 +60,3 @@ /** | ||
export * from './interceptors'; | ||
export { ChildWorkflowCancellationType, ChildWorkflowOptions, ContinueAsNew, ContinueAsNewOptions, ParentClosePolicy, ParentWorkflowInfo, WorkflowInfo, } from './interfaces'; | ||
export { ChildWorkflowCancellationType, ChildWorkflowOptions, ContinueAsNew, ContinueAsNewOptions, ParentClosePolicy, ParentWorkflowInfo, WorkflowInfo, FileSlice, FileLocation, StackTrace, EnhancedStackTrace, SDKInfo, } from './interfaces'; | ||
export { Sink, SinkCall, SinkFunction, Sinks } from './sinks'; | ||
@@ -63,0 +63,0 @@ export { Trigger } from './trigger'; |
@@ -246,1 +246,57 @@ import { RetryPolicy, TemporalFailure } from '@temporalio/common'; | ||
export declare type ChildWorkflowOptionsWithDefaults = ChildWorkflowOptions & RequiredChildWorkflowOptions; | ||
export interface SDKInfo { | ||
name: string; | ||
version: string; | ||
} | ||
/** | ||
* Represents a slice of a file starting at lineOffset | ||
*/ | ||
export interface FileSlice { | ||
/** | ||
* slice of a file with `\n` (newline) line terminator. | ||
*/ | ||
content: string; | ||
/** | ||
* Only used possible to trim the file without breaking syntax highlighting. | ||
*/ | ||
lineOffset: number; | ||
} | ||
/** | ||
* A pointer to a location in a file | ||
*/ | ||
export interface FileLocation { | ||
/** | ||
* Path to source file (absolute or relative). | ||
* When using a relative path, make sure all paths are relative to the same root. | ||
*/ | ||
filePath?: string; | ||
/** | ||
* If possible, SDK should send this, required for displaying the code location. | ||
*/ | ||
line?: number; | ||
/** | ||
* If possible, SDK should send this. | ||
*/ | ||
column?: number; | ||
/** | ||
* Function name this line belongs to (if applicable). | ||
* Used for falling back to stack trace view. | ||
*/ | ||
functionName?: string; | ||
} | ||
export interface StackTrace { | ||
locations: FileLocation[]; | ||
} | ||
/** | ||
* Used as the result for the enhanced stack trace query | ||
*/ | ||
export interface EnhancedStackTrace { | ||
sdk: SDKInfo; | ||
/** | ||
* Mapping of file path to file contents. | ||
* SDK may choose to send no, some or all sources. | ||
* Sources might be trimmed, and some time only the file(s) of the top element of the trace will be sent. | ||
*/ | ||
sources: Record<string, FileSlice[]>; | ||
stacks: StackTrace[]; | ||
} |
import { PayloadConverter } from '@temporalio/common'; | ||
import type { RawSourceMap } from 'source-map'; | ||
import { Workflow, WorkflowQueryType, WorkflowSignalType } from '@temporalio/internal-workflow-common'; | ||
@@ -6,4 +7,8 @@ import type { coresdk } from '@temporalio/proto'; | ||
import { QueryInput, SignalInput, WorkflowExecuteInput, WorkflowInterceptors, WorkflowInterceptorsFactory } from './interceptors'; | ||
import { WorkflowInfo } from './interfaces'; | ||
import { FileLocation, WorkflowInfo } from './interfaces'; | ||
import { SinkCall } from './sinks'; | ||
export interface Stack { | ||
formatted: string; | ||
structured: FileLocation[]; | ||
} | ||
/** | ||
@@ -14,3 +19,3 @@ * Global store to track promise stacks for stack trace query | ||
childToParent: Map<Promise<unknown>, Set<Promise<unknown>>>; | ||
promiseToStack: Map<Promise<unknown>, string>; | ||
promiseToStack: Map<Promise<unknown>, Stack>; | ||
} | ||
@@ -101,2 +106,11 @@ export declare type ResolveFunction<T = any> = (val: T) => any; | ||
/** | ||
* Source map file for looking up the source files in response to __enhanced_stack_trace | ||
*/ | ||
sourceMap: RawSourceMap | undefined; | ||
/** | ||
* Whether or not to send the sources in enhanced stack trace query responses | ||
*/ | ||
showStackTraceSources: boolean; | ||
protected getStackTraces(): Stack[]; | ||
/** | ||
* Mapping of query name to handler | ||
@@ -103,0 +117,0 @@ */ |
@@ -13,2 +13,5 @@ "use strict"; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _State_now; | ||
@@ -24,2 +27,3 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
const stack_helpers_1 = require("./stack-helpers"); | ||
const pkg_1 = __importDefault(require("./pkg")); | ||
var StartChildWorkflowExecutionFailedCause; | ||
@@ -300,2 +304,6 @@ (function (StartChildWorkflowExecutionFailedCause) { | ||
/** | ||
* Whether or not to send the sources in enhanced stack trace query responses | ||
*/ | ||
this.showStackTraceSources = false; | ||
/** | ||
* Mapping of query name to handler | ||
@@ -307,23 +315,32 @@ */ | ||
() => { | ||
const { childToParent, promiseToStack } = globalThis.__TEMPORAL__ | ||
.promiseStackStore; | ||
const internalNodes = new Set([...childToParent.values()].reduce((acc, curr) => { | ||
for (const p of curr) { | ||
acc.add(p); | ||
return this.getStackTraces() | ||
.map((s) => s.formatted) | ||
.join('\n\n'); | ||
}, | ||
], | ||
[ | ||
'__enhanced_stack_trace', | ||
() => { | ||
const { sourceMap } = this; | ||
const sdk = { name: 'typescript', version: pkg_1.default.version }; | ||
const stacks = this.getStackTraces().map(({ structured: locations }) => ({ locations })); | ||
const sources = {}; | ||
if (this.showStackTraceSources) { | ||
for (const { locations } of stacks) { | ||
for (const { filePath } of locations) { | ||
if (!filePath) | ||
continue; | ||
const content = sourceMap?.sourcesContent?.[sourceMap?.sources.indexOf(filePath)]; | ||
if (!content) | ||
continue; | ||
sources[filePath] = [ | ||
{ | ||
content, | ||
lineOffset: 0, | ||
}, | ||
]; | ||
} | ||
} | ||
return acc; | ||
}, new Set())); | ||
const stacks = new Set(); | ||
for (const child of childToParent.keys()) { | ||
if (!internalNodes.has(child)) { | ||
const stack = promiseToStack.get(child); | ||
if (!stack) | ||
continue; | ||
stacks.add(stack); | ||
} | ||
} | ||
// Not 100% sure where this comes from, just filter it out | ||
stacks.delete(' at Promise.then (<anonymous>)'); | ||
stacks.delete(' at Promise.then (<anonymous>)\n'); | ||
return [...stacks].join('\n\n'); | ||
return { sdk, stacks, sources }; | ||
}, | ||
@@ -390,2 +407,24 @@ ], | ||
} | ||
getStackTraces() { | ||
const { childToParent, promiseToStack } = globalThis.__TEMPORAL__.promiseStackStore; | ||
const internalNodes = [...childToParent.values()].reduce((acc, curr) => { | ||
for (const p of curr) { | ||
acc.add(p); | ||
} | ||
return acc; | ||
}, new Set()); | ||
const stacks = new Map(); | ||
for (const child of childToParent.keys()) { | ||
if (!internalNodes.has(child)) { | ||
const stack = promiseToStack.get(child); | ||
if (!stack || !stack.formatted) | ||
continue; | ||
stacks.set(stack.formatted, stack); | ||
} | ||
} | ||
// Not 100% sure where this comes from, just filter it out | ||
stacks.delete(' at Promise.then (<anonymous>)'); | ||
stacks.delete(' at Promise.then (<anonymous>)\n'); | ||
return [...stacks].map(([_, stack]) => stack); | ||
} | ||
get now() { | ||
@@ -392,0 +431,0 @@ if (__classPrivateFieldGet(this, _State_now, "f") === undefined) { |
@@ -11,2 +11,3 @@ /** | ||
import { SinkCall } from './sinks'; | ||
import type { RawSourceMap } from 'source-map'; | ||
export { PromiseStackStore } from './internals'; | ||
@@ -18,3 +19,7 @@ export interface WorkflowCreateOptions { | ||
patches: string[]; | ||
showStackTraceSources: boolean; | ||
} | ||
export interface WorkflowCreateOptionsWithSourceMap extends WorkflowCreateOptions { | ||
sourceMap: RawSourceMap; | ||
} | ||
export interface ImportFunctions { | ||
@@ -31,3 +36,3 @@ importWorkflows: WorkflowsImportFunc; | ||
*/ | ||
export declare function initRuntime({ info, randomnessSeed, now, patches }: WorkflowCreateOptions): Promise<void>; | ||
export declare function initRuntime({ info, randomnessSeed, now, patches, sourceMap, showStackTraceSources, }: WorkflowCreateOptionsWithSourceMap): Promise<void>; | ||
/** | ||
@@ -34,0 +39,0 @@ * Run a chunk of activation jobs |
@@ -103,3 +103,3 @@ "use strict"; | ||
*/ | ||
async function initRuntime({ info, randomnessSeed, now, patches }) { | ||
async function initRuntime({ info, randomnessSeed, now, patches, sourceMap, showStackTraceSources, }) { | ||
const global = globalThis; | ||
@@ -117,2 +117,4 @@ // Set the runId globally on the context so it can be retrieved in the case | ||
internals_1.state.random = (0, alea_1.alea)(randomnessSeed); | ||
internals_1.state.showStackTraceSources = showStackTraceSources; | ||
internals_1.state.sourceMap = sourceMap; | ||
if (info.unsafe.isReplaying) { | ||
@@ -119,0 +121,0 @@ for (const patch of patches) { |
import { ActivityFunction, ActivityOptions, LocalActivityOptions, QueryDefinition, SearchAttributes, SignalDefinition, UntypedActivities, WithWorkflowArgs, Workflow, WorkflowResultType, WorkflowReturnType } from '@temporalio/internal-workflow-common'; | ||
import { ChildWorkflowOptions, ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions, WorkflowInfo } from './interfaces'; | ||
import { ChildWorkflowOptions, ChildWorkflowOptionsWithDefaults, ContinueAsNewOptions, EnhancedStackTrace, WorkflowInfo } from './interfaces'; | ||
import { Sinks } from './sinks'; | ||
@@ -408,1 +408,2 @@ import { ChildWorkflowHandle, ExternalWorkflowHandle } from './workflow-handle'; | ||
export declare const stackTraceQuery: QueryDefinition<string, []>; | ||
export declare const enhancedStackTraceQuery: QueryDefinition<EnhancedStackTrace, []>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.stackTraceQuery = exports.upsertSearchAttributes = exports.setHandler = exports.defineQuery = exports.defineSignal = exports.condition = exports.deprecatePatch = exports.patched = exports.uuid4 = exports.continueAsNew = exports.makeContinueAsNewFunc = exports.proxySinks = exports.inWorkflowContext = exports.workflowInfo = exports.executeChild = exports.startChild = exports.getExternalWorkflowHandle = exports.proxyLocalActivities = exports.proxyActivities = exports.NotAnActivityMethod = exports.scheduleLocalActivity = exports.scheduleActivity = exports.sleep = exports.addDefaultWorkflowOptions = void 0; | ||
exports.enhancedStackTraceQuery = exports.stackTraceQuery = exports.upsertSearchAttributes = exports.setHandler = exports.defineQuery = exports.defineSignal = exports.condition = exports.deprecatePatch = exports.patched = exports.uuid4 = exports.continueAsNew = exports.makeContinueAsNewFunc = exports.proxySinks = exports.inWorkflowContext = exports.workflowInfo = exports.executeChild = exports.startChild = exports.getExternalWorkflowHandle = exports.proxyLocalActivities = exports.proxyActivities = exports.NotAnActivityMethod = exports.scheduleLocalActivity = exports.scheduleActivity = exports.sleep = exports.addDefaultWorkflowOptions = void 0; | ||
const common_1 = require("@temporalio/common"); | ||
@@ -944,2 +944,3 @@ const internal_workflow_common_1 = require("@temporalio/internal-workflow-common"); | ||
exports.stackTraceQuery = defineQuery('__stack_trace'); | ||
exports.enhancedStackTraceQuery = defineQuery('__enhanced_stack_trace'); | ||
//# sourceMappingURL=workflow.js.map |
{ | ||
"name": "@temporalio/workflow", | ||
"version": "1.0.1", | ||
"version": "1.1.0", | ||
"description": "Temporal.io SDK Workflow sub-package", | ||
@@ -20,6 +20,9 @@ "keywords": [ | ||
"dependencies": { | ||
"@temporalio/common": "^1.0.1", | ||
"@temporalio/internal-workflow-common": "^1.0.1", | ||
"@temporalio/proto": "^1.0.1" | ||
"@temporalio/common": "^1.1.0", | ||
"@temporalio/internal-workflow-common": "^1.1.0", | ||
"@temporalio/proto": "^1.1.0" | ||
}, | ||
"devDependencies": { | ||
"source-map": "^0.7.4" | ||
}, | ||
"publishConfig": { | ||
@@ -32,3 +35,3 @@ "access": "public" | ||
], | ||
"gitHead": "a1dae539e72b6b088b400998d7bef482e8ed52f1" | ||
"gitHead": "132f23a47a93fecf3f39836b31f08ea837b30320" | ||
} |
@@ -87,2 +87,7 @@ /** | ||
WorkflowInfo, | ||
FileSlice, | ||
FileLocation, | ||
StackTrace, | ||
EnhancedStackTrace, | ||
SDKInfo, | ||
} from './interfaces'; | ||
@@ -89,0 +94,0 @@ export { Sink, SinkCall, SinkFunction, Sinks } from './sinks'; |
@@ -295,1 +295,62 @@ import { RetryPolicy, TemporalFailure } from '@temporalio/common'; | ||
export type ChildWorkflowOptionsWithDefaults = ChildWorkflowOptions & RequiredChildWorkflowOptions; | ||
export interface SDKInfo { | ||
name: string; | ||
version: string; | ||
} | ||
/** | ||
* Represents a slice of a file starting at lineOffset | ||
*/ | ||
export interface FileSlice { | ||
/** | ||
* slice of a file with `\n` (newline) line terminator. | ||
*/ | ||
content: string; | ||
/** | ||
* Only used possible to trim the file without breaking syntax highlighting. | ||
*/ | ||
lineOffset: number; | ||
} | ||
/** | ||
* A pointer to a location in a file | ||
*/ | ||
export interface FileLocation { | ||
/** | ||
* Path to source file (absolute or relative). | ||
* When using a relative path, make sure all paths are relative to the same root. | ||
*/ | ||
filePath?: string; | ||
/** | ||
* If possible, SDK should send this, required for displaying the code location. | ||
*/ | ||
line?: number; | ||
/** | ||
* If possible, SDK should send this. | ||
*/ | ||
column?: number; | ||
/** | ||
* Function name this line belongs to (if applicable). | ||
* Used for falling back to stack trace view. | ||
*/ | ||
functionName?: string; | ||
} | ||
export interface StackTrace { | ||
locations: FileLocation[]; | ||
} | ||
/** | ||
* Used as the result for the enhanced stack trace query | ||
*/ | ||
export interface EnhancedStackTrace { | ||
sdk: SDKInfo; | ||
/** | ||
* Mapping of file path to file contents. | ||
* SDK may choose to send no, some or all sources. | ||
* Sources might be trimmed, and some time only the file(s) of the top element of the trace will be sent. | ||
*/ | ||
sources: Record<string, FileSlice[]>; | ||
stacks: StackTrace[]; | ||
} |
import { PayloadConverter } from '@temporalio/common'; | ||
import type { RawSourceMap } from 'source-map'; | ||
import { | ||
@@ -30,5 +31,6 @@ arrayFromPayloads, | ||
} from './interceptors'; | ||
import { ContinueAsNew, WorkflowInfo } from './interfaces'; | ||
import { ContinueAsNew, SDKInfo, FileSlice, EnhancedStackTrace, FileLocation, WorkflowInfo } from './interfaces'; | ||
import { SinkCall } from './sinks'; | ||
import { untrackPromise } from './stack-helpers'; | ||
import pkg from './pkg'; | ||
@@ -42,2 +44,7 @@ enum StartChildWorkflowExecutionFailedCause { | ||
export interface Stack { | ||
formatted: string; | ||
structured: FileLocation[]; | ||
} | ||
/** | ||
@@ -48,3 +55,3 @@ * Global store to track promise stacks for stack trace query | ||
childToParent: Map<Promise<unknown>, Set<Promise<unknown>>>; | ||
promiseToStack: Map<Promise<unknown>, string>; | ||
promiseToStack: Map<Promise<unknown>, Stack>; | ||
} | ||
@@ -384,2 +391,34 @@ | ||
/** | ||
* Source map file for looking up the source files in response to __enhanced_stack_trace | ||
*/ | ||
public sourceMap: RawSourceMap | undefined; | ||
/** | ||
* Whether or not to send the sources in enhanced stack trace query responses | ||
*/ | ||
public showStackTraceSources = false; | ||
protected getStackTraces(): Stack[] { | ||
const { childToParent, promiseToStack } = (globalThis as any).__TEMPORAL__.promiseStackStore as PromiseStackStore; | ||
const internalNodes = [...childToParent.values()].reduce((acc, curr) => { | ||
for (const p of curr) { | ||
acc.add(p); | ||
} | ||
return acc; | ||
}, new Set()); | ||
const stacks = new Map<string, Stack>(); | ||
for (const child of childToParent.keys()) { | ||
if (!internalNodes.has(child)) { | ||
const stack = promiseToStack.get(child); | ||
if (!stack || !stack.formatted) continue; | ||
stacks.set(stack.formatted, stack); | ||
} | ||
} | ||
// Not 100% sure where this comes from, just filter it out | ||
stacks.delete(' at Promise.then (<anonymous>)'); | ||
stacks.delete(' at Promise.then (<anonymous>)\n'); | ||
return [...stacks].map(([_, stack]) => stack); | ||
} | ||
/** | ||
* Mapping of query name to handler | ||
@@ -391,24 +430,30 @@ */ | ||
() => { | ||
const { childToParent, promiseToStack } = (globalThis as any).__TEMPORAL__ | ||
.promiseStackStore as PromiseStackStore; | ||
const internalNodes = new Set( | ||
[...childToParent.values()].reduce((acc, curr) => { | ||
for (const p of curr) { | ||
acc.add(p); | ||
return this.getStackTraces() | ||
.map((s) => s.formatted) | ||
.join('\n\n'); | ||
}, | ||
], | ||
[ | ||
'__enhanced_stack_trace', | ||
(): EnhancedStackTrace => { | ||
const { sourceMap } = this; | ||
const sdk: SDKInfo = { name: 'typescript', version: pkg.version }; | ||
const stacks = this.getStackTraces().map(({ structured: locations }) => ({ locations })); | ||
const sources: Record<string, FileSlice[]> = {}; | ||
if (this.showStackTraceSources) { | ||
for (const { locations } of stacks) { | ||
for (const { filePath } of locations) { | ||
if (!filePath) continue; | ||
const content = sourceMap?.sourcesContent?.[sourceMap?.sources.indexOf(filePath)]; | ||
if (!content) continue; | ||
sources[filePath] = [ | ||
{ | ||
content, | ||
lineOffset: 0, | ||
}, | ||
]; | ||
} | ||
return acc; | ||
}, new Set()) | ||
); | ||
const stacks = new Set<string>(); | ||
for (const child of childToParent.keys()) { | ||
if (!internalNodes.has(child)) { | ||
const stack = promiseToStack.get(child); | ||
if (!stack) continue; | ||
stacks.add(stack); | ||
} | ||
} | ||
// Not 100% sure where this comes from, just filter it out | ||
stacks.delete(' at Promise.then (<anonymous>)'); | ||
stacks.delete(' at Promise.then (<anonymous>)\n'); | ||
return [...stacks].join('\n\n'); | ||
return { sdk, stacks, sources }; | ||
}, | ||
@@ -415,0 +460,0 @@ ], |
@@ -16,2 +16,3 @@ /** | ||
import { SinkCall } from './sinks'; | ||
import type { RawSourceMap } from 'source-map'; | ||
@@ -26,4 +27,9 @@ // Export the type for use on the "worker" side | ||
patches: string[]; | ||
showStackTraceSources: boolean; | ||
} | ||
export interface WorkflowCreateOptionsWithSourceMap extends WorkflowCreateOptions { | ||
sourceMap: RawSourceMap; | ||
} | ||
export interface ImportFunctions { | ||
@@ -111,3 +117,10 @@ importWorkflows: WorkflowsImportFunc; | ||
*/ | ||
export async function initRuntime({ info, randomnessSeed, now, patches }: WorkflowCreateOptions): Promise<void> { | ||
export async function initRuntime({ | ||
info, | ||
randomnessSeed, | ||
now, | ||
patches, | ||
sourceMap, | ||
showStackTraceSources, | ||
}: WorkflowCreateOptionsWithSourceMap): Promise<void> { | ||
const global = globalThis as any; | ||
@@ -126,2 +139,4 @@ // Set the runId globally on the context so it can be retrieved in the case | ||
state.random = alea(randomnessSeed); | ||
state.showStackTraceSources = showStackTraceSources; | ||
state.sourceMap = sourceMap; | ||
@@ -128,0 +143,0 @@ if (info.unsafe.isReplaying) { |
@@ -36,2 +36,3 @@ import { mapToPayloads, searchAttributePayloadConverter, toPayloads } from '@temporalio/common'; | ||
ContinueAsNewOptions, | ||
EnhancedStackTrace, | ||
WorkflowInfo, | ||
@@ -1249,1 +1250,2 @@ } from './interfaces'; | ||
export const stackTraceQuery = defineQuery<string>('__stack_trace'); | ||
export const enhancedStackTraceQuery = defineQuery<EnhancedStackTrace>('__enhanced_stack_trace'); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
321113
59
6859
1