@worker-protocol/cloudflare 0.8.0 → 0.8.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/README.md +9 -0
- package/dist/lifecycle.js +32 -15
- package/dist/subscriptions.d.ts +2 -1
- package/dist/subscriptions.js +14 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -202,6 +202,15 @@ Every id is derived from the transition, the resource and its `since`, and the i
|
|
|
202
202
|
brings its birth with it. `heartbeat()` compares up to now and points the shared alarm at the next
|
|
203
203
|
instant; a cron that calls it starts the chain and restarts it if an alarm is lost.
|
|
204
204
|
|
|
205
|
+
**What a mixin does internally is a function of its module, never a method.** `private` is
|
|
206
|
+
TypeScript's alone: at run time it is a method on the prototype, and a Worker whose class declares
|
|
207
|
+
one of the same name replaces it silently. Only the methods each mixin's interface lists are on the
|
|
208
|
+
object.
|
|
209
|
+
|
|
210
|
+
`withSubscriptions` also answers `wantedHere(source, events)`: which events a live subscription it
|
|
211
|
+
holds would receive, synchronously, so an object that keeps an outbox and the subscriptions leaves
|
|
212
|
+
the rest out inside the transaction of the write that raised them.
|
|
213
|
+
|
|
205
214
|
## Also exported
|
|
206
215
|
|
|
207
216
|
`durableOutcomes`, `durableSubscriptions` and `durableLogs` turn a stub into the store `mount()`
|
package/dist/lifecycle.js
CHANGED
|
@@ -51,24 +51,31 @@ export function lifecycleEventsBetween(given) {
|
|
|
51
51
|
]),
|
|
52
52
|
];
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Owes each event not owed before, in the transaction the caller is in, and answers how many were
|
|
56
|
+
* new. The outbox holds an id back only while it waits; this remembers it after.
|
|
57
|
+
*
|
|
58
|
+
* **A function of the module and not a method of the mixin, and that is the rule for every mixin
|
|
59
|
+
* here.** `private` is TypeScript's alone: at run time it is a method on the prototype like any
|
|
60
|
+
* other, and `Mixed` does not carry it, so a Worker whose class declares a method of the same name
|
|
61
|
+
* replaces it without a word from the compiler or the runtime. Only what a mixin publishes as its
|
|
62
|
+
* interface is a method; what it does internally is reached by no subclass.
|
|
63
|
+
*/
|
|
64
|
+
function owe(given) {
|
|
65
|
+
const { storage, enqueue, now, events } = given;
|
|
66
|
+
const sql = migrate(storage, SCHEMA);
|
|
67
|
+
// `RETURNING` answers a row only for an id this inserted, and nothing for one already there.
|
|
68
|
+
const fresh = events.filter((event) => sql
|
|
69
|
+
.exec("INSERT INTO wp_lifecycle_owed (id, at) VALUES (?, ?) ON CONFLICT DO NOTHING RETURNING id", event.id, now)
|
|
70
|
+
.toArray().length > 0);
|
|
71
|
+
enqueue(now, fresh);
|
|
72
|
+
return fresh.length;
|
|
73
|
+
}
|
|
54
74
|
export function withLifecycle(Base, options = {}) {
|
|
55
75
|
const catchUpMs = options.catchUpMs ?? 120 * MINUTE;
|
|
56
76
|
const mostPerRunMs = options.mostPerRunMs ?? 60 * MINUTE;
|
|
57
77
|
const keepAnnouncedMs = options.keepAnnouncedMs ?? 2 * 24 * 60 * MINUTE;
|
|
58
78
|
class WithLifecycle extends Base {
|
|
59
|
-
/**
|
|
60
|
-
* Owes each event not owed before, in the transaction the calling method is in, and answers how
|
|
61
|
-
* many were new. The outbox holds an id back only while it waits; this remembers it after.
|
|
62
|
-
*/
|
|
63
|
-
owe(now, events) {
|
|
64
|
-
const sql = migrate(this.ctx.storage, SCHEMA);
|
|
65
|
-
// `RETURNING` answers a row only for an id this inserted, and nothing for one already there.
|
|
66
|
-
const fresh = events.filter((event) => sql
|
|
67
|
-
.exec("INSERT INTO wp_lifecycle_owed (id, at) VALUES (?, ?) ON CONFLICT DO NOTHING RETURNING id", event.id, now)
|
|
68
|
-
.toArray().length > 0);
|
|
69
|
-
this.enqueue(now, fresh);
|
|
70
|
-
return fresh.length;
|
|
71
|
-
}
|
|
72
79
|
/**
|
|
73
80
|
* Performs `write` and owes what it changed: the Tasks and Alerts at `now` before it and after
|
|
74
81
|
* it, compared in the same transaction as the write. `write` is synchronous, because the
|
|
@@ -77,7 +84,12 @@ export function withLifecycle(Base, options = {}) {
|
|
|
77
84
|
changing(now, write) {
|
|
78
85
|
const before = this.snapshot(now);
|
|
79
86
|
const done = write();
|
|
80
|
-
|
|
87
|
+
owe({
|
|
88
|
+
storage: this.ctx.storage,
|
|
89
|
+
enqueue: (at, events) => this.enqueue(at, events),
|
|
90
|
+
now,
|
|
91
|
+
events: lifecycleEventsBetween({ previous: before, current: this.snapshot(now), at: now }),
|
|
92
|
+
});
|
|
81
93
|
return done;
|
|
82
94
|
}
|
|
83
95
|
/**
|
|
@@ -110,7 +122,12 @@ export function withLifecycle(Base, options = {}) {
|
|
|
110
122
|
at = next;
|
|
111
123
|
}
|
|
112
124
|
}
|
|
113
|
-
const fresh =
|
|
125
|
+
const fresh = owe({
|
|
126
|
+
storage: this.ctx.storage,
|
|
127
|
+
enqueue: (at, events) => this.enqueue(at, events),
|
|
128
|
+
now,
|
|
129
|
+
events: owed,
|
|
130
|
+
});
|
|
114
131
|
sql.exec("INSERT OR REPLACE INTO wp_lifecycle_mark (one, at) VALUES (1, ?)", Math.max(to, from));
|
|
115
132
|
sql.exec("DELETE FROM wp_lifecycle_owed WHERE at < ?", now - keepAnnouncedMs);
|
|
116
133
|
await this.flush();
|
package/dist/subscriptions.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Publishable, type SubscriptionStore } from "@worker-protocol/hono";
|
|
2
2
|
import { type DurableObjectClass, type Mixed, type Rpc } from "./durable.ts";
|
|
3
3
|
/** What `withSubscriptions` adds to a Durable Object. Every subscription crosses as JSON. */
|
|
4
4
|
export interface SubscriptionMethods {
|
|
@@ -16,6 +16,7 @@ export interface SubscriptionMethods {
|
|
|
16
16
|
clear: string[];
|
|
17
17
|
}): void;
|
|
18
18
|
removeSubscription(id: string): void;
|
|
19
|
+
wantedHere(source: string, events: Publishable[]): boolean[];
|
|
19
20
|
}
|
|
20
21
|
export declare function withSubscriptions<B extends DurableObjectClass>(Base: B): Mixed<B, SubscriptionMethods>;
|
|
21
22
|
/** What `durableSubscriptions` needs of a stub: the methods `withSubscriptions` adds, over RPC. */
|
package/dist/subscriptions.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wantedBy, } from "@worker-protocol/hono";
|
|
1
2
|
import { first } from "./durable.js";
|
|
2
3
|
import { migrate } from "./schema.js";
|
|
3
4
|
/**
|
|
@@ -103,6 +104,19 @@ export function withSubscriptions(Base) {
|
|
|
103
104
|
const sql = migrate(this.ctx.storage, SCHEMA);
|
|
104
105
|
sql.exec("DELETE FROM wp_subscription WHERE id = ?", id);
|
|
105
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Which of these events a live subscription held here would receive (SUB-13), answered
|
|
109
|
+
* synchronously — so a Worker can leave the rest out of its outbox inside the very transaction
|
|
110
|
+
* of the write that raised them, as `changing()` needs. `source` is the Worker's id, which every
|
|
111
|
+
* event carries (EVT-1); the envelope is the hub's own, so the filters read the same attributes.
|
|
112
|
+
*/
|
|
113
|
+
wantedHere(source, events) {
|
|
114
|
+
return wantedBy({
|
|
115
|
+
source,
|
|
116
|
+
subscribed: (type) => this.subscriptionsFor(type).map(parse),
|
|
117
|
+
events,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
106
120
|
}
|
|
107
121
|
return WithSubscriptions;
|
|
108
122
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@worker-protocol/cloudflare",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"workerProtocolEdition": "0.6",
|
|
5
5
|
"description": "The protocol's stores in Durable Objects, and the Queues between an outbox and a sink: mixins for ENDP-16, SUB-7, LOG-2 and an outbox, for Workers on Cloudflare",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"NOTICE"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@worker-protocol/hono": "0.8.
|
|
42
|
+
"@worker-protocol/hono": "0.8.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"hono": "^4.13.7",
|