@orq-ai/node 3.1.7 → 3.2.0-rc.4
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 +0 -38
- package/docs/sdks/deployments/README.md +0 -81
- package/jsr.json +1 -2
- package/lib/config.d.ts +2 -2
- package/lib/config.js +2 -2
- package/lib/config.js.map +1 -1
- package/lib/matchers.d.ts.map +1 -1
- package/lib/matchers.js +1 -4
- package/lib/matchers.js.map +1 -1
- package/models/operations/createcontact.js +2 -2
- package/models/operations/fileget.js +2 -2
- package/models/operations/filelist.js +2 -2
- package/models/operations/fileupload.js +2 -2
- package/models/operations/index.d.ts +0 -1
- package/models/operations/index.d.ts.map +1 -1
- package/models/operations/index.js +0 -1
- package/models/operations/index.js.map +1 -1
- package/package.json +3 -2
- package/sdk/deployments.d.ts +0 -8
- package/sdk/deployments.d.ts.map +1 -1
- package/sdk/deployments.js +0 -10
- package/sdk/deployments.js.map +1 -1
- package/src/lib/config.ts +2 -2
- package/src/lib/matchers.ts +1 -4
- package/src/models/operations/createcontact.ts +2 -2
- package/src/models/operations/fileget.ts +2 -2
- package/src/models/operations/filelist.ts +2 -2
- package/src/models/operations/fileupload.ts +2 -2
- package/src/models/operations/index.ts +0 -1
- package/src/sdk/deployments.ts +0 -19
- package/funcs/deploymentsStream.d.ts +0 -16
- package/funcs/deploymentsStream.d.ts.map +0 -1
- package/funcs/deploymentsStream.js +0 -126
- package/funcs/deploymentsStream.js.map +0 -1
- package/lib/event-streams.d.ts +0 -17
- package/lib/event-streams.d.ts.map +0 -1
- package/lib/event-streams.js +0 -220
- package/lib/event-streams.js.map +0 -1
- package/models/operations/deploymentstream.d.ts +0 -1622
- package/models/operations/deploymentstream.d.ts.map +0 -1
- package/models/operations/deploymentstream.js +0 -1571
- package/models/operations/deploymentstream.js.map +0 -1
- package/packages/orq-rc/FUNCTIONS.md +0 -106
- package/packages/orq-rc/README.md +0 -506
- package/packages/orq-rc/RUNTIMES.md +0 -48
- package/packages/orq-rc/docs/sdks/contacts/README.md +0 -84
- package/packages/orq-rc/docs/sdks/deployments/README.md +0 -235
- package/packages/orq-rc/docs/sdks/feedback/README.md +0 -92
- package/packages/orq-rc/docs/sdks/files/README.md +0 -305
- package/packages/orq-rc/docs/sdks/metrics/README.md +0 -86
- package/packages/orq-rc/docs/sdks/orq/README.md +0 -10
- package/packages/orq-rc/docs/sdks/prompts/README.md +0 -608
- package/packages/orq-rc/docs/sdks/remoteconfigs/README.md +0 -80
- package/packages/orq-rc/jsr.json +0 -27
- package/packages/orq-rc/package-lock.json +0 -1861
- package/packages/orq-rc/package.json +0 -31
- package/packages/orq-rc/src/core.ts +0 -13
- package/packages/orq-rc/src/funcs/contactsCreate.ts +0 -127
- package/packages/orq-rc/src/funcs/deploymentsGetConfig.ts +0 -135
- package/packages/orq-rc/src/funcs/deploymentsInvoke.ts +0 -143
- package/packages/orq-rc/src/funcs/deploymentsList.ts +0 -142
- package/packages/orq-rc/src/funcs/deploymentsMetricsCreate.ts +0 -135
- package/packages/orq-rc/src/funcs/feedbackCreate.ts +0 -127
- package/packages/orq-rc/src/funcs/filesCreate.ts +0 -150
- package/packages/orq-rc/src/funcs/filesDelete.ts +0 -131
- package/packages/orq-rc/src/funcs/filesGet.ts +0 -133
- package/packages/orq-rc/src/funcs/filesList.ts +0 -134
- package/packages/orq-rc/src/funcs/promptsCreate.ts +0 -127
- package/packages/orq-rc/src/funcs/promptsDelete.ts +0 -131
- package/packages/orq-rc/src/funcs/promptsGetVersion.ts +0 -147
- package/packages/orq-rc/src/funcs/promptsList.ts +0 -134
- package/packages/orq-rc/src/funcs/promptsListVersions.ts +0 -140
- package/packages/orq-rc/src/funcs/promptsRetrieve.ts +0 -133
- package/packages/orq-rc/src/funcs/promptsUpdate.ts +0 -139
- package/packages/orq-rc/src/funcs/remoteconfigsRetrieve.ts +0 -128
- package/packages/orq-rc/src/hooks/global.ts +0 -44
- package/packages/orq-rc/src/hooks/hooks.ts +0 -132
- package/packages/orq-rc/src/hooks/index.ts +0 -6
- package/packages/orq-rc/src/hooks/registration.ts +0 -15
- package/packages/orq-rc/src/hooks/types.ts +0 -110
- package/packages/orq-rc/src/index.ts +0 -7
- package/packages/orq-rc/src/lib/base64.ts +0 -37
- package/packages/orq-rc/src/lib/config.ts +0 -70
- package/packages/orq-rc/src/lib/dlv.ts +0 -53
- package/packages/orq-rc/src/lib/encodings.ts +0 -483
- package/packages/orq-rc/src/lib/env.ts +0 -73
- package/packages/orq-rc/src/lib/files.ts +0 -40
- package/packages/orq-rc/src/lib/http.ts +0 -323
- package/packages/orq-rc/src/lib/is-plain-object.ts +0 -43
- package/packages/orq-rc/src/lib/logger.ts +0 -9
- package/packages/orq-rc/src/lib/matchers.ts +0 -322
- package/packages/orq-rc/src/lib/primitives.ts +0 -136
- package/packages/orq-rc/src/lib/retries.ts +0 -218
- package/packages/orq-rc/src/lib/schemas.ts +0 -91
- package/packages/orq-rc/src/lib/sdks.ts +0 -400
- package/packages/orq-rc/src/lib/security.ts +0 -253
- package/packages/orq-rc/src/lib/url.ts +0 -33
- package/packages/orq-rc/src/models/components/deployments.ts +0 -1666
- package/packages/orq-rc/src/models/components/index.ts +0 -6
- package/packages/orq-rc/src/models/components/security.ts +0 -71
- package/packages/orq-rc/src/models/errors/apierror.ts +0 -27
- package/packages/orq-rc/src/models/errors/getpromptversion.ts +0 -71
- package/packages/orq-rc/src/models/errors/honoapierror.ts +0 -82
- package/packages/orq-rc/src/models/errors/httpclienterrors.ts +0 -62
- package/packages/orq-rc/src/models/errors/index.ts +0 -10
- package/packages/orq-rc/src/models/errors/sdkvalidationerror.ts +0 -97
- package/packages/orq-rc/src/models/errors/updateprompt.ts +0 -71
- package/packages/orq-rc/src/models/operations/createcontact.ts +0 -256
- package/packages/orq-rc/src/models/operations/createfeedback.ts +0 -286
- package/packages/orq-rc/src/models/operations/createprompt.ts +0 -3717
- package/packages/orq-rc/src/models/operations/deleteprompt.ts +0 -69
- package/packages/orq-rc/src/models/operations/deploymentcreatemetric.ts +0 -1790
- package/packages/orq-rc/src/models/operations/deploymentgetconfig.ts +0 -3527
- package/packages/orq-rc/src/models/operations/deploymentinvoke.ts +0 -1144
- package/packages/orq-rc/src/models/operations/deployments.ts +0 -2148
- package/packages/orq-rc/src/models/operations/filedelete.ts +0 -78
- package/packages/orq-rc/src/models/operations/fileget.ts +0 -222
- package/packages/orq-rc/src/models/operations/filelist.ts +0 -336
- package/packages/orq-rc/src/models/operations/fileupload.ts +0 -322
- package/packages/orq-rc/src/models/operations/getallprompts.ts +0 -2116
- package/packages/orq-rc/src/models/operations/getoneprompt.ts +0 -1982
- package/packages/orq-rc/src/models/operations/getpromptversion.ts +0 -2012
- package/packages/orq-rc/src/models/operations/index.ts +0 -22
- package/packages/orq-rc/src/models/operations/listpromptversions.ts +0 -2146
- package/packages/orq-rc/src/models/operations/remoteconfigsgetconfig.ts +0 -190
- package/packages/orq-rc/src/models/operations/updateprompt.ts +0 -3900
- package/packages/orq-rc/src/sdk/contacts.ts +0 -27
- package/packages/orq-rc/src/sdk/deployments.ts +0 -70
- package/packages/orq-rc/src/sdk/feedback.ts +0 -27
- package/packages/orq-rc/src/sdk/files.ts +0 -78
- package/packages/orq-rc/src/sdk/index.ts +0 -5
- package/packages/orq-rc/src/sdk/metrics.ts +0 -27
- package/packages/orq-rc/src/sdk/prompts.ts +0 -126
- package/packages/orq-rc/src/sdk/remoteconfigs.ts +0 -24
- package/packages/orq-rc/src/sdk/sdk.ts +0 -43
- package/packages/orq-rc/src/types/blobs.ts +0 -31
- package/packages/orq-rc/src/types/constdatetime.ts +0 -15
- package/packages/orq-rc/src/types/enums.ts +0 -16
- package/packages/orq-rc/src/types/fp.ts +0 -50
- package/packages/orq-rc/src/types/index.ts +0 -11
- package/packages/orq-rc/src/types/operations.ts +0 -105
- package/packages/orq-rc/src/types/rfcdate.ts +0 -54
- package/packages/orq-rc/src/types/streams.ts +0 -21
- package/packages/orq-rc/tsconfig.json +0 -41
- package/src/funcs/deploymentsStream.ts +0 -151
- package/src/lib/event-streams.ts +0 -264
- package/src/models/operations/deploymentstream.ts +0 -3062
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
const dateRE = /^\d{4}-\d{2}-\d{2}$/;
|
|
6
|
-
|
|
7
|
-
export class RFCDate {
|
|
8
|
-
private serialized: string;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Creates a new RFCDate instance using today's date.
|
|
12
|
-
*/
|
|
13
|
-
static today(): RFCDate {
|
|
14
|
-
return new RFCDate(new Date());
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Creates a new RFCDate instance using the provided input.
|
|
19
|
-
* If a string is used then in must be in the format YYYY-MM-DD.
|
|
20
|
-
*
|
|
21
|
-
* @param date A Date object or a date string in YYYY-MM-DD format
|
|
22
|
-
* @example
|
|
23
|
-
* new RFCDate("2022-01-01")
|
|
24
|
-
* @example
|
|
25
|
-
* new RFCDate(new Date())
|
|
26
|
-
*/
|
|
27
|
-
constructor(date: Date | string) {
|
|
28
|
-
if (typeof date === "string" && !dateRE.test(date)) {
|
|
29
|
-
throw new RangeError(
|
|
30
|
-
"RFCDate: date strings must be in the format YYYY-MM-DD: " + date,
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const value = new Date(date);
|
|
35
|
-
if (isNaN(+value)) {
|
|
36
|
-
throw new RangeError("RFCDate: invalid date provided: " + date);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
this.serialized = value.toISOString().slice(0, "YYYY-MM-DD".length);
|
|
40
|
-
if (!dateRE.test(this.serialized)) {
|
|
41
|
-
throw new TypeError(
|
|
42
|
-
`RFCDate: failed to build valid date with given value: ${date} serialized to ${this.serialized}`,
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
toJSON(): string {
|
|
48
|
-
return this.toString();
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
toString(): string {
|
|
52
|
-
return this.serialized;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export function isReadableStream<T = Uint8Array>(
|
|
6
|
-
val: unknown,
|
|
7
|
-
): val is ReadableStream<T> {
|
|
8
|
-
if (typeof val !== "object" || val === null) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Check for the presence of methods specific to ReadableStream
|
|
13
|
-
const stream = val as ReadableStream<Uint8Array>;
|
|
14
|
-
|
|
15
|
-
// ReadableStream has methods like getReader, cancel, and tee
|
|
16
|
-
return (
|
|
17
|
-
typeof stream.getReader === "function" &&
|
|
18
|
-
typeof stream.cancel === "function" &&
|
|
19
|
-
typeof stream.tee === "function"
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"incremental": true,
|
|
4
|
-
"tsBuildInfoFile": ".tsbuildinfo",
|
|
5
|
-
"target": "ES2020",
|
|
6
|
-
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
-
"jsx": "react-jsx",
|
|
8
|
-
|
|
9
|
-
"module": "Node16",
|
|
10
|
-
"moduleResolution": "Node16",
|
|
11
|
-
|
|
12
|
-
"allowJs": true,
|
|
13
|
-
|
|
14
|
-
"declaration": true,
|
|
15
|
-
"declarationMap": true,
|
|
16
|
-
"sourceMap": true,
|
|
17
|
-
"outDir": ".",
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// https://github.com/tsconfig/bases/blob/a1bf7c0fa2e094b068ca3e1448ca2ece4157977e/bases/strictest.json
|
|
21
|
-
"strict": true,
|
|
22
|
-
"allowUnusedLabels": false,
|
|
23
|
-
"allowUnreachableCode": false,
|
|
24
|
-
"exactOptionalPropertyTypes": true,
|
|
25
|
-
"useUnknownInCatchVariables": true,
|
|
26
|
-
"noFallthroughCasesInSwitch": true,
|
|
27
|
-
"noImplicitOverride": true,
|
|
28
|
-
"noImplicitReturns": true,
|
|
29
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
30
|
-
"noUncheckedIndexedAccess": true,
|
|
31
|
-
"noUnusedLocals": true,
|
|
32
|
-
"noUnusedParameters": true,
|
|
33
|
-
"isolatedModules": true,
|
|
34
|
-
"checkJs": true,
|
|
35
|
-
"esModuleInterop": true,
|
|
36
|
-
"skipLibCheck": true,
|
|
37
|
-
"forceConsistentCasingInFileNames": true
|
|
38
|
-
},
|
|
39
|
-
"include": ["src"],
|
|
40
|
-
"exclude": ["node_modules"]
|
|
41
|
-
}
|
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as z from "zod";
|
|
6
|
-
import { OrqCore } from "../core.js";
|
|
7
|
-
import { encodeJSON, encodeSimple } from "../lib/encodings.js";
|
|
8
|
-
import { EventStream } from "../lib/event-streams.js";
|
|
9
|
-
import * as M from "../lib/matchers.js";
|
|
10
|
-
import { compactMap } from "../lib/primitives.js";
|
|
11
|
-
import { safeParse } from "../lib/schemas.js";
|
|
12
|
-
import { RequestOptions } from "../lib/sdks.js";
|
|
13
|
-
import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js";
|
|
14
|
-
import { pathToFunc } from "../lib/url.js";
|
|
15
|
-
import { APIError } from "../models/errors/apierror.js";
|
|
16
|
-
import {
|
|
17
|
-
ConnectionError,
|
|
18
|
-
InvalidRequestError,
|
|
19
|
-
RequestAbortedError,
|
|
20
|
-
RequestTimeoutError,
|
|
21
|
-
UnexpectedClientError,
|
|
22
|
-
} from "../models/errors/httpclienterrors.js";
|
|
23
|
-
import { SDKValidationError } from "../models/errors/sdkvalidationerror.js";
|
|
24
|
-
import * as operations from "../models/operations/index.js";
|
|
25
|
-
import { Result } from "../types/fp.js";
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Stream
|
|
29
|
-
*
|
|
30
|
-
* @remarks
|
|
31
|
-
* Stream deployment generation. Only supported for completions and chat completions.
|
|
32
|
-
*/
|
|
33
|
-
export async function deploymentsStream(
|
|
34
|
-
client: OrqCore,
|
|
35
|
-
request: operations.DeploymentStreamRequestBody,
|
|
36
|
-
options?: RequestOptions,
|
|
37
|
-
): Promise<
|
|
38
|
-
Result<
|
|
39
|
-
EventStream<operations.DeploymentStreamResponseBody>,
|
|
40
|
-
| APIError
|
|
41
|
-
| SDKValidationError
|
|
42
|
-
| UnexpectedClientError
|
|
43
|
-
| InvalidRequestError
|
|
44
|
-
| RequestAbortedError
|
|
45
|
-
| RequestTimeoutError
|
|
46
|
-
| ConnectionError
|
|
47
|
-
>
|
|
48
|
-
> {
|
|
49
|
-
const parsed = safeParse(
|
|
50
|
-
request,
|
|
51
|
-
(value) =>
|
|
52
|
-
operations.DeploymentStreamRequestBody$outboundSchema.parse(value),
|
|
53
|
-
"Input validation failed",
|
|
54
|
-
);
|
|
55
|
-
if (!parsed.ok) {
|
|
56
|
-
return parsed;
|
|
57
|
-
}
|
|
58
|
-
const payload = parsed.value;
|
|
59
|
-
const body = encodeJSON("body", payload, { explode: true });
|
|
60
|
-
|
|
61
|
-
const path = pathToFunc("/v2/deployments/stream")();
|
|
62
|
-
|
|
63
|
-
const headers = new Headers(compactMap({
|
|
64
|
-
"Content-Type": "application/json",
|
|
65
|
-
Accept: "text/event-stream",
|
|
66
|
-
"contactId": encodeSimple("contactId", client._options.contactId, {
|
|
67
|
-
explode: false,
|
|
68
|
-
charEncoding: "none",
|
|
69
|
-
}),
|
|
70
|
-
"environment": encodeSimple("environment", client._options.environment, {
|
|
71
|
-
explode: false,
|
|
72
|
-
charEncoding: "none",
|
|
73
|
-
}),
|
|
74
|
-
}));
|
|
75
|
-
|
|
76
|
-
const secConfig = await extractSecurity(client._options.apiKey);
|
|
77
|
-
const securityInput = secConfig == null ? {} : { apiKey: secConfig };
|
|
78
|
-
const requestSecurity = resolveGlobalSecurity(securityInput);
|
|
79
|
-
|
|
80
|
-
const context = {
|
|
81
|
-
baseURL: options?.serverURL ?? "",
|
|
82
|
-
operationID: "DeploymentStream",
|
|
83
|
-
oAuth2Scopes: [],
|
|
84
|
-
|
|
85
|
-
resolvedSecurity: requestSecurity,
|
|
86
|
-
|
|
87
|
-
securitySource: client._options.apiKey,
|
|
88
|
-
retryConfig: options?.retries
|
|
89
|
-
|| client._options.retryConfig
|
|
90
|
-
|| { strategy: "none" },
|
|
91
|
-
retryCodes: options?.retryCodes || ["429", "500", "502", "503", "504"],
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const requestRes = client._createRequest(context, {
|
|
95
|
-
security: requestSecurity,
|
|
96
|
-
method: "POST",
|
|
97
|
-
baseURL: options?.serverURL,
|
|
98
|
-
path: path,
|
|
99
|
-
headers: headers,
|
|
100
|
-
body: body,
|
|
101
|
-
timeoutMs: options?.timeoutMs || client._options.timeoutMs || 600000,
|
|
102
|
-
}, options);
|
|
103
|
-
if (!requestRes.ok) {
|
|
104
|
-
return requestRes;
|
|
105
|
-
}
|
|
106
|
-
const req = requestRes.value;
|
|
107
|
-
|
|
108
|
-
const doResult = await client._do(req, {
|
|
109
|
-
context,
|
|
110
|
-
errorCodes: ["4XX", "5XX"],
|
|
111
|
-
retryConfig: context.retryConfig,
|
|
112
|
-
retryCodes: context.retryCodes,
|
|
113
|
-
});
|
|
114
|
-
if (!doResult.ok) {
|
|
115
|
-
return doResult;
|
|
116
|
-
}
|
|
117
|
-
const response = doResult.value;
|
|
118
|
-
|
|
119
|
-
const [result] = await M.match<
|
|
120
|
-
EventStream<operations.DeploymentStreamResponseBody>,
|
|
121
|
-
| APIError
|
|
122
|
-
| SDKValidationError
|
|
123
|
-
| UnexpectedClientError
|
|
124
|
-
| InvalidRequestError
|
|
125
|
-
| RequestAbortedError
|
|
126
|
-
| RequestTimeoutError
|
|
127
|
-
| ConnectionError
|
|
128
|
-
>(
|
|
129
|
-
M.sse(
|
|
130
|
-
200,
|
|
131
|
-
z.instanceof(ReadableStream<Uint8Array>).transform(stream => {
|
|
132
|
-
return new EventStream({
|
|
133
|
-
stream,
|
|
134
|
-
decoder(rawEvent) {
|
|
135
|
-
const schema =
|
|
136
|
-
operations.DeploymentStreamResponseBody$inboundSchema;
|
|
137
|
-
return schema.parse(rawEvent);
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
}),
|
|
141
|
-
{ sseSentinel: "[DONE]" },
|
|
142
|
-
),
|
|
143
|
-
M.fail("4XX"),
|
|
144
|
-
M.fail("5XX"),
|
|
145
|
-
)(response);
|
|
146
|
-
if (!result.ok) {
|
|
147
|
-
return result;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return result;
|
|
151
|
-
}
|
package/src/lib/event-streams.ts
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export type ServerEvent<T> = {
|
|
6
|
-
data?: T | undefined;
|
|
7
|
-
event?: string | undefined;
|
|
8
|
-
retry?: number | undefined;
|
|
9
|
-
id?: string | undefined;
|
|
10
|
-
};
|
|
11
|
-
const LF = 0x0a;
|
|
12
|
-
const CR = 0x0d;
|
|
13
|
-
const NEWLINE_CHARS = new Set([LF, CR]);
|
|
14
|
-
const MESSAGE_BOUNDARIES = [
|
|
15
|
-
new Uint8Array([CR, LF, CR, LF]),
|
|
16
|
-
new Uint8Array([CR, CR]),
|
|
17
|
-
new Uint8Array([LF, LF]),
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
export class EventStream<Event extends ServerEvent<unknown>> {
|
|
21
|
-
private readonly stream: ReadableStream<Uint8Array>;
|
|
22
|
-
private readonly decoder: (rawEvent: ServerEvent<string>) => Event;
|
|
23
|
-
|
|
24
|
-
constructor(init: {
|
|
25
|
-
stream: ReadableStream<Uint8Array>;
|
|
26
|
-
decoder: (rawEvent: ServerEvent<string>) => Event;
|
|
27
|
-
}) {
|
|
28
|
-
this.stream = init.stream;
|
|
29
|
-
this.decoder = init.decoder;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async *[Symbol.asyncIterator](): AsyncGenerator<Event, void, unknown> {
|
|
33
|
-
const reader = this.stream.getReader();
|
|
34
|
-
let buffer = new Uint8Array([]);
|
|
35
|
-
let position = 0;
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
while (true) {
|
|
39
|
-
const { done, value } = await reader.read();
|
|
40
|
-
if (done) {
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
45
|
-
newBuffer.set(buffer);
|
|
46
|
-
newBuffer.set(value, buffer.length);
|
|
47
|
-
buffer = newBuffer;
|
|
48
|
-
|
|
49
|
-
for (let i = position; i < buffer.length; i++) {
|
|
50
|
-
const boundary = findBoundary(buffer, i);
|
|
51
|
-
if (boundary == null) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const chunk = buffer.slice(position, i);
|
|
56
|
-
position = i + boundary.length;
|
|
57
|
-
const event = parseEvent(chunk, this.decoder);
|
|
58
|
-
if (event != null) {
|
|
59
|
-
yield event;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (position > 0) {
|
|
64
|
-
buffer = buffer.slice(position);
|
|
65
|
-
position = 0;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (buffer.length > 0) {
|
|
70
|
-
const event = parseEvent(buffer, this.decoder);
|
|
71
|
-
if (event != null) {
|
|
72
|
-
yield event;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
} catch (e: unknown) {
|
|
76
|
-
if (e instanceof Error && e.name === "AbortError") {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
throw e;
|
|
81
|
-
} finally {
|
|
82
|
-
reader.releaseLock();
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function findBoundary(buffer: Uint8Array, start: number): Uint8Array | null {
|
|
88
|
-
const char1 = buffer[start];
|
|
89
|
-
const char2 = buffer[start + 1];
|
|
90
|
-
|
|
91
|
-
// Don't bother checking if the first two characters are not new line
|
|
92
|
-
// characters.
|
|
93
|
-
if (
|
|
94
|
-
char1 == null
|
|
95
|
-
|| char2 == null
|
|
96
|
-
|| !NEWLINE_CHARS.has(char1)
|
|
97
|
-
|| !NEWLINE_CHARS.has(char2)
|
|
98
|
-
) {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
for (const s of MESSAGE_BOUNDARIES) {
|
|
103
|
-
const seq = peekSequence(start, buffer, s);
|
|
104
|
-
if (seq != null) {
|
|
105
|
-
return seq;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function peekSequence(
|
|
113
|
-
position: number,
|
|
114
|
-
buffer: Uint8Array,
|
|
115
|
-
sequence: Uint8Array,
|
|
116
|
-
): Uint8Array | null {
|
|
117
|
-
if (sequence.length > buffer.length - position) {
|
|
118
|
-
return null;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
for (let i = 0; i < sequence.length; i++) {
|
|
122
|
-
if (buffer[position + i] !== sequence[i]) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return sequence;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function parseEvent<Event extends ServerEvent<unknown>>(
|
|
131
|
-
chunk: Uint8Array,
|
|
132
|
-
decoder: (rawEvent: ServerEvent<string>) => Event,
|
|
133
|
-
) {
|
|
134
|
-
if (!chunk.length) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const td = new TextDecoder();
|
|
139
|
-
const raw = td.decode(chunk);
|
|
140
|
-
const lines = raw.split(/\r?\n|\r/g);
|
|
141
|
-
let publish = false;
|
|
142
|
-
const rawEvent: ServerEvent<string> = {};
|
|
143
|
-
|
|
144
|
-
for (const line of lines) {
|
|
145
|
-
if (!line) {
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const delim = line.indexOf(":");
|
|
150
|
-
// Lines starting with a colon are ignored.
|
|
151
|
-
if (delim === 0) {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
const field = delim > 0 ? line.substring(0, delim) : "";
|
|
156
|
-
let value = delim > 0 ? line.substring(delim + 1) : "";
|
|
157
|
-
if (value.charAt(0) === " ") {
|
|
158
|
-
value = value.substring(1);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
switch (field) {
|
|
162
|
-
case "event": {
|
|
163
|
-
publish = true;
|
|
164
|
-
rawEvent.event = value;
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
case "data": {
|
|
168
|
-
publish = true;
|
|
169
|
-
rawEvent.data ??= "";
|
|
170
|
-
rawEvent.data += value + "\n";
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
case "id": {
|
|
174
|
-
publish = true;
|
|
175
|
-
rawEvent.id = value;
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
case "retry": {
|
|
179
|
-
const r = parseInt(value, 10);
|
|
180
|
-
if (!Number.isNaN(r)) {
|
|
181
|
-
publish = true;
|
|
182
|
-
rawEvent.retry = r;
|
|
183
|
-
}
|
|
184
|
-
break;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
if (!publish) {
|
|
190
|
-
return null;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (rawEvent.data != null) {
|
|
194
|
-
rawEvent.data = rawEvent.data.slice(0, -1);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return decoder(rawEvent);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export function discardSentinel(
|
|
201
|
-
stream: ReadableStream<Uint8Array>,
|
|
202
|
-
sentinel: string,
|
|
203
|
-
): ReadableStream<Uint8Array> {
|
|
204
|
-
return new ReadableStream<Uint8Array>({
|
|
205
|
-
async start(controller) {
|
|
206
|
-
let buffer = new Uint8Array([]);
|
|
207
|
-
let position = 0;
|
|
208
|
-
let done = false;
|
|
209
|
-
let discard = false;
|
|
210
|
-
const rdr = stream.getReader();
|
|
211
|
-
try {
|
|
212
|
-
while (!done) {
|
|
213
|
-
const result = await rdr.read();
|
|
214
|
-
const value = result.value;
|
|
215
|
-
done = done || result.done;
|
|
216
|
-
// We keep consuming from the source to its completion so it can
|
|
217
|
-
// flush all its contents and release resources.
|
|
218
|
-
if (discard) {
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
if (typeof value === "undefined") {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const newBuffer = new Uint8Array(buffer.length + value.length);
|
|
226
|
-
newBuffer.set(buffer);
|
|
227
|
-
newBuffer.set(value, buffer.length);
|
|
228
|
-
buffer = newBuffer;
|
|
229
|
-
|
|
230
|
-
for (let i = position; i < buffer.length; i++) {
|
|
231
|
-
const boundary = findBoundary(buffer, i);
|
|
232
|
-
if (boundary == null) {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const start = position;
|
|
237
|
-
const chunk = buffer.slice(start, i);
|
|
238
|
-
position = i + boundary.length;
|
|
239
|
-
const event = parseEvent(chunk, id);
|
|
240
|
-
if (event?.data === sentinel) {
|
|
241
|
-
controller.enqueue(buffer.slice(0, start));
|
|
242
|
-
discard = true;
|
|
243
|
-
} else {
|
|
244
|
-
controller.enqueue(buffer.slice(0, position));
|
|
245
|
-
buffer = buffer.slice(position);
|
|
246
|
-
position = 0;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
} catch (e) {
|
|
251
|
-
controller.error(e);
|
|
252
|
-
} finally {
|
|
253
|
-
// If the source stream terminates, flush its contents and terminate.
|
|
254
|
-
// If the sentinel event was found, flush everything up to its start.
|
|
255
|
-
controller.close();
|
|
256
|
-
rdr.releaseLock();
|
|
257
|
-
}
|
|
258
|
-
},
|
|
259
|
-
});
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function id<T>(v: T): T {
|
|
263
|
-
return v;
|
|
264
|
-
}
|