@oddington/sdk 0.1.20 → 0.1.21
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 +77 -60
- package/dist/browser.js +562 -463
- package/dist/index.js +6 -6
- package/dist/types/packages/sdk/src/public.d.ts +87 -35
- package/dist/types/packages/sdk/src/routine-definition-types.d.ts +53 -19
- package/dist/types/shared/app-descriptor.d.ts +21 -0
- package/dist/types/shared/inbox-contract.d.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,39 +33,71 @@ interaction duties belong to the consuming app's interface.
|
|
|
33
33
|
npm install @oddington/sdk
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
An authored routine exports an inert definition from
|
|
36
|
+
An authored routine exports an inert definition from `routines/<directory>/routine.ts`:
|
|
37
37
|
|
|
38
38
|
```ts
|
|
39
39
|
import { defineRoutine, file, schema } from '@oddington/sdk';
|
|
40
40
|
|
|
41
41
|
export default defineRoutine({
|
|
42
|
+
id: 'invoice-import',
|
|
42
43
|
input: schema.object({ document: file() }),
|
|
43
|
-
|
|
44
|
+
access: { files: 'read' },
|
|
45
|
+
steps: {
|
|
46
|
+
read: {
|
|
47
|
+
title: 'Read receipt',
|
|
48
|
+
async run(input: { document: import('@oddington/sdk').File }, os) {
|
|
49
|
+
const response = await os.files.read(input.document.id);
|
|
50
|
+
return { summary: { files: 1 }, data: { text: await response.text() } };
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
44
54
|
result: schema.object({ recordsCreated: schema.integer() }),
|
|
45
55
|
async run(input, os) {
|
|
46
|
-
await os.step('read');
|
|
47
|
-
|
|
48
|
-
// Perform customer-owned work with the supplied installed capabilities.
|
|
49
|
-
return { recordsCreated: 1 };
|
|
56
|
+
await os.step('read', input);
|
|
57
|
+
return { recordsCreated: 0 };
|
|
50
58
|
},
|
|
51
59
|
});
|
|
52
60
|
```
|
|
53
61
|
|
|
54
|
-
Importing or defining performs no business work. Input
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
62
|
+
Importing or defining performs no business work. Input and result use bounded
|
|
63
|
+
schemas; step inputs, summaries and detail are inferred from executable functions.
|
|
64
|
+
Each step runs at most once and returns `{ summary, data }`. Unknown or repeated
|
|
65
|
+
steps fail the Run even if routine code catches the error; unreached steps are
|
|
66
|
+
skipped. Omitted input normalizes to `{}`. A top-level schema can supply a validated
|
|
67
|
+
immutable default with `.default(value)`, such as
|
|
68
|
+
`schema.object({ files: schema.array(file(), { maxItems: 32 }) }).default({ files: [] })`.
|
|
69
|
+
Nested defaults are unsupported and rejected. Omitted steps permit no step call;
|
|
70
|
+
omitted result permits no returned value. `file()` declares a complete OS File descriptor;
|
|
58
71
|
the trusted launcher separately verifies current File-use authority. The supplied
|
|
59
72
|
runtime contains `run.id`, `data`, `files`, `connections`, `inbox`, and `step`.
|
|
60
|
-
Accepted input and
|
|
73
|
+
Accepted input and saved values are immutable snapshots. Access declarations set
|
|
74
|
+
maximum named capabilities and grant no authority; the trusted host checks current
|
|
75
|
+
authority. Response handler IDs are local to the routine and must be unique. A
|
|
76
|
+
declared `review` handler crosses the Inbox publication seam as
|
|
77
|
+
`invoice-import/review`, without deploying or executing that handler.
|
|
61
78
|
|
|
62
79
|
The bounded grammar supports closed objects with required properties, arrays with
|
|
63
80
|
an explicit `maxItems` from 1 to 64, booleans, strings (at most 4096 code points),
|
|
64
81
|
finite numbers and safe integers with optional inclusive bounds, and Files.
|
|
65
82
|
Definitions allow at most 64 steps, 64 total object properties across their schemas,
|
|
66
|
-
and eight schema levels. Input, each
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
and eight schema levels. Input, each step input, each summary, each detail value,
|
|
84
|
+
and the result accept at most 256 KiB of UTF-8 serialized JSON, without truncation.
|
|
85
|
+
Across 64 steps, retained summary plus detail is at most 32 MiB, plus 512 KiB for
|
|
86
|
+
Run input and result; step inputs are transient and individually bounded. Schema
|
|
87
|
+
defaults share the input bound. Titles contain at most 256 UTF-16 code units;
|
|
88
|
+
access dimensions and response handlers each have at most 64 entries. Functions,
|
|
89
|
+
accessors, sparse arrays, cycles and non-JSON values reject. The canonical routine
|
|
90
|
+
ID is a bounded lowercase alphanumeric/hyphen name, independent of its directory.
|
|
91
|
+
No entry, workspace, credentials or placement are authored in this definition.
|
|
92
|
+
|
|
93
|
+
Local Run history returns the newest 20 summaries per canonical routine, without
|
|
94
|
+
deleting older Runs or unpublished changes. Step titles and bounded summary/detail
|
|
95
|
+
values are saved with the accepted Run, so later source edits cannot rewrite them.
|
|
96
|
+
Each checkout-private execution/preparation JSON file has a 64 MiB total bound,
|
|
97
|
+
including private diagnostics; app summaries never include those diagnostics.
|
|
98
|
+
Publication reads the existing confirmed-receipt journal independently from the
|
|
99
|
+
successful execution status. Refresh reads materialized state; watching provides
|
|
100
|
+
connected updates without replay or interrupted-execution recovery.
|
|
69
101
|
|
|
70
102
|
The named CLI local launcher requires native Node TypeScript stripping and a
|
|
71
103
|
module `routines/package.json` whose `engines.node` range matches that executable.
|
|
@@ -195,63 +227,48 @@ changed local context fails closed, as do sign-out and initialization replacemen
|
|
|
195
227
|
Local Data selects from the Host's exact published index; a warm selection
|
|
196
228
|
neither initiates nor waits for renewal or synchronous hosted authority checks.
|
|
197
229
|
Local Files returns `unsupported_context` after checking context. Neither path
|
|
198
|
-
falls back to hosted services. Local app
|
|
199
|
-
|
|
230
|
+
falls back to hosted services. Local app routines use the same local execution
|
|
231
|
+
and explicit publication lifecycle as the CLI.
|
|
200
232
|
|
|
201
233
|
Apps can assess a declared routine without starting it:
|
|
202
234
|
|
|
203
235
|
```ts
|
|
204
|
-
import { app
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const status = await app.routines.reconcile.availability();
|
|
217
|
-
if (status.available) {
|
|
218
|
-
const steps: ('read' | 'write')[] = status.steps;
|
|
219
|
-
}
|
|
220
|
-
const run = await app.routines.reconcile.run({ limit: 2 });
|
|
221
|
-
for await (const event of run.events()) {
|
|
222
|
-
if (event.type === 'step' && event.id === 'write') console.log(event.summary.changed);
|
|
223
|
-
if (event.type === 'finished' && event.state === 'succeeded') console.log(event.result.processed);
|
|
224
|
-
}
|
|
225
|
-
// After refresh or reopening the same live origin:
|
|
226
|
-
const recovered = await app.routines.reconcile.recover();
|
|
227
|
-
// await recovered[0]?.cancel(); // Resolves only after host acknowledgement.
|
|
236
|
+
import { app } from '@oddington/sdk';
|
|
237
|
+
|
|
238
|
+
const routines = await app.listRoutines(); // Declaration order, including unavailable routines.
|
|
239
|
+
const description = await app.routines.receipts.describe();
|
|
240
|
+
const run = await app.routines.receipts.run(); // Uses the definition's default input.
|
|
241
|
+
for await (const state of run.watch()) console.log(state.status, state.steps);
|
|
242
|
+
const detail = await run.step('read'); // Inferred summary and data for this new Run.
|
|
243
|
+
// After refresh, under newly checked authority:
|
|
244
|
+
const recent = await app.routines.receipts.runs.list();
|
|
245
|
+
const saved = await app.routines.receipts.runs.get(recent[0].id);
|
|
246
|
+
console.log(await saved.current());
|
|
247
|
+
// await saved.publish(); // Only in response to an explicit publication action.
|
|
228
248
|
```
|
|
229
249
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
cancellation requests do not acknowledge cancellation. Handles expose no IDs,
|
|
245
|
-
cursors, raw output or process controls. Local sign-out, expiry, context
|
|
246
|
-
replacement, origin changes and unconfirmed credential changes invalidate pending work.
|
|
250
|
+
The fixed build generates types from each routine definition; no app-authored
|
|
251
|
+
contract map is needed. Descriptions combine safe structure with live readiness
|
|
252
|
+
and connection availability. Starts validate the current definition and input;
|
|
253
|
+
retained reads and publication recheck complete saved member/source/capability
|
|
254
|
+
scope. No installation is needed. Bindings accept no endpoint, credential,
|
|
255
|
+
command, path or configuration selector. Hosted declarations stay visible and
|
|
256
|
+
unavailable until hosted execution exists. Operations reject with
|
|
257
|
+
`AppRoutineError.reason`: `authority_unavailable`, `execution_unavailable`, or
|
|
258
|
+
`invalid_input`. Starts and publications are not automatically retried. A
|
|
259
|
+
disconnected watch ends and requires `current()`. History returns at most 20
|
|
260
|
+
summaries without deleting older Runs. Each JSON value is bounded to 256 KiB.
|
|
261
|
+
Transport envelopes allow 17 MiB per summary, 514 KiB per detail and 20 summaries
|
|
262
|
+
per list; execution retains at most 10 MiB of report evidence. Raw process
|
|
263
|
+
output and private authority stay private.
|
|
247
264
|
|
|
248
265
|
The exact-origin browser credential survives document disposal, reload and tab
|
|
249
266
|
closure in local storage. Disposal rejects the outgoing document's pending
|
|
250
267
|
operations and disconnects its Run handles without cancelling the host-owned
|
|
251
268
|
child. Fresh initialization at the same live Local Host origin can call the
|
|
252
|
-
declared operation's `
|
|
253
|
-
|
|
254
|
-
|
|
269
|
+
declared operation's `runs.get(id)` to read retained facts without launching it
|
|
270
|
+
again. Old handles remain invalid. Terminal facts and bounded step detail live
|
|
271
|
+
in the checkout's existing Run store; interrupted execution is not recovered.
|
|
255
272
|
|
|
256
273
|
Each active initialization proactively renews before expiry, normally
|
|
257
274
|
sixty seconds early with a shorter lead for shorter lifetimes. Only the exact
|