@oddington/sdk 0.1.19 → 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 +87 -63
- package/dist/browser.js +584 -474
- 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/app-routine-contract.d.ts +1 -0
- package/dist/types/shared/inbox-contract.d.ts +5 -1
- package/dist/types/shared/inbox-member-contract.d.ts +2 -2
- package/dist/types/shared/inbox-member-types.d.ts +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,9 +12,16 @@ same key and content returns the original result; changed content conflicts.
|
|
|
12
12
|
Existing Inbox-retained files remain separate from shared Files, with their
|
|
13
13
|
original identities, bytes and audience. The SDK exposes no raw-credential API.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
Hosted apps use `inbox.questions.list({ routines })` for `AnswerableQuestion[]`.
|
|
16
|
+
Derive `routines` from the existing app declaration with
|
|
17
|
+
`[...new Set(Object.values(appDeclaration.routines).map(binding => binding.routine))]`.
|
|
18
|
+
These inner canonical names narrow relevance only; they grant no answer or
|
|
19
|
+
Record-search authority. The ordinary authenticated Inbox context needs no app
|
|
20
|
+
identity or declaration provisioning. The filter is required; `[]` returns no
|
|
21
|
+
Questions after authentication. The SDK validates and privately snapshots the
|
|
22
|
+
filter across pagination. Local apps use `inbox.questions.list()` instead, bound
|
|
23
|
+
to their trusted host's declaration; any supplied filter is invalid locally.
|
|
24
|
+
Both use the same answer and Record-search methods, without a filter or prior list.
|
|
18
25
|
`InboxItem` remains the complete first-party Inbox value. Record refs are placement
|
|
19
26
|
hints only: match them against independently authorized Data, and omit ambiguous
|
|
20
27
|
detail placement. Keep drafts on failed or uncertain acceptance, prevent duplicate
|
|
@@ -26,39 +33,71 @@ interaction duties belong to the consuming app's interface.
|
|
|
26
33
|
npm install @oddington/sdk
|
|
27
34
|
```
|
|
28
35
|
|
|
29
|
-
An authored routine exports an inert definition from
|
|
36
|
+
An authored routine exports an inert definition from `routines/<directory>/routine.ts`:
|
|
30
37
|
|
|
31
38
|
```ts
|
|
32
39
|
import { defineRoutine, file, schema } from '@oddington/sdk';
|
|
33
40
|
|
|
34
41
|
export default defineRoutine({
|
|
42
|
+
id: 'invoice-import',
|
|
35
43
|
input: schema.object({ document: file() }),
|
|
36
|
-
|
|
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
|
+
},
|
|
37
54
|
result: schema.object({ recordsCreated: schema.integer() }),
|
|
38
55
|
async run(input, os) {
|
|
39
|
-
await os.step('read');
|
|
40
|
-
|
|
41
|
-
// Perform customer-owned work with the supplied installed capabilities.
|
|
42
|
-
return { recordsCreated: 1 };
|
|
56
|
+
await os.step('read', input);
|
|
57
|
+
return { recordsCreated: 0 };
|
|
43
58
|
},
|
|
44
59
|
});
|
|
45
60
|
```
|
|
46
61
|
|
|
47
|
-
Importing or defining performs no business work. Input
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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;
|
|
51
71
|
the trusted launcher separately verifies current File-use authority. The supplied
|
|
52
72
|
runtime contains `run.id`, `data`, `files`, `connections`, `inbox`, and `step`.
|
|
53
|
-
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.
|
|
54
78
|
|
|
55
79
|
The bounded grammar supports closed objects with required properties, arrays with
|
|
56
80
|
an explicit `maxItems` from 1 to 64, booleans, strings (at most 4096 code points),
|
|
57
81
|
finite numbers and safe integers with optional inclusive bounds, and Files.
|
|
58
82
|
Definitions allow at most 64 steps, 64 total object properties across their schemas,
|
|
59
|
-
and eight schema levels. Input, each
|
|
60
|
-
|
|
61
|
-
|
|
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.
|
|
62
101
|
|
|
63
102
|
The named CLI local launcher requires native Node TypeScript stripping and a
|
|
64
103
|
module `routines/package.json` whose `engines.node` range matches that executable.
|
|
@@ -188,63 +227,48 @@ changed local context fails closed, as do sign-out and initialization replacemen
|
|
|
188
227
|
Local Data selects from the Host's exact published index; a warm selection
|
|
189
228
|
neither initiates nor waits for renewal or synchronous hosted authority checks.
|
|
190
229
|
Local Files returns `unsupported_context` after checking context. Neither path
|
|
191
|
-
falls back to hosted services. Local app
|
|
192
|
-
|
|
230
|
+
falls back to hosted services. Local app routines use the same local execution
|
|
231
|
+
and explicit publication lifecycle as the CLI.
|
|
193
232
|
|
|
194
233
|
Apps can assess a declared routine without starting it:
|
|
195
234
|
|
|
196
235
|
```ts
|
|
197
|
-
import { app
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
const status = await app.routines.reconcile.availability();
|
|
210
|
-
if (status.available) {
|
|
211
|
-
const steps: ('read' | 'write')[] = status.steps;
|
|
212
|
-
}
|
|
213
|
-
const run = await app.routines.reconcile.run({ limit: 2 });
|
|
214
|
-
for await (const event of run.events()) {
|
|
215
|
-
if (event.type === 'step' && event.id === 'write') console.log(event.summary.changed);
|
|
216
|
-
if (event.type === 'finished' && event.state === 'succeeded') console.log(event.result.processed);
|
|
217
|
-
}
|
|
218
|
-
// After refresh or reopening the same live origin:
|
|
219
|
-
const recovered = await app.routines.reconcile.recover();
|
|
220
|
-
// 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.
|
|
221
248
|
```
|
|
222
249
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
cancellation requests do not acknowledge cancellation. Handles expose no IDs,
|
|
238
|
-
cursors, raw output or process controls. Local sign-out, expiry, context
|
|
239
|
-
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.
|
|
240
264
|
|
|
241
265
|
The exact-origin browser credential survives document disposal, reload and tab
|
|
242
266
|
closure in local storage. Disposal rejects the outgoing document's pending
|
|
243
267
|
operations and disconnects its Run handles without cancelling the host-owned
|
|
244
268
|
child. Fresh initialization at the same live Local Host origin can call the
|
|
245
|
-
declared operation's `
|
|
246
|
-
|
|
247
|
-
|
|
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.
|
|
248
272
|
|
|
249
273
|
Each active initialization proactively renews before expiry, normally
|
|
250
274
|
sixty seconds early with a shorter lead for shorter lifetimes. Only the exact
|