@fungi.computer/carrier 0.0.0-stage → 0.0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +457 -2
  3. package/dist/cloudflare.d.ts +32 -0
  4. package/dist/cloudflare.js +80 -0
  5. package/dist/email.d.ts +2 -0
  6. package/dist/email.js +2 -0
  7. package/dist/index.d.ts +21 -0
  8. package/dist/index.js +28 -0
  9. package/dist/inspection.d.ts +108 -0
  10. package/dist/inspection.js +188 -0
  11. package/dist/internal/cloudflare-send.d.ts +9 -0
  12. package/dist/internal/cloudflare-send.js +79 -0
  13. package/dist/internal/contracts.d.ts +94 -0
  14. package/dist/internal/contracts.js +7 -0
  15. package/dist/internal/owner.d.ts +24 -0
  16. package/dist/internal/owner.js +419 -0
  17. package/dist/internal/policy.d.ts +25 -0
  18. package/dist/internal/policy.js +18 -0
  19. package/dist/internal/post-contract.d.ts +27 -0
  20. package/dist/internal/post-contract.js +22 -0
  21. package/dist/internal/post-execution.d.ts +45 -0
  22. package/dist/internal/post-execution.js +73 -0
  23. package/dist/internal/post-sql.d.ts +51 -0
  24. package/dist/internal/post-sql.js +255 -0
  25. package/dist/internal/receipt-schema.d.ts +3 -0
  26. package/dist/internal/receipt-schema.js +12 -0
  27. package/dist/post-d1.d.ts +36 -0
  28. package/dist/post-d1.js +55 -0
  29. package/dist/post-outbox.d.ts +40 -0
  30. package/dist/post-outbox.js +99 -0
  31. package/dist/post-postgres.d.ts +25 -0
  32. package/dist/post-postgres.js +79 -0
  33. package/dist/post.d.ts +189 -0
  34. package/dist/post.js +436 -0
  35. package/dist/testing.d.ts +16 -0
  36. package/dist/testing.js +20 -0
  37. package/docs/api/README.md +20 -0
  38. package/docs/api/cloudflare.md +100 -0
  39. package/docs/api/email.md +87 -0
  40. package/docs/api/index.md +343 -0
  41. package/docs/api/inspection.md +281 -0
  42. package/docs/api/post-d1.md +184 -0
  43. package/docs/api/post-postgres.md +108 -0
  44. package/docs/api/post.md +620 -0
  45. package/docs/api/testing.md +46 -0
  46. package/package.json +94 -3
