@enfocussw/switch-scripting-context 25.11.0-beta.9 → 25.11.1-beta.1
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/CHANGELOG.md +256 -0
- package/README.md +59 -35
- package/dist/init.d.ts +15 -0
- package/dist/init.js +130 -76
- package/docs/switch-api/api-versions.md +116 -0
- package/docs/switch-api/connection.md +82 -0
- package/docs/switch-api/{api-document-classes.md → document-classes.md} +13 -2
- package/docs/switch-api/entry-points.md +171 -0
- package/docs/switch-api/{api-enums.md → enums.md} +23 -12
- package/docs/switch-api/{api-execution-environment.md → execution-environment.md} +39 -12
- package/docs/switch-api/{api-flow-element.md → flow-element.md} +23 -7
- package/docs/switch-api/{api-http.md → http.md} +10 -1
- package/docs/switch-api/job-patterns.md +178 -0
- package/docs/switch-api/{api-job.md → job.md} +23 -9
- package/docs/switch-api/{api-logging.md → logging.md} +47 -5
- package/docs/switch-api/{api-switch.md → switch.md} +68 -4
- package/docs/switch-appstore/app-guidelines.md +258 -0
- package/docs/switch-appstore/app-manual.md +84 -0
- package/docs/switch-appstore/app-store-listing.md +69 -0
- package/docs/switch-appstore/app-store-submission.md +83 -0
- package/docs/{switch-api/api-debugging.md → switch-project/debugging.md} +9 -0
- package/docs/{switch-api/api-logs-and-dataroot.md → switch-project/logs-and-dataroot.md} +10 -1
- package/docs/switch-project/project-planning.md +117 -0
- package/docs/switch-project/property-documentation.md +75 -0
- package/docs/{switch-api/api-property-editors.md → switch-project/property-editors.md} +55 -8
- package/docs/{switch-api/api-script-declaration.md → switch-project/script-declaration.md} +47 -13
- package/docs/switch-project/script-structure.md +188 -0
- package/docs/{switch-api/api-tooling.md → switch-project/tooling.md} +87 -1
- package/docs/{switch-api/api-vscode.md → switch-project/vscode.md} +19 -0
- package/docs/switch-scripting.md +49 -23
- package/package.json +11 -7
- package/docs/switch-api/api-connection.md +0 -63
- package/docs/switch-api/api-entry-points.md +0 -82
- package/docs/switch-api/api-job-patterns.md +0 -79
- package/docs/switch-api/api-script-structure.md +0 -85
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: entry-points
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 2
|
|
5
|
+
summary: "All entry point signatures, constraints, and when each is called"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Scaffolding a script, adding/editing an entry point, or making any edit to main.ts/main.js"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Switch Script Entry Points
|
|
11
|
+
|
|
12
|
+
Entry points are top-level `async` functions with specific names. They are **not exported**. Switch calls them automatically based on flow events.
|
|
13
|
+
|
|
14
|
+
## Entry-point scanner constraints
|
|
15
|
+
|
|
16
|
+
Switch discovers a script's entry points by regex, not by parsing. Before matching
|
|
17
|
+
`function\s+(name)\s*\(` it strips comments and literals with a regex that doesn't understand JS
|
|
18
|
+
escaping. Certain source shapes make that strip regex delete large spans of real code — and every
|
|
19
|
+
`function` declaration inside the deleted span becomes invisible to Switch, whether or not that
|
|
20
|
+
function is itself well-formed.
|
|
21
|
+
|
|
22
|
+
This applies to **every** entry point on this page, not only the four checked below — a swallowed
|
|
23
|
+
`validateProperties` or `getLibraryForProperty` fails silently (the callback just never runs, no
|
|
24
|
+
error anywhere), which is worse than the loud failure the four below produce. The one exception is
|
|
25
|
+
`calculateScriptExpression`: it's invoked directly at runtime rather than through this scanner, so
|
|
26
|
+
it isn't at risk.
|
|
27
|
+
|
|
28
|
+
If none of `jobArrived`, `timerFired`, `flowStopTriggered`, `httpRequestTriggeredAsync` survives,
|
|
29
|
+
Switch fails with `Cannot open script '<name>': no entry points found` — `httpRequestTriggeredSync`
|
|
30
|
+
alone does not satisfy this check. Both the packed `.sscript` (the entry-point list is baked in at
|
|
31
|
+
pack time) and the unpacked script folder (`main.js` is rescanned by this same scanner every time
|
|
32
|
+
Switch loads it, e.g. running or debugging from Designer) are affected. Packing does not validate
|
|
33
|
+
or warn about any of this — a script that packs cleanly can still fail to load.
|
|
34
|
+
|
|
35
|
+
**Rules for writing entry points in `main.ts`/`main.js`:**
|
|
36
|
+
|
|
37
|
+
1. Never write a string literal whose content ends with a backslash: `"\\"`, `'\\'`, `` `\\` ``,
|
|
38
|
+
`"C:\\Temp\\"`. This is the highest-frequency trigger — the strip regex hunts for the next
|
|
39
|
+
matching quote character anywhere later in the file to close the literal (a backslash right
|
|
40
|
+
before the real closing quote makes it skip past that quote), and deletes everything in between.
|
|
41
|
+
Use `"\x5c"`, `"\u005C"`, `String.fromCharCode(92)`, or restructure (e.g.
|
|
42
|
+
`JSON.stringify(v).slice(1, -1)` for backslash/quote escaping) instead. A backslash elsewhere in
|
|
43
|
+
the literal is fine: `"\\n is newline"`, `"a\\b"`.
|
|
44
|
+
2. Avoid regex literals — including ones that look properly closed, like `/[^/]+/` (a character
|
|
45
|
+
class containing an unescaped `/`). The strip regex doesn't understand character classes, so it
|
|
46
|
+
closes the "literal" early at the inner `/` and leaves a dangling `/` that swallows forward to
|
|
47
|
+
the next `/` anywhere later in the file. Use `new RegExp("...")` instead.
|
|
48
|
+
3. Avoid division that isn't in the plain `word / word` shape. `a / b` is recognised and stripped
|
|
49
|
+
safely; `) / 2`, `] / 2`, and `/=` are not, and the leftover `/` swallows forward exactly like an
|
|
50
|
+
unclosed regex literal. Rewrite as `Math.floor(x / y)` with plain identifiers, or hoist to a
|
|
51
|
+
named variable first.
|
|
52
|
+
4. Declare every entry point with the literal `function` keyword at top level:
|
|
53
|
+
`function jobArrived(...)` or `async function jobArrived(...)`. Arrow functions,
|
|
54
|
+
`exports.jobArrived = function (...)`, and class methods are invisible to the scanner.
|
|
55
|
+
5. Entry-point names are matched case-sensitively. `JobArrived` is silently dropped during
|
|
56
|
+
extraction — if another valid entry point is also present the script packs and loads without
|
|
57
|
+
error, the misnamed function just never runs.
|
|
58
|
+
|
|
59
|
+
See [tooling.md § Verify entry points before packing](../switch-project/tooling.md#verify-entry-points-before-packing)
|
|
60
|
+
for a script to catch this before it reaches Switch.
|
|
61
|
+
|
|
62
|
+
## Flow lifecycle
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
async function flowStartTriggered(s: Switch, flowElement: FlowElement): Promise<void>
|
|
66
|
+
```
|
|
67
|
+
Called when the flow starts. Use to subscribe to webhooks (`s.httpRequestSubscribe`) or channels (`flowElement.subscribeToChannel`). Cannot coexist with `timerFired` or `jobArrived` as the sole entry point. May execute in parallel for concurrent elements. Not available for debugging.
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
async function flowStopTriggered(s: Switch, flowElement: FlowElement): Promise<void>
|
|
71
|
+
```
|
|
72
|
+
Called when the flow stops. May execute in parallel for concurrent elements. Not available for debugging.
|
|
73
|
+
|
|
74
|
+
## Timer
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
async function timerFired(s: Switch, flowElement: FlowElement): Promise<void>
|
|
78
|
+
```
|
|
79
|
+
Called on a recurring timer. First fires after `flowStartTriggered`. Set the interval via `flowElement.setTimerInterval(seconds)`. Cannot coexist with `flowStartTriggered` as the sole entry point.
|
|
80
|
+
|
|
81
|
+
Required when `IncomingConnections="No"`; optional (alongside `jobArrived`) when
|
|
82
|
+
`IncomingConnections="Yes"`. Never leave it present but empty — remove it entirely if it does
|
|
83
|
+
nothing.
|
|
84
|
+
|
|
85
|
+
## Job processing
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
async function jobArrived(s: Switch, flowElement: FlowElement, job: Job): Promise<void>
|
|
89
|
+
```
|
|
90
|
+
Called when a job arrives. Must eventually call a `job.sendTo*()` or `job.fail()`. Can run concurrently if configured in the script XML declaration.
|
|
91
|
+
|
|
92
|
+
`jobArrived` and `timerFired` presence must match the declared connections — present when
|
|
93
|
+
`IncomingConnections="Yes"` (`timerFired` may additionally be present); when
|
|
94
|
+
`IncomingConnections="No"`, `timerFired` must be present instead. See
|
|
95
|
+
[script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields). Never leave an empty
|
|
96
|
+
`jobArrived` or `timerFired` in the script — remove the function entirely if it does nothing.
|
|
97
|
+
|
|
98
|
+
**Gotcha: a flow restart replays every queued job through `jobArrived` again.** This includes a job
|
|
99
|
+
whose real processing was deferred elsewhere, such as a job registered in global data and actually
|
|
100
|
+
handled later in `timerFired`. `jobArrived` does not skip a job just because it was already
|
|
101
|
+
registered on a previous run; if the element still has a large backlog queued when the flow
|
|
102
|
+
restarts, every one of those jobs fires `jobArrived` again, and working through a long backlog this
|
|
103
|
+
way can take a long time even when each invocation only needs to recognize the job as already
|
|
104
|
+
registered and return. A script that defers processing this way must check global data at the top
|
|
105
|
+
of `jobArrived` and return immediately for a job already registered there, rather than assuming
|
|
106
|
+
`jobArrived` fires exactly once per job.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
async function abort(s: Switch, flowElement: FlowElement, job: Job, abortData: any): Promise<void>
|
|
110
|
+
```
|
|
111
|
+
Called when an entry point exceeds its configured timeout. The `abortData` value was set beforehand via `s.setAbortData()` (Switch 22.1+). Maximum execution: 60 seconds, after which the script executor is killed. Applies to: `jobArrived`, `timerFired`, `httpRequestTriggeredSync`, `httpRequestTriggeredAsync`, `flowStartTriggered`, `flowStopTriggered`.
|
|
112
|
+
|
|
113
|
+
## Webhooks
|
|
114
|
+
|
|
115
|
+
Both webhook entry points need Switch 21.1+, the first release with `s.httpRequestSubscribe()`.
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
async function httpRequestTriggeredSync(request: HttpRequest, args: any[], response: HttpResponse, s: Switch): Promise<void>
|
|
119
|
+
```
|
|
120
|
+
Synchronous webhook handler. A response **must** be sent before the function returns. Registered via `s.httpRequestSubscribe()` in `flowStartTriggered`. Executes in concurrent mode. Request body limit: 1 MB (HTTP 413). Queue limit: 10,000 pending requests (HTTP 429). Execution timeout: 1 minute (HTTP 524). Default response if none set: HTTP 200 with `{"status": true}`.
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
async function httpRequestTriggeredAsync(request: HttpRequest, args: any[], s: Switch, flowElement: FlowElement): Promise<void>
|
|
124
|
+
```
|
|
125
|
+
Asynchronous webhook handler. No response is required. Registered via `s.httpRequestSubscribe()` in `flowStartTriggered`. Only invoked if `httpRequestTriggeredSync` is not defined, or if the sync handler returned a 2xx status.
|
|
126
|
+
|
|
127
|
+
## Script expression
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
async function calculateScriptExpression(s: Switch, flowElement: FlowElement, job: Job): Promise<string | number | boolean>
|
|
131
|
+
```
|
|
132
|
+
Called to evaluate a script expression for the flow element. The return value is used as the expression result.
|
|
133
|
+
|
|
134
|
+
## Property UI callbacks
|
|
135
|
+
|
|
136
|
+
Not available for debugging.
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
async function getLibraryForProperty(s: Switch, flowElement: FlowElement, tag: string): Promise<string[]>
|
|
140
|
+
```
|
|
141
|
+
Returns a dynamic list of values for a property's library dropdown. Mandatory if any property uses
|
|
142
|
+
the `askplugin`/`askplugin2` editor (see
|
|
143
|
+
[property-editors.md](../switch-project/property-editors.md#modal-editors)). Log an error via `flowElement.log()`
|
|
144
|
+
if the list would otherwise come back empty, so the user can see why the dropdown has nothing in it.
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
async function getLibraryForConnectionProperty(s: Switch, flowElement: FlowElement, c: Connection, tag: string): Promise<string[]>
|
|
148
|
+
```
|
|
149
|
+
Returns a dynamic list of values for a connection property's library dropdown. Same guidance as
|
|
150
|
+
`getLibraryForProperty` above, for connection fields using `askplugin`/`askplugin2`.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
async function validateProperties(s: Switch, flowElement: FlowElement, tags: string[]): Promise<{ tag: string, valid: boolean }[]>
|
|
154
|
+
```
|
|
155
|
+
Validates one or more property values. Return one result object per tag. Mandatory if any property
|
|
156
|
+
declares `Validation="Custom"` or `"Standard and custom"` (see
|
|
157
|
+
[script-declaration.md](../switch-project/script-declaration.md#custom-property-elements-elementfields)). Log
|
|
158
|
+
an error via `flowElement.log()` for any tag returned with `valid: false`, so the user sees why.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
async function validateConnectionProperties(s: Switch, flowElement: FlowElement, c: Connection, tags: string[]): Promise<{ tag: string, valid: boolean }[]>
|
|
162
|
+
```
|
|
163
|
+
Validates one or more connection property values. Same guidance as `validateProperties` above, for
|
|
164
|
+
connection fields declaring `Validation="Custom"`/`"Standard and custom"`.
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
async function findExternalEditorPath(s: Switch, flowElement: FlowElement, tag: string): Promise<string>
|
|
168
|
+
```
|
|
169
|
+
Resolves the path to an external editor for a property. Required whenever the
|
|
170
|
+
`external`/`external2`/… editor is used, unless the dependent `Application` property is non-empty —
|
|
171
|
+
see [property-editors.md § Notes](../switch-project/property-editors.md#notes).
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: enums
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 8
|
|
5
|
+
summary: "All enums with string values (`LogLevel`, `AccessLevel`, `DatasetModel`, `Scope`, `Priority`, `Connection.Level`, etc.)"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Looking up enum values"
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# Switch Scripting Enums
|
|
2
11
|
|
|
3
|
-
All enums are available globally in `main.ts`. They are also accessible via `EnfocusSwitch.*` when used outside `main.ts` (e.g. in imported modules).
|
|
12
|
+
All enums are available globally in `main.ts`. They are also accessible via `EnfocusSwitch.*` when used outside `main.ts` (e.g. in imported modules). Enums and values without a Switch version below exist in every Switch version with Node.js scripting; see [api-versions.md](api-versions.md).
|
|
4
13
|
|
|
5
14
|
## LogLevel
|
|
6
15
|
|
|
@@ -11,7 +20,7 @@ Used with `job.log()` and `flowElement.log()`.
|
|
|
11
20
|
| `LogLevel.Info` | `"info"` |
|
|
12
21
|
| `LogLevel.Warning` | `"warning"` |
|
|
13
22
|
| `LogLevel.Error` | `"error"` |
|
|
14
|
-
| `LogLevel.Debug` | `"debug"` |
|
|
23
|
+
| `LogLevel.Debug` | `"debug"` (Switch 21.0+) |
|
|
15
24
|
|
|
16
25
|
## AccessLevel
|
|
17
26
|
|
|
@@ -32,7 +41,7 @@ Used with `job.createDataset()`, `job.sendToLog()`, and `job.listDatasets()`.
|
|
|
32
41
|
| `DatasetModel.XML` | `"XML"` |
|
|
33
42
|
| `DatasetModel.XMP` | `"XMP"` |
|
|
34
43
|
| `DatasetModel.JDF` | `"JDF"` |
|
|
35
|
-
| `DatasetModel.JSON` | `"JSON"` |
|
|
44
|
+
| `DatasetModel.JSON` | `"JSON"` (Switch 22.0+) |
|
|
36
45
|
|
|
37
46
|
## Scope
|
|
38
47
|
|
|
@@ -41,14 +50,14 @@ Used with `s.getGlobalData()`, `s.setGlobalData()`, `s.removeGlobalData()`.
|
|
|
41
50
|
| Value | String |
|
|
42
51
|
|---|---|
|
|
43
52
|
| `Scope.Element` | `"element"` |
|
|
44
|
-
| `Scope.Flow` | `"flow"` |
|
|
53
|
+
| `Scope.Flow` | `"flow"` (Switch 22.0+) |
|
|
45
54
|
| `Scope.FlowElement` | `"flowElement"` |
|
|
46
|
-
| `Scope.FlowElements` | `"flowElements"` |
|
|
55
|
+
| `Scope.FlowElements` | `"flowElements"` (Switch 22.0+) |
|
|
47
56
|
| `Scope.Global` | `"global"` |
|
|
48
57
|
|
|
49
58
|
## Priority
|
|
50
59
|
|
|
51
|
-
Used with `job.setPriority()` / `job.getPriority()`.
|
|
60
|
+
Used with `job.setPriority()` / `job.getPriority()`. Switch 22.1+.
|
|
52
61
|
|
|
53
62
|
| Value | Number |
|
|
54
63
|
|---|---|
|
|
@@ -68,11 +77,13 @@ Used with `job.sendToData()` and `job.sendToLog()` for traffic light connections
|
|
|
68
77
|
| `Connection.Level.Warning` | `"warning"` |
|
|
69
78
|
| `Connection.Level.Error` | `"error"` |
|
|
70
79
|
|
|
71
|
-
Also available as `EnfocusSwitch.Connection.Level.*` outside `main.ts`.
|
|
80
|
+
Also available as `EnfocusSwitch.Connection.Level.*` outside `main.ts`. It selects which level to
|
|
81
|
+
route to; it is not a property you can read back from a `Connection` object, see
|
|
82
|
+
[connection.md § Connection.Level enum](connection.md#connectionlevel-enum).
|
|
72
83
|
|
|
73
84
|
## HttpRequest.Method
|
|
74
85
|
|
|
75
|
-
Used with `s.httpRequestSubscribe()` and `s.httpRequestUnsubscribe()`.
|
|
86
|
+
Used with `s.httpRequestSubscribe()` and `s.httpRequestUnsubscribe()`. Switch 21.1+.
|
|
76
87
|
|
|
77
88
|
| Value | String |
|
|
78
89
|
|---|---|
|
|
@@ -103,7 +114,7 @@ Returned by `flowElement.getPropertyType()` and `connection.getPropertyType()`.
|
|
|
103
114
|
|
|
104
115
|
## NoYesListPropertyStringValue
|
|
105
116
|
|
|
106
|
-
Convenience for `Boolean`-typed properties returned as strings.
|
|
117
|
+
Convenience for `Boolean`-typed properties returned as strings. Switch 24.0+.
|
|
107
118
|
|
|
108
119
|
| Value | String |
|
|
109
120
|
|---|---|
|
|
@@ -112,7 +123,7 @@ Convenience for `Boolean`-typed properties returned as strings.
|
|
|
112
123
|
|
|
113
124
|
## EnfocusSwitchPrivateDataTag
|
|
114
125
|
|
|
115
|
-
Well-known tags for `job.getPrivateData()` / `job.setPrivateData()`.
|
|
126
|
+
Well-known tags for `job.getPrivateData()` / `job.setPrivateData()`. The enum needs Switch 21.0+; `initiated` and `submittedTo` need 21.1+, and `state` needs 22.1+.
|
|
116
127
|
|
|
117
128
|
| Value | String |
|
|
118
129
|
|---|---|
|
|
@@ -129,7 +140,7 @@ Well-known tags for `job.getPrivateData()` / `job.setPrivateData()`.
|
|
|
129
140
|
|
|
130
141
|
## ImageDocument.ColorMode
|
|
131
142
|
|
|
132
|
-
Used with `ImageDocument.getColorMode()`. Available as `EnfocusSwitch.ImageDocument.ColorMode.*` outside `main.ts`.
|
|
143
|
+
Used with `ImageDocument.getColorMode()`. Available as `EnfocusSwitch.ImageDocument.ColorMode.*` outside `main.ts`. Switch 21.1+.
|
|
133
144
|
|
|
134
145
|
| Value | String |
|
|
135
146
|
|---|---|
|
|
@@ -145,7 +156,7 @@ Used with `ImageDocument.getColorMode()`. Available as `EnfocusSwitch.ImageDocum
|
|
|
145
156
|
|
|
146
157
|
## ImageDocument.ColorSpace
|
|
147
158
|
|
|
148
|
-
Used with `ImageDocument.getColorSpace()`. Available as `EnfocusSwitch.ImageDocument.ColorSpace.*` outside `main.ts`.
|
|
159
|
+
Used with `ImageDocument.getColorSpace()`. Available as `EnfocusSwitch.ImageDocument.ColorSpace.*` outside `main.ts`. Switch 21.1+.
|
|
149
160
|
|
|
150
161
|
| Value | String |
|
|
151
162
|
|---|---|
|
|
@@ -1,13 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: execution-environment
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 17
|
|
5
|
+
summary: "Execution modes (`Concurrent`/`Serialized`, `ExecutionGroup`, `NumberOfSlots`), process/concurrency model, state persistence across job invocations, unhandled-rejection behavior, npm/native module constraints"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Choosing or changing an execution mode, relying on module-level state across jobs, handling errors/rejections, or using third-party npm packages"
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# Execution Environment
|
|
2
11
|
|
|
3
|
-
How the Node.js process a script runs in behaves, beyond the entry point API itself.
|
|
4
|
-
consequences of the host process model
|
|
5
|
-
subtle bugs around state persistence and error handling.
|
|
12
|
+
How the Node.js process a script runs in behaves, beyond the entry point API itself. Apart from the
|
|
13
|
+
execution mode below, these are consequences of the host process model rather than things a script
|
|
14
|
+
configures — understanding them avoids subtle bugs around state persistence and error handling.
|
|
15
|
+
|
|
16
|
+
## Execution modes
|
|
17
|
+
|
|
18
|
+
Set in the XML declaration via SwitchScripter, or by editing it directly (see
|
|
19
|
+
[script-declaration.md](../switch-project/script-declaration.md#built-in-elementfields)). Applies to all
|
|
20
|
+
instances of the script.
|
|
21
|
+
|
|
22
|
+
**Concurrent** — entry points for the same or different instances may run in parallel. Scripts must
|
|
23
|
+
synchronize access to any shared resources. `NumberOfSlots` is only meaningful in this mode.
|
|
24
|
+
|
|
25
|
+
**Serialized** — entry points within the same **execution group** are never concurrent. Instances
|
|
26
|
+
in different execution groups may still run in parallel.
|
|
27
|
+
|
|
28
|
+
**Execution group** — only relevant for Serialized mode. Should be a reverse-domain string (e.g.
|
|
29
|
+
`com.mycompany.myScript`) to avoid collisions. Defaults to the Script ID if left empty.
|
|
30
|
+
|
|
31
|
+
Neither setting maps to a count of Node.js OS processes — see below.
|
|
6
32
|
|
|
7
33
|
## Two independent concurrency tiers
|
|
8
34
|
|
|
9
|
-
`NumberOfSlots`/`ExecutionGroup` (
|
|
10
|
-
[Execution modes](api-script-structure.md#execution-modes)) and the pool of Node.js processes that
|
|
35
|
+
`NumberOfSlots`/`ExecutionGroup` (above) and the pool of Node.js processes that
|
|
11
36
|
actually run script code are governed completely separately — there is no one-to-one mapping between
|
|
12
37
|
them:
|
|
13
38
|
|
|
@@ -23,7 +48,7 @@ them:
|
|
|
23
48
|
whichever pooled executor is free (or a new one is spawned if none are); executors are reused
|
|
24
49
|
across many jobs and across different flow elements running the same Node.js version, until
|
|
25
50
|
recycled (see
|
|
26
|
-
[Executor cleanup thresholds](
|
|
51
|
+
[Executor cleanup thresholds](job-patterns.md#executor-cleanup-thresholds)).
|
|
27
52
|
|
|
28
53
|
## Module-level state persists across jobs on the same executor
|
|
29
54
|
|
|
@@ -46,25 +71,27 @@ underlying executor process is **not** killed and continues serving subsequent j
|
|
|
46
71
|
including for other flow elements pooled onto the same executor. Don't rely on an unhandled
|
|
47
72
|
rejection to surface as a hard failure of the whole executor; always catch and handle errors
|
|
48
73
|
explicitly (e.g. via `job.fail()`/`flowElement.failProcess()` — see
|
|
49
|
-
[
|
|
74
|
+
[logging.md](logging.md)) rather than letting a promise reject unhandled.
|
|
50
75
|
|
|
51
76
|
## Third-party npm modules: file-based scripts only
|
|
52
77
|
|
|
53
78
|
A script **expression** (entered inline in a flow element property, not a file-based script/app —
|
|
54
|
-
see [Script expression](
|
|
79
|
+
see [Script expression](entry-points.md#script-expression)) cannot use third-party npm modules
|
|
55
80
|
at all; only Node.js built-ins are available via `require`. A file-based script/app can use
|
|
56
81
|
third-party modules from its own `node_modules` folder (see
|
|
57
|
-
[Script folder files](
|
|
82
|
+
[Script folder files](../switch-project/script-structure.md#script-folder-files)).
|
|
58
83
|
|
|
59
84
|
## Native (binary) addons are not supported
|
|
60
85
|
|
|
61
|
-
Scripts with ESM dependencies are bundled before execution
|
|
86
|
+
Scripts with ESM dependencies are bundled before execution, when `SwitchVersion` in `manifest.xml`
|
|
87
|
+
is `24.0` or higher (see
|
|
88
|
+
[script-structure.md § Other effects of `SwitchVersion`](../switch-project/script-structure.md#other-effects-of-switchversion)); this bundling path does not support
|
|
62
89
|
native/binary Node addons (`.node` files). Stick to pure-JavaScript/TypeScript dependencies.
|
|
63
90
|
|
|
64
91
|
## No explicit CPU or memory cap beyond the documented thresholds
|
|
65
92
|
|
|
66
93
|
Beyond the entry-point abort timeout and executor recycling thresholds already documented (see
|
|
67
|
-
[Job processing](
|
|
68
|
-
[Executor cleanup thresholds](
|
|
94
|
+
[Job processing](entry-points.md#job-processing) and
|
|
95
|
+
[Executor cleanup thresholds](job-patterns.md#executor-cleanup-thresholds)), there is no
|
|
69
96
|
additional CPU-time or memory limit enforced on a script's own code. A runaway loop or leak is
|
|
70
97
|
bounded only by those thresholds, not stopped proactively.
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: flow-element
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 4
|
|
5
|
+
summary: "`FlowElement`: properties, connections, job creation, logging"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Reading properties, creating jobs, logging, connections"
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# FlowElement Class
|
|
2
11
|
|
|
3
12
|
The `FlowElement` instance `flowElement` is passed to every entry point that operates on a flow element. It provides access to properties, connections, job creation, and logging.
|
|
@@ -5,11 +14,13 @@ The `FlowElement` instance `flowElement` is passed to every entry point that ope
|
|
|
5
14
|
## Identity
|
|
6
15
|
|
|
7
16
|
```ts
|
|
17
|
+
// Switch 21.1+
|
|
8
18
|
flowElement.getName(): string
|
|
9
19
|
```
|
|
10
20
|
Returns the name of this flow element.
|
|
11
21
|
|
|
12
22
|
```ts
|
|
23
|
+
// Switch 22.0+
|
|
13
24
|
flowElement.getFlowName(): string
|
|
14
25
|
```
|
|
15
26
|
Returns the name of the flow containing this element.
|
|
@@ -21,11 +32,11 @@ Properties are configured by the user in the Switch canvas and declared in the s
|
|
|
21
32
|
```ts
|
|
22
33
|
flowElement.getPropertyStringValue(tag: string): Promise<string | string[]>
|
|
23
34
|
```
|
|
24
|
-
Returns the property value as a string (or array for multi-value properties). For `OAuthToken` properties, returns a valid refreshed token. Throws `"Invalid tag: <tag>"` if the tag is unknown or a hidden dependent property. See [
|
|
35
|
+
Returns the property value as a string (or array for multi-value properties). For `OAuthToken` properties, returns a valid refreshed token. Throws `"Invalid tag: <tag>"` if the tag is unknown **or if it's a `Dependency` dependent currently hidden by its master's value** — see [script-declaration.md § Dependency](../switch-project/script-declaration.md#custom-property-elements-elementfields). Before fetching a dependent property, confirm its condition holds (from the already-read master value, or via `hasProperty(tag)` below) rather than fetching it unconditionally. See [property-editors.md](../switch-project/property-editors.md) for editor types and their return value formats.
|
|
25
36
|
|
|
26
37
|
> **Dynamic values (Switch variables and script expressions) are only resolved when `getPropertyStringValue()` is called from `jobArrived`.** In any other entry point (e.g. `timerFired`) the raw unresolved string is returned.
|
|
27
38
|
>
|
|
28
|
-
> **Workaround for deferred processing:** Read property values in `jobArrived` and store them with `s.setGlobalData()`. In `timerFired`, retrieve the stored values and fetch the waiting jobs with `flowElement.getJobs(ids)
|
|
39
|
+
> **Workaround for deferred processing:** Read property values in `jobArrived` and store them with `s.setGlobalData()`. In `timerFired`, retrieve the stored values and fetch the waiting jobs with `flowElement.getJobs(ids)` (Switch 21.0+).
|
|
29
40
|
|
|
30
41
|
```ts
|
|
31
42
|
flowElement.getPropertyType(tag: string): PropertyType
|
|
@@ -40,7 +51,7 @@ Returns the English display name of the property (for use in log messages).
|
|
|
40
51
|
```ts
|
|
41
52
|
flowElement.hasProperty(tag: string): boolean
|
|
42
53
|
```
|
|
43
|
-
Returns `true` if the property exists and is visible for the current configuration.
|
|
54
|
+
Returns `true` if the property exists and is visible for the current configuration. Use this to guard `getPropertyStringValue(tag)` calls on `Dependency` dependents — see the note above.
|
|
44
55
|
|
|
45
56
|
## Connections
|
|
46
57
|
|
|
@@ -58,7 +69,7 @@ Sets the interval between `timerFired` invocations. Default is 300 s. The actual
|
|
|
58
69
|
|
|
59
70
|
## Logging
|
|
60
71
|
|
|
61
|
-
See [
|
|
72
|
+
See [logging.md](logging.md) for log level semantics and logging practice.
|
|
62
73
|
|
|
63
74
|
```ts
|
|
64
75
|
flowElement.log(level: LogLevel, message: string, messageParams?: (string | number | boolean)[]): Promise<void>
|
|
@@ -68,16 +79,17 @@ Logs a message for the flow element. Use `%1`, `%2`, etc. in the message string
|
|
|
68
79
|
```ts
|
|
69
80
|
flowElement.failProcess(message: string, messageParam?: string | number | boolean): void
|
|
70
81
|
```
|
|
71
|
-
Logs a fatal error and puts the element into the "problem process" state. `messageParam` substitutes `%1
|
|
82
|
+
Logs a fatal error and puts the element into the "problem process" state. `messageParam` substitutes `%1`; before Switch 22.1, always pass it, as a string (see [api-versions.md](api-versions.md#declaration-changes-to-existing-methods)). Throws `"Job routing is not allowed in this entry point."` if called from an entry point where routing isn't permitted.
|
|
72
83
|
|
|
73
84
|
## Job creation (jobArrived / timerFired)
|
|
74
85
|
|
|
75
86
|
```ts
|
|
76
87
|
flowElement.createJob(path: string): Promise<Job>
|
|
77
88
|
```
|
|
78
|
-
Creates a new job from an existing file/folder path. Valid only in `jobArrived` and `timerFired`. The new job has default properties (no parent). The caller is responsible for cleaning up the source file after routing. See [
|
|
89
|
+
Creates a new job from an existing file/folder path. Valid only in `jobArrived` and `timerFired`. The new job has default properties (no parent). The caller is responsible for cleaning up the source file after routing. See [job-patterns.md](job-patterns.md#temp-file-cleanup) for temp file cleanup rules and [job-patterns.md](job-patterns.md#sending-jobs) for routing constraints.
|
|
79
90
|
|
|
80
91
|
```ts
|
|
92
|
+
// Switch 21.0+
|
|
81
93
|
flowElement.getJobs(ids: string[]): Promise<Job[]>
|
|
82
94
|
```
|
|
83
95
|
Returns up to 10,000 waiting jobs by ID. Throws if `ids` is not an array, is empty, or exceeds 10,000 entries. Call at most once per entry point. Not available in concurrent `jobArrived`. Private data and metadata of returned jobs cannot be read in the same invocation.
|
|
@@ -85,6 +97,7 @@ Returns up to 10,000 waiting jobs by ID. Throws if `ids` is not an array, is emp
|
|
|
85
97
|
## Channels
|
|
86
98
|
|
|
87
99
|
```ts
|
|
100
|
+
// Switch 22.1+
|
|
88
101
|
flowElement.subscribeToChannel(channelId: string, backingFolderPath: string): void
|
|
89
102
|
```
|
|
90
103
|
Subscribes to a channel to receive jobs from it. Only one subscriber per channel at a time. Must be called inside `flowStartTriggered`.
|
|
@@ -92,16 +105,19 @@ Subscribes to a channel to receive jobs from it. Only one subscriber per channel
|
|
|
92
105
|
## Utilities
|
|
93
106
|
|
|
94
107
|
```ts
|
|
108
|
+
// Switch 24.0+
|
|
95
109
|
flowElement.createPathWithName(name: string, createFolder: boolean): Promise<any>
|
|
96
110
|
```
|
|
97
|
-
Creates a temporary path (optionally as a folder — `createFolder` is required, not optional). Returns an empty string only if creating the folder throws (e.g. a permissions error); it does not check whether the path already exists first.
|
|
111
|
+
Creates a temporary path (optionally as a folder — `createFolder` is required, not optional). Returns an empty string only if creating the folder throws (e.g. a permissions error); it does not check whether the path already exists first. This is the recommended way to create temp files — see [job-patterns.md](job-patterns.md#temp-file-cleanup) for cleanup rules, including why this method should be preferred over ad hoc temp-file approaches like the `tmp` npm package.
|
|
98
112
|
|
|
99
113
|
```ts
|
|
114
|
+
// Switch 24.1+
|
|
100
115
|
flowElement.getFileCount(nested?: boolean): Promise<number>
|
|
101
116
|
```
|
|
102
117
|
Returns the number of files in the active flow. If `nested` is `false`, counts only direct children; if `true` (the default, so it can be omitted), counts recursively (folders themselves are not counted).
|
|
103
118
|
|
|
104
119
|
```ts
|
|
120
|
+
// Switch 24.0+
|
|
105
121
|
flowElement.getScriptDataPath(): string
|
|
106
122
|
```
|
|
107
123
|
Returns the path to the ScriptData folder for this element.
|
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: http
|
|
3
|
+
category: switch-api
|
|
4
|
+
order: 7
|
|
5
|
+
summary: "`HttpRequest` / `HttpResponse` + webhook pattern"
|
|
6
|
+
triggers:
|
|
7
|
+
- "Handling incoming HTTP webhooks"
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# HttpRequest & HttpResponse Classes
|
|
2
11
|
|
|
3
|
-
Used in the `httpRequestTriggeredSync` and `httpRequestTriggeredAsync` entry points. Webhook subscriptions are registered via `s.httpRequestSubscribe()` in `flowStartTriggered`.
|
|
12
|
+
Used in the `httpRequestTriggeredSync` and `httpRequestTriggeredAsync` entry points. Webhook subscriptions are registered via `s.httpRequestSubscribe()` in `flowStartTriggered`. Both classes, `HttpRequest.Method`, and the subscribe methods need Switch 21.1+.
|
|
4
13
|
|
|
5
14
|
## HttpRequest
|
|
6
15
|
|