@mcp-b/do-runtime 0.3.1 → 0.3.2
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/CHANGELOG.md +6 -0
- package/dist/gate.js +15 -20
- package/dist/gate.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/gate.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { c as tryCurrentSlice } from "./chunks/io-context-D89n6HVM.js";
|
|
2
2
|
//#region src/gate.ts
|
|
3
3
|
var continuationContext;
|
|
4
|
-
var publications = [];
|
|
5
4
|
function isThenable(value) {
|
|
6
5
|
return (typeof value === "object" && value !== null || typeof value === "function") && typeof Reflect.get(value, "then") === "function";
|
|
7
6
|
}
|
|
@@ -12,19 +11,16 @@ function __gate(value) {
|
|
|
12
11
|
if (context === void 0) return value;
|
|
13
12
|
return resumeWithContext(context, Promise.resolve(value));
|
|
14
13
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Resolve one transformed await per task, inside a fresh actor slice. Starting
|
|
17
|
-
* from a task with an empty microtask queue makes its continuation the only code
|
|
18
|
-
* between publishing and clearing the actor identity. A shared queue prevents
|
|
19
|
-
* two actors that settle together from overwriting each other's publication.
|
|
20
|
-
*/
|
|
21
|
-
function enqueuePublication(publication) {
|
|
22
|
-
publications.push(publication);
|
|
23
|
-
if (publications.length === 1) schedulePublication();
|
|
24
|
-
}
|
|
25
14
|
function resumeWithContext(context, promise) {
|
|
26
15
|
return new Promise((resolve, reject) => {
|
|
27
16
|
const publish = context.makeTransformReentryCallback((outcome) => {
|
|
17
|
+
if (continuationContext !== void 0) {
|
|
18
|
+
schedulePublication({
|
|
19
|
+
publish: () => publish(outcome),
|
|
20
|
+
reject
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
28
24
|
const token = {};
|
|
29
25
|
continuationContext = {
|
|
30
26
|
context,
|
|
@@ -34,12 +30,10 @@ function resumeWithContext(context, promise) {
|
|
|
34
30
|
else reject(outcome.exception);
|
|
35
31
|
queueMicrotask(() => {
|
|
36
32
|
if (continuationContext?.token === token) continuationContext = void 0;
|
|
37
|
-
publications.shift();
|
|
38
|
-
if (publications.length > 0) schedulePublication();
|
|
39
33
|
});
|
|
40
34
|
});
|
|
41
35
|
promise.then((value) => {
|
|
42
|
-
|
|
36
|
+
schedulePublication({
|
|
43
37
|
publish: () => publish({
|
|
44
38
|
ok: true,
|
|
45
39
|
value
|
|
@@ -47,7 +41,7 @@ function resumeWithContext(context, promise) {
|
|
|
47
41
|
reject
|
|
48
42
|
});
|
|
49
43
|
}, (exception) => {
|
|
50
|
-
|
|
44
|
+
schedulePublication({
|
|
51
45
|
publish: () => publish({
|
|
52
46
|
ok: false,
|
|
53
47
|
exception
|
|
@@ -57,17 +51,18 @@ function resumeWithContext(context, promise) {
|
|
|
57
51
|
});
|
|
58
52
|
});
|
|
59
53
|
}
|
|
60
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Resolve one transformed await per task, inside a fresh actor slice. Admission
|
|
56
|
+
* attempts are independent so a blocked actor cannot stall the actor that will
|
|
57
|
+
* unblock it. The task boundary keeps each continuation ambient isolated.
|
|
58
|
+
*/
|
|
59
|
+
function schedulePublication(publication) {
|
|
61
60
|
const channel = new MessageChannel();
|
|
62
61
|
channel.port1.onmessage = () => {
|
|
63
62
|
channel.port1.close();
|
|
64
63
|
channel.port2.close();
|
|
65
|
-
const publication = publications[0];
|
|
66
|
-
if (publication === void 0) return;
|
|
67
64
|
publication.publish().catch((exception) => {
|
|
68
65
|
publication.reject(exception);
|
|
69
|
-
publications.shift();
|
|
70
|
-
if (publications.length > 0) schedulePublication();
|
|
71
66
|
});
|
|
72
67
|
};
|
|
73
68
|
channel.port2.postMessage(void 0);
|
package/dist/gate.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gate.js","names":[],"sources":["../src/gate.ts"],"sourcesContent":["/* @do-runtime-gated */\n\nimport { tryCurrentSlice, type IoContext } from \"./io/io-context\";\n\ntype ContinuationContext = {\n readonly context: IoContext;\n readonly token: object;\n};\n\nlet continuationContext: ContinuationContext | undefined;\n\ntype Publication = {\n readonly publish: () => Promise<void>;\n readonly reject: (exception: unknown) => void;\n};\n\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\
|
|
1
|
+
{"version":3,"file":"gate.js","names":[],"sources":["../src/gate.ts"],"sourcesContent":["/* @do-runtime-gated */\n\nimport { tryCurrentSlice, type IoContext } from \"./io/io-context\";\n\ntype ContinuationContext = {\n readonly context: IoContext;\n readonly token: object;\n};\n\nlet continuationContext: ContinuationContext | undefined;\n\ntype Publication = {\n readonly publish: () => Promise<void>;\n readonly reject: (exception: unknown) => void;\n};\n\ntype Outcome<T> =\n | { readonly ok: true; readonly value: T }\n | { readonly ok: false; readonly exception: unknown };\n\nfunction isThenable(value: unknown): value is PromiseLike<unknown> {\n return (\n (typeof value === \"object\" && value !== null) ||\n typeof value === \"function\"\n ) && typeof Reflect.get(value, \"then\") === \"function\";\n}\n\n/** Re-enter the actor that owns this transformed await; fail open outside actors. */\nexport function __gate<T>(value: T): T | Promise<Awaited<T>> {\n const context = tryCurrentSlice() ?? continuationContext?.context;\n if (!isThenable(value) && context === undefined) return value;\n if (context === undefined) return value;\n return resumeWithContext(context, Promise.resolve(value));\n}\n\nfunction resumeWithContext<T>(context: IoContext, promise: Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const publish = context.makeTransformReentryCallback((outcome: Outcome<T>) => {\n if (continuationContext !== undefined) {\n schedulePublication({ publish: () => publish(outcome), reject });\n return;\n }\n const token = {};\n continuationContext = { context, token };\n if (outcome.ok) resolve(outcome.value);\n else reject(outcome.exception);\n queueMicrotask(() => {\n if (continuationContext?.token === token) continuationContext = undefined;\n });\n });\n void promise.then(\n (value) => {\n schedulePublication({ publish: () => publish({ ok: true, value }), reject });\n },\n (exception: unknown) => {\n schedulePublication({ publish: () => publish({ ok: false, exception }), reject });\n },\n );\n });\n}\n\n/**\n * Resolve one transformed await per task, inside a fresh actor slice. Admission\n * attempts are independent so a blocked actor cannot stall the actor that will\n * unblock it. The task boundary keeps each continuation ambient isolated.\n */\nfunction schedulePublication(publication: Publication): void {\n const channel = new MessageChannel();\n channel.port1.onmessage = () => {\n channel.port1.close();\n channel.port2.close();\n\n void publication.publish().catch((exception: unknown) => {\n publication.reject(exception);\n });\n };\n channel.port2.postMessage(undefined);\n}\n\nfunction iteratorFor<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> | Iterator<T> {\n const subject = Object(iterable);\n const asyncIterator: unknown = Reflect.get(subject, Symbol.asyncIterator);\n if (typeof asyncIterator === \"function\") return Reflect.apply(asyncIterator, iterable, []);\n const iterator: unknown = Reflect.get(subject, Symbol.iterator);\n if (typeof iterator === \"function\") return Reflect.apply(iterator, iterable, []);\n throw new TypeError(\"value is not async iterable or iterable\");\n}\n\nfunction gatedIterator<T>(iterable: AsyncIterable<T> | Iterable<T>): AsyncIterator<T> {\n const iterator = iteratorFor(iterable);\n\n function invoke(methodName: \"next\" | \"return\" | \"throw\", args: unknown[]): Promise<IteratorResult<T>> {\n const method: unknown = Reflect.get(iterator, methodName);\n if (typeof method === \"function\") {\n return Promise.resolve(__gate(Reflect.apply(method, iterator, args)));\n }\n if (methodName === \"throw\") return Promise.reject(args[0]);\n return Promise.resolve({ done: true, value: args[0] });\n }\n\n return {\n next: (...args: [] | [unknown]) => invoke(\"next\", args),\n return: (value?: unknown) => invoke(\"return\", [value]),\n throw: (exception?: unknown) => invoke(\"throw\", [exception]),\n };\n}\n\n/** Gate every operation used by `for await`, including early return and throw. */\nexport function __gateAsyncIterable<T, IterableType extends AsyncIterable<T> | Iterable<T>>(\n iterable: IterableType,\n): IterableType;\nexport function __gateAsyncIterable<T>(\n iterable: AsyncIterable<T> | Iterable<T>,\n): AsyncIterable<T> | Iterable<T> {\n const wrapper: AsyncIterable<T> = {\n [Symbol.asyncIterator]: () => gatedIterator(iterable),\n };\n if ((typeof iterable !== \"object\" || iterable === null) && typeof iterable !== \"function\") {\n return wrapper;\n }\n return new Proxy(iterable, {\n get(target, property, receiver): unknown {\n if (property === Symbol.asyncIterator) return wrapper[Symbol.asyncIterator];\n return Reflect.get(target, property, receiver);\n },\n });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-b/do-runtime",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Cloudflare's Durable Object runtime (workerd), ported to TypeScript: actors with input/output gates, SQLite storage, facets and alarms, running in the browser and in Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"actors",
|