@@ -0,0 +1,281 @@
1
+ <!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
2
+
3
+ [**@fungi.computer/carrier**](README.md)
4
+
5
+ ---
6
+
7
+ [@fungi.computer/carrier](README.md) / inspection
8
+
9
+ # inspection
10
+
11
+ ## Classes
12
+
13
+ ### DeliveryInspectionError
14
+
15
+ Stable inspection errors never include stored cargo or raw SQL failures.
16
+
17
+ #### Extends
18
+
19
+ - `Error`
20
+
21
+ #### Constructors
22
+
23
+ ##### Constructor
24
+
25
+ ```ts
26
+ new DeliveryInspectionError(code): DeliveryInspectionError;
27
+ ```
28
+
29
+ ###### Parameters
30
+
31
+ | Parameter | Type |
32
+ | --------- | ------------------------------------ |
33
+ | `code` | `"unavailable"` \| `"invalid_query"` |
34
+
35
+ ###### Returns
36
+
37
+ [`DeliveryInspectionError`](#deliveryinspectionerror)
38
+
39
+ ###### Overrides
40
+
41
+ ```ts
42
+ Error.constructor;
43
+ ```
44
+
45
+ #### Properties
46
+
47
+ ##### code
48
+
49
+ ```ts
50
+ readonly code: "unavailable" | "invalid_query";
51
+ ```
52
+
53
+ ## Type Aliases
54
+
55
+ ### DeliveryInspectionPageQuery
56
+
57
+ ```ts
58
+ type DeliveryInspectionPageQuery = Schema.Codec.Encoded<
59
+ typeof DeliveryInspectionPageQuerySchema
60
+ >;
61
+ ```
62
+
63
+ An email receipt page uses the same producer-key pagination.
64
+
65
+ ---
66
+
67
+ ### DeliveryInspectionQuery
68
+
69
+ ```ts
70
+ type DeliveryInspectionQuery = Schema.Codec.Encoded<
71
+ typeof DeliveryInspectionQuerySchema
72
+ >;
73
+ ```
74
+
75
+ Input to one producer-local inspection. Cursors are producer keys, without
76
+ storage prefixes.
77
+
78
+ ---
79
+
80
+ ### PostReceiptSummary
81
+
82
+ ```ts
83
+ type PostReceiptSummary = Schema.Schema.Type<typeof PostReceiptSummarySchema>;
84
+ ```
85
+
86
+ Metadata for one retained Post row.
87
+
88
+ ---
89
+
90
+ ### PostInspectionPage
91
+
92
+ ```ts
93
+ type PostInspectionPage = Schema.Schema.Type<typeof PostInspectionPageSchema>;
94
+ ```
95
+
96
+ One read of producer-local Post dispatch evidence.
97
+
98
+ ---
99
+
100
+ ### CarrierInspectionPage
101
+
102
+ ```ts
103
+ type CarrierInspectionPage = Schema.Schema.Type<
104
+ typeof CarrierInspectionPageSchema
105
+ >;
106
+ ```
107
+
108
+ One read of aggregate email dispatch evidence.
109
+
110
+ ## Variables
111
+
112
+ ### DeliveryInspectionPageQuerySchema
113
+
114
+ ```ts
115
+ const DeliveryInspectionPageQuerySchema: Struct<{
116
+ limit: withDecodingDefaultType<Int, never>;
117
+ after: optional<String>;
118
+ }>;
119
+ ```
120
+
121
+ One bounded scan; an empty filtered page can still have a continuation.
122
+
123
+ ---
124
+
125
+ ### DeliveryInspectionQuerySchema
126
+
127
+ ```ts
128
+ const DeliveryInspectionQuerySchema: Struct<{
129
+ limit: withDecodingDefaultType<Int, never>;
130
+ after: optional<String>;
131
+ view: Literals<readonly ["receipts", "deadLetters"]>;
132
+ }>;
133
+ ```
134
+
135
+ Post can filter dead letters while scanning at most one bounded page.
136
+
137
+ ---
138
+
139
+ ### PostReceiptSummarySchema
140
+
141
+ ```ts
142
+ const PostReceiptSummarySchema: Union<
143
+ readonly [
144
+ Struct<{
145
+ key: String;
146
+ state: Literal<"delivered">;
147
+ }>,
148
+ Struct<{
149
+ key: String;
150
+ state: Literal<"pending">;
151
+ kind: String;
152
+ attempts: Int;
153
+ nextAttemptAt: Number;
154
+ }>,
155
+ Struct<{
156
+ key: String;
157
+ state: Literal<"dead">;
158
+ kind: String;
159
+ attempts: Int;
160
+ reason: Literals<readonly ["refused", "exhausted"]>;
161
+ }>,
162
+ ]
163
+ >;
164
+ ```
165
+
166
+ Dispatch evidence deliberately omits the address and event.
167
+
168
+ ---
169
+
170
+ ### PostInspectionPageSchema
171
+
172
+ ```ts
173
+ const PostInspectionPageSchema: Union<readonly [Struct<{
174
+ status: Literal<"uninitialized">;
175
+ }>, Struct<{
176
+ status: Literal<"available">;
177
+ records: $Array<Union<readonly [Struct<{
178
+ key: String;
179
+ state: Literal<"delivered">;
180
+ }>, Struct<{
181
+ key: String;
182
+ state: Literal<"pending">;
183
+ kind: String;
184
+ attempts: Int;
185
+ nextAttemptAt: Number;
186
+ }>, Struct<{
187
+ key: String;
188
+ state: Literal<"dead">;
189
+ kind: String;
190
+ attempts: Int;
191
+ reason: Literals<readonly [..., ...]>;
192
+ }>]>>;
193
+ nextCursor: NullOr<String>;
194
+ }>]>;
195
+ ```
196
+
197
+ Bounded evidence with an explicit distinction between empty and uninitialized
198
+ storage.
199
+
200
+ ---
201
+
202
+ ### CarrierReceiptSummarySchema
203
+
204
+ ```ts
205
+ const CarrierReceiptSummarySchema: Struct<{
206
+ id: String;
207
+ status: Literals<
208
+ readonly [
209
+ "queued",
210
+ "dispatching",
211
+ "provider_accepted",
212
+ "outcome_unknown",
213
+ "rejected",
214
+ "refused",
215
+ "expired",
216
+ "superseded",
217
+ ]
218
+ >;
219
+ attempts: Int;
220
+ retryAt: NullOr<Number>;
221
+ providerMessageId: optional<NonEmptyString>;
222
+ providerRejection: optional<
223
+ Struct<{
224
+ code: NonEmptyString;
225
+ class: Literals<readonly ["permanent", "temporary"]>;
226
+ }>
227
+ >;
228
+ }>;
229
+ ```
230
+
231
+ Aggregate email evidence without bodies, headers or recipient addresses.
232
+
233
+ ---
234
+
235
+ ### CarrierInspectionPageSchema
236
+
237
+ ```ts
238
+ const CarrierInspectionPageSchema: Union<readonly [Struct<{
239
+ status: Literal<"uninitialized">;
240
+ }>, Struct<{
241
+ status: Literal<"available">;
242
+ records: $Array<Struct<{
243
+ id: String;
244
+ status: Literals<readonly ["queued", "dispatching", "provider_accepted", "outcome_unknown", "rejected", "refused", "expired", "superseded"]>;
245
+ attempts: Int;
246
+ retryAt: NullOr<Number>;
247
+ providerMessageId: optional<NonEmptyString>;
248
+ providerRejection: optional<Struct<{
249
+ code: NonEmptyString;
250
+ class: Literals<...>;
251
+ }>>;
252
+ }>>;
253
+ nextCursor: NullOr<String>;
254
+ }>]>;
255
+ ```
256
+
257
+ Carrier's bounded metadata page; unavailable storage is never reported as empty.
258
+
259
+ ## Functions
260
+
261
+ ### createDeliveryInspection()
262
+
263
+ ```ts
264
+ function createDeliveryInspection(sql): object;
265
+ ```
266
+
267
+ Read existing storage without opening a sender, initializing tables, repairing
268
+ jobs or arming a wake. The trusted host must admit an operator before calling.
269
+
270
+ #### Parameters
271
+
272
+ | Parameter | Type |
273
+ | --------- | ----------------------------------------------------------------------------------- |
274
+ | `sql` | `Readonly`\<\{ `exec`: (`statement`, ...`bindings`) => `WatchdogSqliteCursor`; \}\> |
275
+
276
+ #### Returns
277
+
278
+ | Name | Type | Description |
279
+ | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
280
+ | `email()` | (`input`) => \| \{ `status`: `"uninitialized"`; \} \| \{ `status`: `"available"`; `records`: readonly `object`[]; `nextCursor`: `string` \| `null`; \} | Read aggregate dispatch evidence without email cargo or recipient addresses. |
281
+ | `post()` | (`input`) => \| \{ `status`: `"uninitialized"`; \} \| \{ `status`: `"available"`; `records`: readonly ( \| \{ `key`: `string`; `state`: `"delivered"`; \} \| \{ `key`: `string`; `state`: `"pending"`; `kind`: `string`; `attempts`: `number`; `nextAttemptAt`: `number`; \} \| \{ `key`: `string`; `state`: `"dead"`; `kind`: `string`; `attempts`: `number`; `reason`: `"refused"` \| `"exhausted"`; \})[]; `nextCursor`: `string` \| `null`; \} | Read Post metadata; filtered pages retain their continuation through other states. |
@@ -0,0 +1,184 @@
1
+ <!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
2
+
3
+ [**@fungi.computer/carrier**](README.md)
4
+
5
+ ---
6
+
7
+ [@fungi.computer/carrier](README.md) / post-d1
8
+
9
+ # post-d1
10
+
11
+ ## Type Aliases
12
+
13
+ ### SqlPostOptions
14
+
15
+ ```ts
16
+ type SqlPostOptions<R> = Readonly<{
17
+ routes: R;
18
+ failureDetail?: (cause) => string;
19
+ retry?: Readonly<{
20
+ maxAttempts: number;
21
+ baseDelayMs: number;
22
+ maxDelayMs: number;
23
+ }>;
24
+ now: () => number;
25
+ scheduleWake: (at) => Promise<void>;
26
+ }>;
27
+ ```
28
+
29
+ SQL native Carrier runtime configuration; route decisions remain in Post.
30
+
31
+ #### Type Parameters
32
+
33
+ | Type Parameter |
34
+ | ------------------------------------------------------------------------------------ |
35
+ | `R` _extends_ `Record`\<`string`, [`PostRegistryRoute`](post.md#postregistryroute)\> |
36
+
37
+ ---
38
+
39
+ ### SqlPostRuntime
40
+
41
+ ```ts
42
+ type SqlPostRuntime = Readonly<{
43
+ execute: (
44
+ job,
45
+ signal?,
46
+ ) => Promise<
47
+ Readonly<{
48
+ kind: "completed";
49
+ }>
50
+ >;
51
+ enqueueDue: (limit?, afterKey?) => Promise<string | undefined>;
52
+ read: (key) => Promise<PostRow | undefined>;
53
+ }>;
54
+ ```
55
+
56
+ Async inspection and Watchdog executor shared by D1 and PostgreSQL.
57
+
58
+ ---
59
+
60
+ ### D1PostSource
61
+
62
+ ```ts
63
+ type D1PostSource = Readonly<{
64
+ text: string;
65
+ values: readonly (string | number | null)[];
66
+ }>;
67
+ ```
68
+
69
+ Trusted SELECT yielding post_key, envelope_json, queue_name, next_attempt_at and
70
+ job_id.
71
+
72
+ ---
73
+
74
+ ### D1Post
75
+
76
+ ```ts
77
+ type D1Post = SqlPostRuntime &
78
+ Readonly<{
79
+ send: (envelope) => readonly D1PreparedStatement[];
80
+ sendFromSelect: (source) => readonly D1PreparedStatement[];
81
+ }>;
82
+ ```
83
+
84
+ Post admission statements; callers commit them with the originating D1 fact.
85
+
86
+ ---
87
+
88
+ ### D1PostErasureStatement
89
+
90
+ ```ts
91
+ type D1PostErasureStatement = Readonly<{
92
+ text: string;
93
+ values: readonly (string | number | null)[];
94
+ }>;
95
+ ```
96
+
97
+ Native erasure statement; its values remain bound by the caller's D1 driver.
98
+
99
+ ## Variables
100
+
101
+ ### postD1Schema
102
+
103
+ ```ts
104
+ const postD1Schema: readonly string[];
105
+ ```
106
+
107
+ Carrier-owned D1 schema, applied by the deployment migration owner.
108
+
109
+ ## Functions
110
+
111
+ ### createD1Post()
112
+
113
+ ```ts
114
+ function createD1Post<R>(options): D1Post;
115
+ ```
116
+
117
+ Bind the Post registry to native D1 batch admission and the shared delivery
118
+ engine.
119
+
120
+ #### Type Parameters
121
+
122
+ | Type Parameter |
123
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
124
+ | `R` _extends_ `Record`\<`string`, `Readonly`\<\{ `addressKind`: `string`; `address`: `Codec`\<`unknown`, `unknown`\>; `event`: `Codec`\<`unknown`, `unknown`\>; `encodeEnvelope`: (`envelope`) => `object`; `parseDelivery`: (`envelope`) => `object`; `prepareEnvelope?`: (`envelope`, `signal`) => `Promise`\<\{ `key`: `string`; `kind`: `string`; `address`: `unknown`; `event`: `unknown`; \}\>; `recordDelivered?`: (`envelope`) => `void`; `nameOf`: (`envelope`) => `string`; `namespace`: `Readonly`\<\{ `getByName`: (`name`) => `Readonly`\<\{ `deliver`: (`envelope`) => `Promise`\<[`PostDeliveryResult`](post.md#postdeliveryresult)\>; \}\>; \}\>; `recordCursor?`: (`envelope`, `cursor`) => `void`; `recordRefused?`: (`envelope`) => `void`; \}\>\> |
125
+
126
+ #### Parameters
127
+
128
+ | Parameter | Type |
129
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
130
+ | `options` | `Readonly`\<\{ `routes`: `R`; `failureDetail?`: (`cause`) => `string`; `retry?`: `Readonly`\<\{ `maxAttempts`: `number`; `baseDelayMs`: `number`; `maxDelayMs`: `number`; \}\>; `now`: () => `number`; `scheduleWake`: (`at`) => `Promise`\<`void`\>; \}\> & `Readonly`\<\{ `database`: `D1Database`; `watchdog`: `D1Watchdog`; \}\> |
131
+
132
+ #### Returns
133
+
134
+ [`D1Post`](#d1post)
135
+
136
+ ---
137
+
138
+ ### prepareD1PostAdmission()
139
+
140
+ ```ts
141
+ function prepareD1PostAdmission(
142
+ database,
143
+ source,
144
+ ): readonly D1PreparedStatement[];
145
+ ```
146
+
147
+ Prepare conditional envelopes and their jobs inside the producer's D1 batch.
148
+
149
+ #### Parameters
150
+
151
+ | Parameter | Type |
152
+ | ---------- | ------------------------------- |
153
+ | `database` | `D1Database` |
154
+ | `source` | [`D1PostSource`](#d1postsource) |
155
+
156
+ #### Returns
157
+
158
+ readonly `D1PreparedStatement`[]
159
+
160
+ ---
161
+
162
+ ### purgeD1Post()
163
+
164
+ ```ts
165
+ function purgeD1Post(source): readonly Readonly<{
166
+ text: string;
167
+ values: readonly (string | number | null)[];
168
+ }>[];
169
+ ```
170
+
171
+ Remove selected recipient queues, including every envelope and attempt,
172
+ atomically. The trusted SELECT yields queue_name from producer/envelope facts,
173
+ not job state.
174
+
175
+ #### Parameters
176
+
177
+ | Parameter | Type |
178
+ | --------- | --------------------------------------------------- |
179
+ | `source` | [`D1PostErasureStatement`](#d1posterasurestatement) |
180
+
181
+ #### Returns
182
+
183
+ readonly `Readonly`\<\{ `text`: `string`; `values`: readonly (`string` \|
184
+ `number` \| `null`)[]; \}\>[]
@@ -0,0 +1,108 @@
1
+ <!-- Generated by Botanical API docs (TypeDoc + typedoc-plugin-markdown). Do not edit. -->
2
+
3
+ [**@fungi.computer/carrier**](README.md)
4
+
5
+ ---
6
+
7
+ [@fungi.computer/carrier](README.md) / post-postgres
8
+
9
+ # post-postgres
10
+
11
+ ## Type Aliases
12
+
13
+ ### PostgresPost
14
+
15
+ ```ts
16
+ type PostgresPost = SqlPostRuntime &
17
+ Readonly<{
18
+ send: (client, envelope) => Promise<void>;
19
+ }>;
20
+ ```
21
+
22
+ Post on PostgreSQL; the producer retains ownership of BEGIN and COMMIT.
23
+
24
+ ---
25
+
26
+ ### PostgresPostErasureStatement
27
+
28
+ ```ts
29
+ type PostgresPostErasureStatement = Readonly<{
30
+ text: string;
31
+ values: readonly (string | number | null)[];
32
+ }>;
33
+ ```
34
+
35
+ Parameterized native erasure; the producer controls BEGIN and COMMIT.
36
+
37
+ ## Variables
38
+
39
+ ### postPostgresSchema
40
+
41
+ ```ts
42
+ const postPostgresSchema: readonly string[];
43
+ ```
44
+
45
+ Carrier-owned PostgreSQL schema, applied by the deployment migration owner.
46
+
47
+ ## Functions
48
+
49
+ ### createPostgresPost()
50
+
51
+ ```ts
52
+ function createPostgresPost<R>(options): PostgresPost;
53
+ ```
54
+
55
+ Bind the Post registry to a PostgreSQL owner and the shared delivery engine.
56
+
57
+ #### Type Parameters
58
+
59
+ | Type Parameter |
60
+ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
61
+ | `R` _extends_ `Record`\<`string`, `Readonly`\<\{ `addressKind`: `string`; `address`: `Codec`\<`unknown`, `unknown`\>; `event`: `Codec`\<`unknown`, `unknown`\>; `encodeEnvelope`: (`envelope`) => `object`; `parseDelivery`: (`envelope`) => `object`; `prepareEnvelope?`: (`envelope`, `signal`) => `Promise`\<\{ `key`: `string`; `kind`: `string`; `address`: `unknown`; `event`: `unknown`; \}\>; `recordDelivered?`: (`envelope`) => `void`; `nameOf`: (`envelope`) => `string`; `namespace`: `Readonly`\<\{ `getByName`: (`name`) => `Readonly`\<\{ `deliver`: (`envelope`) => `Promise`\<[`PostDeliveryResult`](post.md#postdeliveryresult)\>; \}\>; \}\>; `recordCursor?`: (`envelope`, `cursor`) => `void`; `recordRefused?`: (`envelope`) => `void`; \}\>\> |
62
+
63
+ #### Parameters
64
+
65
+ | Parameter | Type |
66
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
67
+ | `options` | `Readonly`\<\{ `routes`: `R`; `failureDetail?`: (`cause`) => `string`; `retry?`: `Readonly`\<\{ `maxAttempts`: `number`; `baseDelayMs`: `number`; `maxDelayMs`: `number`; \}\>; `now`: () => `number`; `scheduleWake`: (`at`) => `Promise`\<`void`\>; \}\> & `Readonly`\<\{ `database`: `Pick`\<`Pool`, `"query"` \| `"connect"`\>; `watchdog`: `PostgresWatchdog`; \}\> |
68
+
69
+ #### Returns
70
+
71
+ [`PostgresPost`](#postgrespost)
72
+
73
+ ---
74
+
75
+ ### purgePostgresPost()
76
+
77
+ ```ts
78
+ function purgePostgresPost(source): readonly Readonly<{
79
+ text: string;
80
+ values: readonly (string | number | null)[];
81
+ }>[];
82
+ ```
83
+
84
+ Purge selected recipient queues, including all envelopes and attempts. The
85
+ trusted SELECT yields queue_name from producer/envelope facts, not job state.
86
+
87
+ #### Parameters
88
+
89
+ | Parameter | Type |
90
+ | --------- | --------------------------------------------------------------- |
91
+ | `source` | [`PostgresPostErasureStatement`](#postgresposterasurestatement) |
92
+
93
+ #### Returns
94
+
95
+ readonly `Readonly`\<\{ `text`: `string`; `values`: readonly (`string` \|
96
+ `number` \| `null`)[]; \}\>[]
97
+
98
+ ## References
99
+
100
+ ### SqlPostOptions
101
+
102
+ Re-exports [SqlPostOptions](post-d1.md#sqlpostoptions)
103
+
104
+ ---
105
+
106
+ ### SqlPostRuntime
107
+
108
+ Re-exports [SqlPostRuntime](post-d1.md#sqlpostruntime)