@resonatehq/supabase 0.1.10 → 0.1.11
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/dist/index.d.ts +11 -2
- package/dist/index.js +39 -31
- package/package.json +1 -1
- package/src/index.ts +63 -47
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Context, type Encryptor, type Func } from "@resonatehq/sdk";
|
|
2
|
+
type OnTerminateCallback = (result: {
|
|
3
|
+
status: "completed";
|
|
4
|
+
result?: any;
|
|
5
|
+
} | {
|
|
6
|
+
status: "suspended";
|
|
7
|
+
waitingOn: string[];
|
|
8
|
+
}) => Promise<void>;
|
|
2
9
|
export { Context };
|
|
3
10
|
export declare class Resonate {
|
|
4
11
|
private registry;
|
|
5
12
|
private dependencies;
|
|
6
13
|
private verbose;
|
|
7
14
|
private encryptor;
|
|
15
|
+
private encoder;
|
|
8
16
|
constructor({ verbose, encryptor, }?: {
|
|
9
17
|
verbose?: boolean;
|
|
10
18
|
encryptor?: Encryptor;
|
|
@@ -16,6 +24,7 @@ export declare class Resonate {
|
|
|
16
24
|
version?: number;
|
|
17
25
|
}): void;
|
|
18
26
|
setDependency(name: string, obj: any): void;
|
|
19
|
-
handler(req: Request): Promise<Response>;
|
|
20
|
-
|
|
27
|
+
handler(req: Request, onTerminate?: OnTerminateCallback): Promise<Response>;
|
|
28
|
+
private decrypt;
|
|
29
|
+
httpHandler(onTerminate?: OnTerminateCallback): Deno.HttpServer;
|
|
21
30
|
}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export class Resonate {
|
|
|
5
5
|
this.dependencies = new Map();
|
|
6
6
|
this.verbose = verbose;
|
|
7
7
|
this.encryptor = encryptor ?? new NoopEncryptor();
|
|
8
|
+
this.encoder = new JsonEncoder();
|
|
8
9
|
}
|
|
9
10
|
register(nameOrFunc, funcOrOptions, maybeOptions = {}) {
|
|
10
11
|
const { version = 1 } = (typeof funcOrOptions === "object" ? funcOrOptions : maybeOptions) ?? {};
|
|
@@ -15,7 +16,7 @@ export class Resonate {
|
|
|
15
16
|
setDependency(name, obj) {
|
|
16
17
|
this.dependencies.set(name, obj);
|
|
17
18
|
}
|
|
18
|
-
async handler(req) {
|
|
19
|
+
async handler(req, onTerminate) {
|
|
19
20
|
try {
|
|
20
21
|
if (req.method !== "POST") {
|
|
21
22
|
return new Response(JSON.stringify({ error: "Method not allowed. Use POST." }), {
|
|
@@ -40,7 +41,6 @@ export class Resonate {
|
|
|
40
41
|
status: 400,
|
|
41
42
|
});
|
|
42
43
|
}
|
|
43
|
-
const encoder = new JsonEncoder();
|
|
44
44
|
const clock = new WallClock();
|
|
45
45
|
const tracer = new NoopTracer();
|
|
46
46
|
const network = new HttpNetwork({
|
|
@@ -56,7 +56,7 @@ export class Resonate {
|
|
|
56
56
|
ttl: 30 * 1000,
|
|
57
57
|
clock,
|
|
58
58
|
network,
|
|
59
|
-
handler: new Handler(network, encoder, this.encryptor),
|
|
59
|
+
handler: new Handler(network, this.encoder, this.encryptor),
|
|
60
60
|
registry: this.registry,
|
|
61
61
|
heartbeat: new NoopHeartbeat(),
|
|
62
62
|
dependencies: this.dependencies,
|
|
@@ -68,39 +68,39 @@ export class Resonate {
|
|
|
68
68
|
tracer,
|
|
69
69
|
});
|
|
70
70
|
const task = { kind: "unclaimed", task: body.task };
|
|
71
|
-
|
|
71
|
+
return new Promise((resolve, reject) => {
|
|
72
72
|
resonateInner.process(tracer.startSpan(task.task.rootPromiseId, clock.now()), task, (error, status) => {
|
|
73
73
|
if (error || !status) {
|
|
74
|
-
|
|
74
|
+
return reject({
|
|
75
75
|
error: "Task processing failed",
|
|
76
76
|
details: { error, status },
|
|
77
|
-
})
|
|
78
|
-
status: 500,
|
|
79
|
-
}));
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
if (status.kind === "completed") {
|
|
83
|
-
resolve(new Response(JSON.stringify({
|
|
84
|
-
status: "completed",
|
|
85
|
-
result: status.promise.value,
|
|
86
|
-
requestUrl: url,
|
|
87
|
-
}), {
|
|
88
|
-
status: 200,
|
|
89
|
-
}));
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
else if (status.kind === "suspended") {
|
|
93
|
-
resolve(new Response(JSON.stringify({
|
|
94
|
-
status: "suspended",
|
|
95
|
-
requestUrl: url,
|
|
96
|
-
}), {
|
|
97
|
-
status: 200,
|
|
98
|
-
}));
|
|
99
|
-
return;
|
|
77
|
+
});
|
|
100
78
|
}
|
|
79
|
+
return resolve({
|
|
80
|
+
...(status.kind === "completed"
|
|
81
|
+
? { status: status.kind, result: status.promise.value }
|
|
82
|
+
: {
|
|
83
|
+
status: status.kind,
|
|
84
|
+
waitingOn: status.callbacks.map((cb) => cb.promiseId),
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
101
87
|
});
|
|
88
|
+
})
|
|
89
|
+
.then(async (res) => {
|
|
90
|
+
try {
|
|
91
|
+
await onTerminate?.(this.decrypt(res));
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
console.error("onTerminate failed", e);
|
|
95
|
+
}
|
|
96
|
+
return new Response(JSON.stringify({
|
|
97
|
+
...res,
|
|
98
|
+
requestUrl: url,
|
|
99
|
+
}), { status: 200 });
|
|
100
|
+
})
|
|
101
|
+
.catch((err) => {
|
|
102
|
+
return new Response(JSON.stringify(err), { status: 500 });
|
|
102
103
|
});
|
|
103
|
-
return completion;
|
|
104
104
|
}
|
|
105
105
|
catch (error) {
|
|
106
106
|
return new Response(JSON.stringify({
|
|
@@ -108,9 +108,17 @@ export class Resonate {
|
|
|
108
108
|
}), { status: 500 });
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
decrypt(res) {
|
|
112
|
+
if (res.status !== "completed")
|
|
113
|
+
return res;
|
|
114
|
+
return {
|
|
115
|
+
...res,
|
|
116
|
+
result: this.encoder.decode(this.encryptor.decrypt(res.result)),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
httpHandler(onTerminate) {
|
|
112
120
|
return Deno.serve(async (req) => {
|
|
113
|
-
return await this.handler(req);
|
|
121
|
+
return await this.handler(req, onTerminate);
|
|
114
122
|
});
|
|
115
123
|
}
|
|
116
124
|
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -15,6 +15,12 @@ import {
|
|
|
15
15
|
WallClock,
|
|
16
16
|
} from "@resonatehq/sdk";
|
|
17
17
|
|
|
18
|
+
type OnTerminateCallback = (
|
|
19
|
+
result:
|
|
20
|
+
| { status: "completed"; result?: any }
|
|
21
|
+
| { status: "suspended"; waitingOn: string[] },
|
|
22
|
+
) => Promise<void>;
|
|
23
|
+
|
|
18
24
|
export { Context };
|
|
19
25
|
|
|
20
26
|
export class Resonate {
|
|
@@ -22,6 +28,7 @@ export class Resonate {
|
|
|
22
28
|
private dependencies = new Map<string, any>();
|
|
23
29
|
private verbose: boolean;
|
|
24
30
|
private encryptor: Encryptor;
|
|
31
|
+
private encoder: JsonEncoder;
|
|
25
32
|
|
|
26
33
|
constructor({
|
|
27
34
|
verbose = false,
|
|
@@ -29,6 +36,7 @@ export class Resonate {
|
|
|
29
36
|
}: { verbose?: boolean; encryptor?: Encryptor } = {}) {
|
|
30
37
|
this.verbose = verbose;
|
|
31
38
|
this.encryptor = encryptor ?? new NoopEncryptor();
|
|
39
|
+
this.encoder = new JsonEncoder();
|
|
32
40
|
}
|
|
33
41
|
|
|
34
42
|
public register<F extends Func>(
|
|
@@ -68,7 +76,10 @@ export class Resonate {
|
|
|
68
76
|
this.dependencies.set(name, obj);
|
|
69
77
|
}
|
|
70
78
|
|
|
71
|
-
public async handler(
|
|
79
|
+
public async handler(
|
|
80
|
+
req: Request,
|
|
81
|
+
onTerminate?: OnTerminateCallback,
|
|
82
|
+
): Promise<Response> {
|
|
72
83
|
try {
|
|
73
84
|
if (req.method !== "POST") {
|
|
74
85
|
return new Response(
|
|
@@ -109,7 +120,6 @@ export class Resonate {
|
|
|
109
120
|
);
|
|
110
121
|
}
|
|
111
122
|
|
|
112
|
-
const encoder = new JsonEncoder();
|
|
113
123
|
const clock = new WallClock();
|
|
114
124
|
const tracer = new NoopTracer();
|
|
115
125
|
const network = new HttpNetwork({
|
|
@@ -126,7 +136,7 @@ export class Resonate {
|
|
|
126
136
|
ttl: 30 * 1000,
|
|
127
137
|
clock,
|
|
128
138
|
network,
|
|
129
|
-
handler: new Handler(network, encoder, this.encryptor),
|
|
139
|
+
handler: new Handler(network, this.encoder, this.encryptor),
|
|
130
140
|
registry: this.registry,
|
|
131
141
|
heartbeat: new NoopHeartbeat(),
|
|
132
142
|
dependencies: this.dependencies,
|
|
@@ -140,58 +150,49 @@ export class Resonate {
|
|
|
140
150
|
|
|
141
151
|
const task: Task = { kind: "unclaimed", task: body.task };
|
|
142
152
|
|
|
143
|
-
|
|
153
|
+
return new Promise<
|
|
154
|
+
| { status: "completed"; result?: any }
|
|
155
|
+
| { status: "suspended"; waitingOn: string[] }
|
|
156
|
+
>((resolve, reject) => {
|
|
144
157
|
resonateInner.process(
|
|
145
158
|
tracer.startSpan(task.task.rootPromiseId, clock.now()),
|
|
146
159
|
task,
|
|
147
160
|
(error, status) => {
|
|
148
161
|
if (error || !status) {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
details: { error, status },
|
|
154
|
-
}),
|
|
155
|
-
{
|
|
156
|
-
status: 500,
|
|
157
|
-
},
|
|
158
|
-
),
|
|
159
|
-
);
|
|
160
|
-
return;
|
|
162
|
+
return reject({
|
|
163
|
+
error: "Task processing failed",
|
|
164
|
+
details: { error, status },
|
|
165
|
+
});
|
|
161
166
|
}
|
|
162
167
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
status:
|
|
168
|
-
|
|
169
|
-
requestUrl: url,
|
|
168
|
+
return resolve({
|
|
169
|
+
...(status.kind === "completed"
|
|
170
|
+
? { status: status.kind, result: status.promise.value }
|
|
171
|
+
: {
|
|
172
|
+
status: status.kind,
|
|
173
|
+
waitingOn: status.callbacks.map((cb) => cb.promiseId),
|
|
170
174
|
}),
|
|
171
|
-
|
|
172
|
-
status: 200,
|
|
173
|
-
},
|
|
174
|
-
),
|
|
175
|
-
);
|
|
176
|
-
return;
|
|
177
|
-
} else if (status.kind === "suspended") {
|
|
178
|
-
resolve(
|
|
179
|
-
new Response(
|
|
180
|
-
JSON.stringify({
|
|
181
|
-
status: "suspended",
|
|
182
|
-
requestUrl: url,
|
|
183
|
-
}),
|
|
184
|
-
{
|
|
185
|
-
status: 200,
|
|
186
|
-
},
|
|
187
|
-
),
|
|
188
|
-
);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
175
|
+
});
|
|
191
176
|
},
|
|
192
177
|
);
|
|
193
|
-
})
|
|
194
|
-
|
|
178
|
+
})
|
|
179
|
+
.then(async (res) => {
|
|
180
|
+
try {
|
|
181
|
+
await onTerminate?.(this.decrypt(res));
|
|
182
|
+
} catch (e) {
|
|
183
|
+
console.error("onTerminate failed", e);
|
|
184
|
+
}
|
|
185
|
+
return new Response(
|
|
186
|
+
JSON.stringify({
|
|
187
|
+
...res,
|
|
188
|
+
requestUrl: url,
|
|
189
|
+
}),
|
|
190
|
+
{ status: 200 },
|
|
191
|
+
);
|
|
192
|
+
})
|
|
193
|
+
.catch((err) => {
|
|
194
|
+
return new Response(JSON.stringify(err), { status: 500 });
|
|
195
|
+
});
|
|
195
196
|
} catch (error) {
|
|
196
197
|
return new Response(
|
|
197
198
|
JSON.stringify({
|
|
@@ -202,9 +203,24 @@ export class Resonate {
|
|
|
202
203
|
}
|
|
203
204
|
}
|
|
204
205
|
|
|
205
|
-
|
|
206
|
+
private decrypt(
|
|
207
|
+
res:
|
|
208
|
+
| { status: "completed"; result?: any }
|
|
209
|
+
| { status: "suspended"; waitingOn: string[] },
|
|
210
|
+
):
|
|
211
|
+
| { status: "completed"; result?: any }
|
|
212
|
+
| { status: "suspended"; waitingOn: string[] } {
|
|
213
|
+
if (res.status !== "completed") return res;
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
...res,
|
|
217
|
+
result: this.encoder.decode(this.encryptor.decrypt(res.result)),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public httpHandler(onTerminate?: OnTerminateCallback): Deno.HttpServer {
|
|
206
222
|
return Deno.serve(async (req: Request) => {
|
|
207
|
-
return await this.handler(req);
|
|
223
|
+
return await this.handler(req, onTerminate);
|
|
208
224
|
});
|
|
209
225
|
}
|
|
210
226
|
}
|