@ixo/oracle-runtime-workers 0.13.0 → 0.16.0
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 +32 -10
- package/package.json +13 -8
- package/src/artifacts/config.ts +158 -0
- package/src/artifacts/crypto.ts +94 -0
- package/src/artifacts/routes.ts +73 -0
- package/src/artifacts/store.ts +238 -0
- package/src/artifacts/sweep.ts +200 -0
- package/src/artifacts/tool.ts +103 -0
- package/src/artifacts/viewer-page.ts +614 -0
- package/src/attachments/download.ts +168 -45
- package/src/attachments/index.ts +9 -0
- package/src/attachments/magic.ts +33 -0
- package/src/attachments/pipeline.ts +105 -49
- package/src/attachments/sandbox-archive.ts +9 -8
- package/src/attachments/view-cache.ts +142 -0
- package/src/attachments/view.ts +53 -12
- package/src/channels/auth.ts +310 -0
- package/src/channels/contract.ts +246 -0
- package/src/channels/turns.ts +280 -0
- package/src/core/budgeted-llm.ts +223 -0
- package/src/core/capability-router.ts +273 -0
- package/src/core/context-budget.ts +97 -10
- package/src/core/env.ts +111 -0
- package/src/core/execution-profile.ts +17 -0
- package/src/core/index.ts +267 -9
- package/src/core/llm.ts +30 -9
- package/src/core/main-agent-types.ts +41 -1
- package/src/core/main-agent.ts +367 -65
- package/src/core/manifest.ts +34 -0
- package/src/core/meta-tools.ts +128 -18
- package/src/core/middlewares/capability-gate.ts +130 -12
- package/src/core/middlewares/context-guard.ts +55 -24
- package/src/core/middlewares/index.ts +20 -2
- package/src/core/middlewares/page-context.ts +46 -2
- package/src/core/middlewares/return-direct-first.ts +47 -0
- package/src/core/middlewares/summarization.ts +152 -10
- package/src/core/middlewares/tool-execution.ts +323 -0
- package/src/core/middlewares/tool-repetition-guard.ts +202 -35
- package/src/core/middlewares/turn-boundary.ts +162 -0
- package/src/core/openrouter-pricing.ts +155 -22
- package/src/core/prompt-composer.ts +112 -7
- package/src/core/registries.ts +253 -48
- package/src/core/request-admission.ts +159 -0
- package/src/core/runtime-context.ts +107 -8
- package/src/core/state.ts +1 -1
- package/src/core/sub-agent-fallback.ts +21 -2
- package/src/core/subagent-as-tool.ts +78 -43
- package/src/core/tool-access.ts +189 -0
- package/src/core/tool-scheduler.ts +125 -0
- package/src/core/turn-budget.ts +205 -0
- package/src/core/turn-time-note.ts +43 -0
- package/src/core/user-kv.ts +446 -0
- package/src/core/wrap-plugin-tool.ts +20 -0
- package/src/delivery/plan.ts +278 -0
- package/src/delivery/profile.ts +161 -0
- package/src/delivery/prompt.ts +27 -0
- package/src/delivery/schema.ts +61 -0
- package/src/delivery/shaper.ts +389 -0
- package/src/delivery/types.ts +84 -0
- package/src/do/ambient.ts +51 -15
- package/src/do/contracts.ts +170 -6
- package/src/do/idle-eviction.ts +38 -0
- package/src/do/matrix-turn-ledger.ts +24 -5
- package/src/do/result-store-test-do.ts +137 -3
- package/src/do/result-store.ts +239 -58
- package/src/do/room-mirror.ts +29 -0
- package/src/do/run-buffer.ts +64 -9
- package/src/do/run-coordinator.ts +451 -76
- package/src/do/run-request.ts +2 -0
- package/src/do/run-store-test-do.ts +301 -1
- package/src/do/run-store.ts +385 -43
- package/src/do/secrets-adapter.ts +22 -3
- package/src/do/sse-stream.ts +60 -9
- package/src/do/transcript.ts +48 -5
- package/src/do/turn-body.ts +105 -5
- package/src/do/ucan-service.ts +204 -34
- package/src/do/user-oracle-do.ts +2003 -274
- package/src/feedback/config.ts +127 -0
- package/src/feedback/contract.ts +148 -0
- package/src/feedback/linear-sink.ts +285 -0
- package/src/feedback/privacy.ts +150 -0
- package/src/feedback/reservation.ts +298 -0
- package/src/feedback/submit.ts +247 -0
- package/src/index.ts +138 -6
- package/src/llm/byo-adapter.ts +27 -6
- package/src/llm/byo-catalog.ts +13 -0
- package/src/llm/byo-model-fallback.ts +248 -0
- package/src/llm/byo-service.ts +45 -8
- package/src/llm/provider-error.ts +139 -2
- package/src/matrix/gateway-do.ts +504 -108
- package/src/matrix/group-chat.ts +66 -23
- package/src/matrix/inbox-store.ts +16 -1
- package/src/matrix/ingest.ts +79 -14
- package/src/matrix/media-deadline.ts +130 -0
- package/src/matrix/replay-format.ts +5 -3
- package/src/matrix/reply-parts.ts +92 -0
- package/src/matrix/room-alias.ts +96 -0
- package/src/matrix/user-homeserver.ts +166 -7
- package/src/owner-store/ixo-vfs-store.ts +170 -43
- package/src/owner-store/migrating-store.ts +31 -15
- package/src/owner-store/types.ts +18 -3
- package/src/plugin-api/index.ts +43 -2
- package/src/plugin-api/oracle-plugin.ts +35 -0
- package/src/plugin-api/request-admission.ts +41 -0
- package/src/plugin-api/tool-helper.ts +25 -1
- package/src/plugin-api/tool-plane.ts +92 -0
- package/src/plugin-api/types.ts +194 -6
- package/src/plugins/agui/agui.plugin.ts +31 -16
- package/src/plugins/composio/composio-tools.ts +57 -6
- package/src/plugins/composio/composio-ucan.ts +3 -2
- package/src/plugins/composio/composio.plugin.ts +2 -0
- package/src/plugins/delegated-capabilities.ts +25 -0
- package/src/plugins/editor/content-session.ts +173 -83
- package/src/plugins/editor/content-tools.ts +76 -17
- package/src/plugins/editor/editor-mx.ts +28 -9
- package/src/plugins/editor/editor.plugin.ts +3 -1
- package/src/plugins/editor/failures.ts +28 -7
- package/src/plugins/editor/prompts.ts +2 -1
- package/src/plugins/editor/provider.ts +553 -40
- package/src/plugins/editor/standalone-editor-tool.ts +61 -18
- package/src/plugins/firecrawl/firecrawl-tools.ts +13 -5
- package/src/plugins/flows/action-metadata.ts +111 -11
- package/src/plugins/flows/actions.ts +18 -0
- package/src/plugins/flows/decision-context.ts +31 -0
- package/src/plugins/flows/edit.ts +223 -52
- package/src/plugins/flows/errors.ts +22 -1
- package/src/plugins/flows/flow-doc.ts +92 -9
- package/src/plugins/flows/flows.plugin.ts +11 -5
- package/src/plugins/flows/forms.ts +34 -0
- package/src/plugins/flows/index.ts +2 -0
- package/src/plugins/flows/input-policy.ts +140 -0
- package/src/plugins/flows/prompts.ts +14 -11
- package/src/plugins/flows/read.ts +49 -9
- package/src/plugins/flows/ref-syntax.ts +129 -0
- package/src/plugins/flows/test-homeserver.ts +245 -0
- package/src/plugins/flows/tools/authoring.ts +216 -112
- package/src/plugins/flows/tools/discovery.ts +4 -1
- package/src/plugins/flows/tools/forms.ts +21 -2
- package/src/plugins/flows/tools/settings.ts +34 -13
- package/src/plugins/flows/translator.ts +13 -10
- package/src/plugins/flows/types.ts +167 -42
- package/src/plugins/index.ts +11 -1
- package/src/plugins/ixo-transaction/chain-ids.ts +43 -0
- package/src/plugins/ixo-transaction/index.ts +2 -0
- package/src/plugins/ixo-transaction/ixo-transaction.plugin.ts +119 -0
- package/src/plugins/ixo-transaction/receipts.ts +99 -0
- package/src/plugins/ixo-transaction/tools.ts +329 -0
- package/src/plugins/ixo-transaction/wallet-signing.ts +202 -0
- package/src/plugins/mcp-tool-adapter.ts +23 -2
- package/src/plugins/memory/memory-tools.ts +7 -2
- package/src/plugins/memory/memory-ucan.ts +3 -2
- package/src/plugins/memory/memory.plugin.ts +2 -0
- package/src/plugins/pod-creator/blueprint-store.ts +163 -0
- package/src/plugins/pod-creator/blueprint-types.ts +61 -0
- package/src/plugins/pod-creator/bounded-map.ts +87 -0
- package/src/plugins/pod-creator/capsule-content-client.ts +285 -0
- package/src/plugins/pod-creator/chain-gateway.ts +110 -0
- package/src/plugins/pod-creator/config.ts +85 -0
- package/src/plugins/pod-creator/create-session-store.ts +180 -0
- package/src/plugins/pod-creator/create-tools.ts +538 -0
- package/src/plugins/pod-creator/design-pod-roles.ts +111 -0
- package/src/plugins/pod-creator/index.ts +65 -0
- package/src/plugins/pod-creator/orchestration-tools.ts +172 -0
- package/src/plugins/pod-creator/pod-creator.plugin.ts +190 -0
- package/src/plugins/pod-creator/stage.ts +201 -0
- package/src/plugins/pod-creator/sub-agents.ts +189 -0
- package/src/plugins/portal/action-log.ts +21 -1
- package/src/plugins/portal/declared-tools.ts +90 -0
- package/src/plugins/portal/portal.plugin.ts +42 -16
- package/src/plugins/sandbox/sandbox-bridge.ts +79 -10
- package/src/plugins/sandbox/sandbox-mcp.ts +3 -2
- package/src/plugins/sandbox/sandbox-write-blob.ts +11 -1
- package/src/plugins/sandbox/sandbox.plugin.ts +8 -16
- package/src/plugins/tasks/manifest.ts +1 -1
- package/src/plugins/tasks/middleware.ts +20 -7
- package/src/plugins/tasks/tasks-tools.ts +30 -3
- package/src/plugins/tasks/tasks.plugin.ts +64 -11
- package/src/plugins/user-preferences/schema.ts +12 -1
- package/src/plugins/user-preferences/user-preferences-store.ts +38 -13
- package/src/plugins/user-preferences/user-preferences-tool.ts +3 -2
- package/src/plugins/vfs/vfs-client.ts +250 -71
- package/src/plugins/vfs/vfs-content.ts +30 -11
- package/src/plugins/vfs/vfs-errors.ts +22 -0
- package/src/plugins/vfs/vfs-sandbox-tools.ts +12 -5
- package/src/plugins/vfs/vfs-tools.ts +60 -20
- package/src/realtime/frontend-call-registry.ts +228 -81
- package/src/realtime/realtime-endpoint.ts +215 -44
- package/src/realtime/session-socket-hub.ts +47 -2
- package/src/secrets/secrets-service.ts +9 -3
- package/src/shell/app.ts +562 -82
- package/src/shell/auth.ts +131 -37
- package/src/shell/turn-body-cap.ts +11 -13
- package/src/sqlite/blob-compactor.ts +61 -28
- package/src/sqlite/database.ts +156 -90
- package/src/sqlite/do-vfs.ts +416 -129
- package/src/sqlite/page-tier.ts +133 -40
- package/src/sqlite/serialization.ts +40 -0
- package/src/sqlite/sessions-store.ts +10 -2
- package/src/sqlite/sqlite-saver.ts +139 -19
- package/src/sqlite/user-kv-store.ts +317 -0
- package/src/tasks/schedule.ts +201 -12
- package/src/tasks/scheduler.ts +586 -98
- package/src/tasks/spec.ts +67 -3
- package/src/tasks/store.ts +292 -27
- package/src/tasks/topic-deliverables.ts +70 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test support: an in-memory Matrix homeserver behind a real `matrix-js-sdk`
|
|
3
|
+
* client. The client's `fetchFn` is routed here, so matrix-crdt and the
|
|
4
|
+
* provider run their real code paths — join, backwards history walk, the
|
|
5
|
+
* `/events` long-poll, document-update sends — against rooms these tests
|
|
6
|
+
* control, and every request is counted. Not a `*.test.ts` file.
|
|
7
|
+
*
|
|
8
|
+
* Only the endpoints the document provider uses are implemented:
|
|
9
|
+
* POST /join/{room} → joins (always succeeds)
|
|
10
|
+
* GET /rooms/{room}/messages → the stored events, newest first
|
|
11
|
+
* GET /events → held open until aborted
|
|
12
|
+
* PUT /rooms/{room}/send/{type}/{txn} → stored, or the scripted failure
|
|
13
|
+
* GET /rooms/{room}/state/… → 404 M_NOT_FOUND
|
|
14
|
+
* Anything else answers 404 `M_UNRECOGNIZED` and is recorded.
|
|
15
|
+
*/
|
|
16
|
+
import { createClient, type MatrixClient } from 'matrix-js-sdk';
|
|
17
|
+
import * as Y from 'yjs';
|
|
18
|
+
|
|
19
|
+
export const TEST_HOMESERVER_URL = 'https://hs.test.example';
|
|
20
|
+
export const TEST_ORACLE_USER = '@oracle:test.example';
|
|
21
|
+
|
|
22
|
+
export interface StoredEvent {
|
|
23
|
+
event_id: string;
|
|
24
|
+
type: string;
|
|
25
|
+
room_id: string;
|
|
26
|
+
sender: string;
|
|
27
|
+
user_id: string;
|
|
28
|
+
origin_server_ts: number;
|
|
29
|
+
content: Record<string, unknown>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A scripted homeserver answer: `ok` stores the event; `network` fails the
|
|
34
|
+
* request with no HTTP answer; `hang` never answers (until aborted); else an
|
|
35
|
+
* error body.
|
|
36
|
+
*/
|
|
37
|
+
export type SendOutcome =
|
|
38
|
+
| 'ok'
|
|
39
|
+
| 'network'
|
|
40
|
+
| 'hang'
|
|
41
|
+
| {
|
|
42
|
+
status: number;
|
|
43
|
+
errcode: string;
|
|
44
|
+
error?: string;
|
|
45
|
+
retry_after_ms?: number;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export interface RecordedRequest {
|
|
49
|
+
method: string;
|
|
50
|
+
path: string;
|
|
51
|
+
at: number;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function json(status: number, body: unknown): Response {
|
|
55
|
+
return new Response(JSON.stringify(body), {
|
|
56
|
+
status,
|
|
57
|
+
headers: { 'content-type': 'application/json' },
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function encodeUpdate(update: Uint8Array): string {
|
|
62
|
+
let binary = '';
|
|
63
|
+
for (const byte of update) binary += String.fromCharCode(byte);
|
|
64
|
+
return btoa(binary);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class TestHomeserver {
|
|
68
|
+
readonly requests: RecordedRequest[] = [];
|
|
69
|
+
/** Events per room, oldest first. */
|
|
70
|
+
readonly rooms = new Map<string, StoredEvent[]>();
|
|
71
|
+
/** Answers for document-update sends, consumed in order; then `ok`. */
|
|
72
|
+
sendScript: SendOutcome[] = [];
|
|
73
|
+
/** When set, `/messages` answers this instead of the stored events. */
|
|
74
|
+
messagesFailure: { status: number; errcode: string } | undefined;
|
|
75
|
+
/** When set, `POST /join` answers this error. */
|
|
76
|
+
joinFailure: { status: number; errcode: string } | undefined;
|
|
77
|
+
/** One-off `/messages` failures, consumed in order before `messagesFailure`. */
|
|
78
|
+
messagesScript: Array<{ status: number; errcode: string }> = [];
|
|
79
|
+
/** `/events` long-polls currently held open. */
|
|
80
|
+
openPolls = 0;
|
|
81
|
+
/** Delays (ms) for successive `/messages` answers, consumed in order. */
|
|
82
|
+
messagesDelays: number[] = [];
|
|
83
|
+
|
|
84
|
+
private nextEventId = 1;
|
|
85
|
+
|
|
86
|
+
/** A fresh client bound to this homeserver. */
|
|
87
|
+
client(): MatrixClient {
|
|
88
|
+
return createClient({
|
|
89
|
+
baseUrl: TEST_HOMESERVER_URL,
|
|
90
|
+
accessToken: 'test-token',
|
|
91
|
+
userId: TEST_ORACLE_USER,
|
|
92
|
+
fetchFn: (input, init) => this.handle(input, init),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Store a Y.Doc's full state as one document-update event in `roomId`. */
|
|
97
|
+
seedDoc(roomId: string, doc: Y.Doc): void {
|
|
98
|
+
this.append(roomId, 'matrix-crdt.doc_update', {
|
|
99
|
+
update: encodeUpdate(Y.encodeStateAsUpdate(doc)),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** Rebuild the room's document from its stored update events. */
|
|
104
|
+
docOf(roomId: string): Y.Doc {
|
|
105
|
+
const doc = new Y.Doc();
|
|
106
|
+
for (const event of this.rooms.get(roomId) ?? []) {
|
|
107
|
+
const update = event.content.update;
|
|
108
|
+
if (typeof update !== 'string') continue;
|
|
109
|
+
const bytes = Uint8Array.from(atob(update), (c) => c.charCodeAt(0));
|
|
110
|
+
Y.applyUpdate(doc, bytes);
|
|
111
|
+
}
|
|
112
|
+
return doc;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
count(method: string, pathPart: string): number {
|
|
116
|
+
return this.requests.filter(
|
|
117
|
+
(r) => r.method === method && r.path.includes(pathPart),
|
|
118
|
+
).length;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private append(
|
|
122
|
+
roomId: string,
|
|
123
|
+
type: string,
|
|
124
|
+
content: Record<string, unknown>,
|
|
125
|
+
): StoredEvent {
|
|
126
|
+
const event: StoredEvent = {
|
|
127
|
+
event_id: `$e${this.nextEventId++}`,
|
|
128
|
+
type,
|
|
129
|
+
room_id: roomId,
|
|
130
|
+
sender: TEST_ORACLE_USER,
|
|
131
|
+
user_id: TEST_ORACLE_USER,
|
|
132
|
+
origin_server_ts: Date.now(),
|
|
133
|
+
content,
|
|
134
|
+
};
|
|
135
|
+
const events = this.rooms.get(roomId) ?? [];
|
|
136
|
+
events.push(event);
|
|
137
|
+
this.rooms.set(roomId, events);
|
|
138
|
+
return event;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private async handle(
|
|
142
|
+
input: RequestInfo | URL,
|
|
143
|
+
init: RequestInit | undefined,
|
|
144
|
+
): Promise<Response> {
|
|
145
|
+
const url = new URL(input instanceof Request ? input.url : String(input));
|
|
146
|
+
const method = (
|
|
147
|
+
init?.method ?? (input instanceof Request ? input.method : 'GET')
|
|
148
|
+
).toUpperCase();
|
|
149
|
+
const path = decodeURIComponent(
|
|
150
|
+
url.pathname.replace(/^\/_matrix\/client\/v3/, ''),
|
|
151
|
+
);
|
|
152
|
+
this.requests.push({ method, path, at: Date.now() });
|
|
153
|
+
|
|
154
|
+
const join = /^\/join\/(.+)$/.exec(path);
|
|
155
|
+
if (method === 'POST' && join)
|
|
156
|
+
return this.joinFailure
|
|
157
|
+
? json(this.joinFailure.status, {
|
|
158
|
+
errcode: this.joinFailure.errcode,
|
|
159
|
+
error: 'scripted failure',
|
|
160
|
+
})
|
|
161
|
+
: json(200, { room_id: join[1] });
|
|
162
|
+
|
|
163
|
+
const messages = /^\/rooms\/([^/]+)\/messages$/.exec(path);
|
|
164
|
+
if (method === 'GET' && messages) {
|
|
165
|
+
const delay = this.messagesDelays.shift();
|
|
166
|
+
if (delay) await new Promise((resolve) => setTimeout(resolve, delay));
|
|
167
|
+
const failure = this.messagesScript.shift() ?? this.messagesFailure;
|
|
168
|
+
if (failure)
|
|
169
|
+
return json(failure.status, {
|
|
170
|
+
errcode: failure.errcode,
|
|
171
|
+
error: 'scripted failure',
|
|
172
|
+
});
|
|
173
|
+
const chunk = [...(this.rooms.get(messages[1] ?? '') ?? [])].reverse();
|
|
174
|
+
return json(200, { chunk, start: 't0' });
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (method === 'GET' && path === '/events') {
|
|
178
|
+
const signal = init?.signal;
|
|
179
|
+
this.openPolls += 1;
|
|
180
|
+
return new Promise<Response>((_resolve, reject) => {
|
|
181
|
+
const finish = () => {
|
|
182
|
+
this.openPolls -= 1;
|
|
183
|
+
const reason: unknown = signal?.reason;
|
|
184
|
+
reject(reason instanceof Error ? reason : new Error('aborted'));
|
|
185
|
+
};
|
|
186
|
+
if (signal?.aborted) finish();
|
|
187
|
+
else signal?.addEventListener('abort', finish, { once: true });
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const send = /^\/rooms\/([^/]+)\/send\/([^/]+)\/([^/]+)$/.exec(path);
|
|
192
|
+
if (method === 'PUT' && send) {
|
|
193
|
+
const [, roomId = '', type = ''] = send;
|
|
194
|
+
const outcome =
|
|
195
|
+
type === 'matrix-crdt.doc_update' ? this.sendScript.shift() : 'ok';
|
|
196
|
+
if (outcome === 'network') throw new TypeError('Network connection lost');
|
|
197
|
+
if (outcome === 'hang')
|
|
198
|
+
return new Promise<Response>((_resolve, reject) => {
|
|
199
|
+
const signal = init?.signal;
|
|
200
|
+
signal?.addEventListener(
|
|
201
|
+
'abort',
|
|
202
|
+
() => reject(new Error('aborted')),
|
|
203
|
+
{ once: true },
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
if (outcome && outcome !== 'ok')
|
|
207
|
+
return json(outcome.status, {
|
|
208
|
+
errcode: outcome.errcode,
|
|
209
|
+
error: outcome.error ?? 'scripted failure',
|
|
210
|
+
...(outcome.retry_after_ms !== undefined
|
|
211
|
+
? { retry_after_ms: outcome.retry_after_ms }
|
|
212
|
+
: {}),
|
|
213
|
+
});
|
|
214
|
+
const body: unknown = JSON.parse(String(init?.body ?? '{}'));
|
|
215
|
+
const content = body && typeof body === 'object' ? { ...body } : {};
|
|
216
|
+
return json(200, {
|
|
217
|
+
event_id: this.append(roomId, type, content).event_id,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (method === 'GET' && /^\/rooms\/[^/]+\/state\//.test(path))
|
|
222
|
+
return json(404, { errcode: 'M_NOT_FOUND', error: 'not found' });
|
|
223
|
+
|
|
224
|
+
return json(404, { errcode: 'M_UNRECOGNIZED', error: `no route ${path}` });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Record every unhandled promise rejection until `stop()` is called. Uses the
|
|
230
|
+
* global `unhandledrejection` event, which workerd dispatches.
|
|
231
|
+
*/
|
|
232
|
+
export function watchUnhandledRejections(): {
|
|
233
|
+
reasons: unknown[];
|
|
234
|
+
stop: () => void;
|
|
235
|
+
} {
|
|
236
|
+
const reasons: unknown[] = [];
|
|
237
|
+
const listener = (event: PromiseRejectionEvent) => {
|
|
238
|
+
reasons.push(event.reason);
|
|
239
|
+
};
|
|
240
|
+
globalThis.addEventListener('unhandledrejection', listener);
|
|
241
|
+
return {
|
|
242
|
+
reasons,
|
|
243
|
+
stop: () => globalThis.removeEventListener('unhandledrejection', listener),
|
|
244
|
+
};
|
|
245
|
+
}
|