optio-api 0.1.0
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/LICENSE +201 -0
- package/README.md +244 -0
- package/dist/_generated/optio-engine.d.ts +69 -0
- package/dist/_generated/optio-engine.d.ts.map +1 -0
- package/dist/_generated/optio-engine.js +31 -0
- package/dist/_generated/optio-engine.js.map +1 -0
- package/dist/adapters/express.d.ts +24 -0
- package/dist/adapters/express.d.ts.map +1 -0
- package/dist/adapters/express.js +186 -0
- package/dist/adapters/express.js.map +1 -0
- package/dist/adapters/fastify.d.ts +38 -0
- package/dist/adapters/fastify.d.ts.map +1 -0
- package/dist/adapters/fastify.js +473 -0
- package/dist/adapters/fastify.js.map +1 -0
- package/dist/adapters/nextjs-app.d.ts +29 -0
- package/dist/adapters/nextjs-app.d.ts.map +1 -0
- package/dist/adapters/nextjs-app.js +220 -0
- package/dist/adapters/nextjs-app.js.map +1 -0
- package/dist/adapters/nextjs-pages.d.ts +29 -0
- package/dist/adapters/nextjs-pages.d.ts.map +1 -0
- package/dist/adapters/nextjs-pages.js +189 -0
- package/dist/adapters/nextjs-pages.js.map +1 -0
- package/dist/auth.d.ts +10 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +9 -0
- package/dist/auth.js.map +1 -0
- package/dist/context.d.ts +14 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +13 -0
- package/dist/context.js.map +1 -0
- package/dist/discovery.d.ts +10 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +48 -0
- package/dist/discovery.js.map +1 -0
- package/dist/handlers.d.ts +110 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +188 -0
- package/dist/handlers.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/metadata-filter-query.d.ts +13 -0
- package/dist/metadata-filter-query.d.ts.map +1 -0
- package/dist/metadata-filter-query.js +36 -0
- package/dist/metadata-filter-query.js.map +1 -0
- package/dist/optio-transports.d.ts +8 -0
- package/dist/optio-transports.d.ts.map +1 -0
- package/dist/optio-transports.js +37 -0
- package/dist/optio-transports.js.map +1 -0
- package/dist/process-id-resolver.d.ts +26 -0
- package/dist/process-id-resolver.d.ts.map +1 -0
- package/dist/process-id-resolver.js +31 -0
- package/dist/process-id-resolver.js.map +1 -0
- package/dist/resolve.d.ts +25 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +16 -0
- package/dist/resolve.js.map +1 -0
- package/dist/sse-options.d.ts +28 -0
- package/dist/sse-options.d.ts.map +1 -0
- package/dist/sse-options.js +82 -0
- package/dist/sse-options.js.map +1 -0
- package/dist/stream-poller.d.ts +21 -0
- package/dist/stream-poller.d.ts.map +1 -0
- package/dist/stream-poller.js +146 -0
- package/dist/stream-poller.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/widget-proxy-core.d.ts +7 -0
- package/dist/widget-proxy-core.d.ts.map +1 -0
- package/dist/widget-proxy-core.js +56 -0
- package/dist/widget-proxy-core.js.map +1 -0
- package/dist/widget-upstream-registry.d.ts +27 -0
- package/dist/widget-upstream-registry.d.ts.map +1 -0
- package/dist/widget-upstream-registry.js +28 -0
- package/dist/widget-upstream-registry.js.map +1 -0
- package/package.json +100 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared query-parsing helper for SSE / poller routes.
|
|
3
|
+
*
|
|
4
|
+
* Each adapter (fastify, express, nextjs-app, nextjs-pages) historically
|
|
5
|
+
* duplicated the same SSE/poller query-parsing block:
|
|
6
|
+
* - reject legacy `metadata.*` keys with a 400
|
|
7
|
+
* - parse the `metadataFilter` JSON via parseMetadataFilterQuery
|
|
8
|
+
* - coerce `maxDepth` from string to number
|
|
9
|
+
* - pass `database` / `prefix` through to resolveDb
|
|
10
|
+
*
|
|
11
|
+
* `parseSseOptions(rawQuery)` returns the parsed shape; it throws on bad
|
|
12
|
+
* `metadataFilter` JSON or bad `maxDepth` so adapters can map to a 400.
|
|
13
|
+
*
|
|
14
|
+
* `checkLegacyMetadataParams(rawQuery)` throws `LegacyMetadataParamError`
|
|
15
|
+
* when legacy `metadata.*` keys are present; adapters catch and emit 400.
|
|
16
|
+
*
|
|
17
|
+
* Database resolution stays in the adapter (a single
|
|
18
|
+
* `resolveDb(dbOpts, sseOpts)` line), per Task 5 / commit A4 of
|
|
19
|
+
* docs/2026-05-08-engine-rpc-migration-phase-3-design.md §3.
|
|
20
|
+
*/
|
|
21
|
+
import { parseMetadataFilterQuery, detectLegacyMetadataParams, formatLegacyMetadataMessage, } from './metadata-filter-query.js';
|
|
22
|
+
export class LegacyMetadataParamError extends Error {
|
|
23
|
+
keys;
|
|
24
|
+
constructor(keys) {
|
|
25
|
+
super(formatLegacyMetadataMessage(keys));
|
|
26
|
+
this.name = 'LegacyMetadataParamError';
|
|
27
|
+
this.keys = keys;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse SSE/poller query parameters into a typed shape. Throws Error on
|
|
32
|
+
* invalid `metadataFilter` JSON or on a non-finite/negative `maxDepth`;
|
|
33
|
+
* adapters should map a thrown Error to a 400 response.
|
|
34
|
+
*
|
|
35
|
+
* Does NOT inspect legacy `metadata.*` keys — call
|
|
36
|
+
* `checkLegacyMetadataParams` separately for that, since adapters want to
|
|
37
|
+
* distinguish the two error cases.
|
|
38
|
+
*/
|
|
39
|
+
export function parseSseOptions(rawQuery) {
|
|
40
|
+
const out = {};
|
|
41
|
+
if (typeof rawQuery.database === 'string')
|
|
42
|
+
out.database = rawQuery.database;
|
|
43
|
+
if (typeof rawQuery.prefix === 'string')
|
|
44
|
+
out.prefix = rawQuery.prefix;
|
|
45
|
+
// metadataFilter — parseMetadataFilterQuery returns a discriminated union
|
|
46
|
+
// { ok: true, value } | { ok: false, error }. We only forward the parsed
|
|
47
|
+
// object on success; on failure we throw so the adapter maps to a 400.
|
|
48
|
+
const mfRaw = rawQuery.metadataFilter;
|
|
49
|
+
if (mfRaw !== undefined && mfRaw !== null && mfRaw !== '') {
|
|
50
|
+
const parsed = parseMetadataFilterQuery(typeof mfRaw === 'string' ? mfRaw : undefined);
|
|
51
|
+
if (!parsed.ok) {
|
|
52
|
+
throw new Error(parsed.error);
|
|
53
|
+
}
|
|
54
|
+
out.metadataFilter = parsed.value;
|
|
55
|
+
}
|
|
56
|
+
// maxDepth — coerce string to int. parseInt returns NaN on garbage, which
|
|
57
|
+
// !Number.isFinite catches. Negative depths are also invalid.
|
|
58
|
+
const maxDepthRaw = rawQuery.maxDepth;
|
|
59
|
+
if (typeof maxDepthRaw === 'string' && maxDepthRaw.length > 0) {
|
|
60
|
+
const n = parseInt(maxDepthRaw, 10);
|
|
61
|
+
if (!Number.isFinite(n) || n < 0) {
|
|
62
|
+
throw new Error(`Invalid maxDepth: ${maxDepthRaw}`);
|
|
63
|
+
}
|
|
64
|
+
out.maxDepth = n;
|
|
65
|
+
}
|
|
66
|
+
else if (typeof maxDepthRaw === 'number' && Number.isFinite(maxDepthRaw) && maxDepthRaw >= 0) {
|
|
67
|
+
out.maxDepth = maxDepthRaw;
|
|
68
|
+
}
|
|
69
|
+
return out;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Throws `LegacyMetadataParamError` if the raw query contains any legacy
|
|
73
|
+
* `metadata.*` keys (a removed pre-`metadataFilter` API). Adapters catch
|
|
74
|
+
* this and emit a 400 with the formatted migration message.
|
|
75
|
+
*/
|
|
76
|
+
export function checkLegacyMetadataParams(rawQuery) {
|
|
77
|
+
const legacyKeys = detectLegacyMetadataParams(rawQuery);
|
|
78
|
+
if (legacyKeys.length > 0) {
|
|
79
|
+
throw new LegacyMetadataParamError(legacyKeys);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=sse-options.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse-options.js","sourceRoot":"","sources":["../src/sse-options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAGpC,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACjC,IAAI,CAAW;IAC/B,YAAY,IAAc;QACxB,KAAK,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AASD;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAiC;IAEjC,MAAM,GAAG,GAAqB,EAAE,CAAC;IAEjC,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;IAC5E,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ;QAAE,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAEtE,0EAA0E;IAC1E,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC;IACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC1D,MAAM,MAAM,GAAG,wBAAwB,CACrC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAC9C,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC;IACpC,CAAC;IAED,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACtC,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,MAAM,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC;IACnB,CAAC;SAAM,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QAC/F,GAAG,CAAC,QAAQ,GAAG,WAAW,CAAC;IAC7B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,QAAiC;IAEjC,MAAM,UAAU,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,wBAAwB,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Db } from 'mongodb';
|
|
2
|
+
import type { ProcessMetadataFilter } from 'optio-contracts';
|
|
3
|
+
export interface StreamPollerOptions {
|
|
4
|
+
db: Db;
|
|
5
|
+
prefix: string;
|
|
6
|
+
sendEvent: (data: unknown) => void;
|
|
7
|
+
onError: () => void;
|
|
8
|
+
metadataFilter?: ProcessMetadataFilter;
|
|
9
|
+
}
|
|
10
|
+
export interface ListPollerHandle {
|
|
11
|
+
start(): void;
|
|
12
|
+
stop(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare function createListPoller(opts: StreamPollerOptions): ListPollerHandle;
|
|
15
|
+
export interface TreePollerOptions extends Omit<StreamPollerOptions, 'metadataFilter'> {
|
|
16
|
+
rootId: string;
|
|
17
|
+
baseDepth: number;
|
|
18
|
+
maxDepth?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function createTreePoller(opts: TreePollerOptions): ListPollerHandle;
|
|
21
|
+
//# sourceMappingURL=stream-poller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-poller.d.ts","sourceRoot":"","sources":["../src/stream-poller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAG7D,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,qBAAqB,CAAC;CACxC;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,gBAAgB,CA2D5E;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,gBAAgB,CAAC;IACpF,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,gBAAgB,CAqG1E"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { ObjectId } from 'mongodb';
|
|
2
|
+
import { metadataFilterToMongo } from './metadata-filter-query.js';
|
|
3
|
+
export function createListPoller(opts) {
|
|
4
|
+
const { db, prefix, sendEvent, onError, metadataFilter } = opts;
|
|
5
|
+
const col = db.collection(`${prefix}_processes`);
|
|
6
|
+
const filter = metadataFilterToMongo(metadataFilter);
|
|
7
|
+
let interval = null;
|
|
8
|
+
let lastSnapshot = '';
|
|
9
|
+
async function poll() {
|
|
10
|
+
try {
|
|
11
|
+
const allProcs = await col.find(filter).sort({ depth: 1, order: 1, _id: 1 }).toArray();
|
|
12
|
+
const snapshot = JSON.stringify(allProcs.map((p) => ({
|
|
13
|
+
id: p._id,
|
|
14
|
+
state: p.status?.state,
|
|
15
|
+
percent: p.progress?.percent,
|
|
16
|
+
message: p.progress?.message,
|
|
17
|
+
supportsResume: p.supportsResume ?? false,
|
|
18
|
+
hasSavedState: p.hasSavedState ?? false,
|
|
19
|
+
})));
|
|
20
|
+
if (snapshot !== lastSnapshot) {
|
|
21
|
+
lastSnapshot = snapshot;
|
|
22
|
+
sendEvent({
|
|
23
|
+
type: 'update',
|
|
24
|
+
processes: allProcs.map((p) => ({
|
|
25
|
+
_id: p._id.toString(),
|
|
26
|
+
processId: p.processId,
|
|
27
|
+
name: p.name,
|
|
28
|
+
status: p.status,
|
|
29
|
+
progress: p.progress,
|
|
30
|
+
cancellable: p.cancellable,
|
|
31
|
+
special: p.special,
|
|
32
|
+
warning: p.warning,
|
|
33
|
+
metadata: p.metadata,
|
|
34
|
+
depth: p.depth ?? 0,
|
|
35
|
+
supportsResume: p.supportsResume ?? false,
|
|
36
|
+
hasSavedState: p.hasSavedState ?? false,
|
|
37
|
+
})),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
stop();
|
|
43
|
+
onError();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function start() {
|
|
47
|
+
interval = setInterval(poll, 1000);
|
|
48
|
+
}
|
|
49
|
+
function stop() {
|
|
50
|
+
if (interval) {
|
|
51
|
+
clearInterval(interval);
|
|
52
|
+
interval = null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { start, stop };
|
|
56
|
+
}
|
|
57
|
+
export function createTreePoller(opts) {
|
|
58
|
+
const { db, prefix, sendEvent, onError, rootId, baseDepth, maxDepth } = opts;
|
|
59
|
+
const col = db.collection(`${prefix}_processes`);
|
|
60
|
+
let interval = null;
|
|
61
|
+
let lastSnapshot = '';
|
|
62
|
+
const lastLogCounts = new Map();
|
|
63
|
+
let firstPoll = true;
|
|
64
|
+
async function poll() {
|
|
65
|
+
try {
|
|
66
|
+
const filter = { rootId: new ObjectId(rootId) };
|
|
67
|
+
if (maxDepth !== undefined) {
|
|
68
|
+
filter.depth = { $lte: baseDepth + maxDepth };
|
|
69
|
+
}
|
|
70
|
+
const allProcs = await col.find(filter).sort({ depth: 1, order: 1 }).toArray();
|
|
71
|
+
const snapshot = JSON.stringify(allProcs.map((p) => ({
|
|
72
|
+
id: p._id, status: p.status, progress: p.progress,
|
|
73
|
+
widgetData: p.widgetData, uiWidget: p.uiWidget,
|
|
74
|
+
supportsResume: p.supportsResume ?? false,
|
|
75
|
+
hasSavedState: p.hasSavedState ?? false,
|
|
76
|
+
})));
|
|
77
|
+
if (snapshot !== lastSnapshot) {
|
|
78
|
+
lastSnapshot = snapshot;
|
|
79
|
+
sendEvent({
|
|
80
|
+
type: 'update',
|
|
81
|
+
processes: allProcs.map((p) => ({
|
|
82
|
+
_id: p._id.toString(),
|
|
83
|
+
parentId: p.parentId?.toString() ?? null,
|
|
84
|
+
name: p.name,
|
|
85
|
+
status: p.status,
|
|
86
|
+
progress: p.progress,
|
|
87
|
+
cancellable: p.cancellable ?? false,
|
|
88
|
+
depth: p.depth,
|
|
89
|
+
order: p.order,
|
|
90
|
+
widgetData: p.widgetData,
|
|
91
|
+
uiWidget: p.uiWidget,
|
|
92
|
+
supportsResume: p.supportsResume ?? false,
|
|
93
|
+
hasSavedState: p.hasSavedState ?? false,
|
|
94
|
+
})),
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
// Detect log changes
|
|
98
|
+
let logCleared = false;
|
|
99
|
+
const newLogEntries = [];
|
|
100
|
+
for (const p of allProcs) {
|
|
101
|
+
const pid = p._id.toString();
|
|
102
|
+
const logLen = (p.log ?? []).length;
|
|
103
|
+
const lastLen = lastLogCounts.get(pid) ?? 0;
|
|
104
|
+
if (logLen < lastLen) {
|
|
105
|
+
logCleared = true;
|
|
106
|
+
lastLogCounts.set(pid, 0);
|
|
107
|
+
}
|
|
108
|
+
const effectiveLastLen = lastLogCounts.get(pid) ?? 0;
|
|
109
|
+
if (logLen > effectiveLastLen) {
|
|
110
|
+
const entries = (p.log ?? []).slice(firstPoll ? 0 : effectiveLastLen);
|
|
111
|
+
for (const entry of entries) {
|
|
112
|
+
newLogEntries.push({
|
|
113
|
+
...entry,
|
|
114
|
+
processId: pid,
|
|
115
|
+
processLabel: p.name,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
lastLogCounts.set(pid, logLen);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
firstPoll = false;
|
|
122
|
+
if (logCleared) {
|
|
123
|
+
sendEvent({ type: 'log-clear' });
|
|
124
|
+
}
|
|
125
|
+
if (newLogEntries.length > 0) {
|
|
126
|
+
newLogEntries.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
127
|
+
sendEvent({ type: 'log', entries: newLogEntries });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
stop();
|
|
132
|
+
onError();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function start() {
|
|
136
|
+
interval = setInterval(poll, 1000);
|
|
137
|
+
}
|
|
138
|
+
function stop() {
|
|
139
|
+
if (interval) {
|
|
140
|
+
clearInterval(interval);
|
|
141
|
+
interval = null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return { start, stop };
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=stream-poller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-poller.js","sourceRoot":"","sources":["../src/stream-poller.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Db } from 'mongodb';
|
|
2
|
+
import type { InnerAuthDoc, WidgetUpstreamRegistry, WidgetUpstreamValue } from './widget-upstream-registry.js';
|
|
3
|
+
export declare function resolveWidgetUpstream(db: Db, prefix: string, registry: WidgetUpstreamRegistry, processId: string): Promise<WidgetUpstreamValue | null>;
|
|
4
|
+
export declare function applyInnerAuthHeaders(innerAuth: InnerAuthDoc | null, headers: Record<string, string | string[] | undefined>): Record<string, string | string[] | undefined>;
|
|
5
|
+
export declare function applyInnerAuthQuery(innerAuth: InnerAuthDoc | null, url: string): string;
|
|
6
|
+
export declare function isWriteMethod(method: string): boolean;
|
|
7
|
+
//# sourceMappingURL=widget-proxy-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-proxy-core.d.ts","sourceRoot":"","sources":["../src/widget-proxy-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAE/G,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,EAAE,EACN,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,sBAAsB,EAChC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAkCrC;AAED,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,YAAY,GAAG,IAAI,EAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,GACrD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAc/C;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,YAAY,GAAG,IAAI,EAC9B,GAAG,EAAE,MAAM,GACV,MAAM,CAKR;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGrD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ObjectId } from 'mongodb';
|
|
2
|
+
export async function resolveWidgetUpstream(db, prefix, registry, processId) {
|
|
3
|
+
// Scope the cache by (database, prefix, processId) so the same ObjectId
|
|
4
|
+
// used in two different databases does not collide.
|
|
5
|
+
const cacheKey = `${db.databaseName}/${prefix}/${processId}`;
|
|
6
|
+
if (registry.has(cacheKey)) {
|
|
7
|
+
return registry.get(cacheKey) ?? null;
|
|
8
|
+
}
|
|
9
|
+
let oid;
|
|
10
|
+
try {
|
|
11
|
+
oid = new ObjectId(processId);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
// Don't cache: a malformed processId is a one-off URL and caching
|
|
15
|
+
// the negative would waste an entry; the 404 is cheap to re-derive.
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const doc = await db.collection(`${prefix}_processes`).findOne({ _id: oid }, { projection: { widgetUpstream: 1 } });
|
|
19
|
+
const upstream = (doc?.widgetUpstream ?? null);
|
|
20
|
+
// Only cache positive lookups. A null (no widgetUpstream registered yet
|
|
21
|
+
// or just cleared at teardown) must NOT stick in the cache: when the
|
|
22
|
+
// worker subsequently calls set_widget_upstream, the dashboard's first
|
|
23
|
+
// iframe load would otherwise see a stale negative entry and 404 until
|
|
24
|
+
// the TTL expired. The design spec calls for tree-poller-based
|
|
25
|
+
// invalidation to handle this; until that's wired, skipping the negative
|
|
26
|
+
// cache is the minimal correct behavior.
|
|
27
|
+
if (upstream !== null) {
|
|
28
|
+
registry.set(cacheKey, upstream);
|
|
29
|
+
}
|
|
30
|
+
return upstream;
|
|
31
|
+
}
|
|
32
|
+
export function applyInnerAuthHeaders(innerAuth, headers) {
|
|
33
|
+
if (!innerAuth)
|
|
34
|
+
return headers;
|
|
35
|
+
if (innerAuth.kind === 'basic') {
|
|
36
|
+
const encoded = Buffer.from(`${innerAuth.username}:${innerAuth.password}`).toString('base64');
|
|
37
|
+
return { ...headers, authorization: `Basic ${encoded}` };
|
|
38
|
+
}
|
|
39
|
+
if (innerAuth.kind === 'header') {
|
|
40
|
+
return { ...headers, [innerAuth.name.toLowerCase()]: innerAuth.value };
|
|
41
|
+
}
|
|
42
|
+
// query auth does not touch headers
|
|
43
|
+
return headers;
|
|
44
|
+
}
|
|
45
|
+
export function applyInnerAuthQuery(innerAuth, url) {
|
|
46
|
+
if (!innerAuth || innerAuth.kind !== 'query')
|
|
47
|
+
return url;
|
|
48
|
+
const separator = url.includes('?') ? '&' : '?';
|
|
49
|
+
const encodedValue = encodeURIComponent(innerAuth.value);
|
|
50
|
+
return `${url}${separator}${innerAuth.name}=${encodedValue}`;
|
|
51
|
+
}
|
|
52
|
+
export function isWriteMethod(method) {
|
|
53
|
+
const m = method.toUpperCase();
|
|
54
|
+
return m !== 'GET' && m !== 'HEAD' && m !== 'OPTIONS';
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=widget-proxy-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-proxy-core.js","sourceRoot":"","sources":["../src/widget-proxy-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAW,MAAM,SAAS,CAAC;AAG5C,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAM,EACN,MAAc,EACd,QAAgC,EAChC,SAAiB;IAEjB,wEAAwE;IACxE,oDAAoD;IACpD,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,YAAY,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;IAE7D,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;IACxC,CAAC;IAED,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;QAClE,oEAAoE;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,MAAM,YAAY,CAAC,CAAC,OAAO,CAC5D,EAAE,GAAG,EAAE,GAAG,EAAE,EACZ,EAAE,UAAU,EAAE,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,CACtC,CAAC;IACF,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,cAAc,IAAI,IAAI,CAA+B,CAAC;IAC7E,yEAAyE;IACzE,qEAAqE;IACrE,uEAAuE;IACvE,uEAAuE;IACvE,gEAAgE;IAChE,yEAAyE;IACzE,yCAAyC;IACzC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,SAA8B,EAC9B,OAAsD;IAEtD,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAC;IAE/B,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC9F,OAAO,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,SAAS,OAAO,EAAE,EAAE,CAAC;IAC3D,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC,KAAK,EAAE,CAAC;IACzE,CAAC;IAED,oCAAoC;IACpC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,SAA8B,EAC9B,GAAW;IAEX,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,GAAG,CAAC;IACzD,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,MAAM,YAAY,GAAG,kBAAkB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACzD,OAAO,GAAG,GAAG,GAAG,SAAS,GAAG,SAAS,CAAC,IAAI,IAAI,YAAY,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;IAC/B,OAAO,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,SAAS,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface WidgetUpstreamValue {
|
|
2
|
+
url: string;
|
|
3
|
+
innerAuth: InnerAuthDoc | null;
|
|
4
|
+
}
|
|
5
|
+
export type InnerAuthDoc = {
|
|
6
|
+
kind: 'basic';
|
|
7
|
+
username: string;
|
|
8
|
+
password: string;
|
|
9
|
+
} | {
|
|
10
|
+
kind: 'query';
|
|
11
|
+
name: string;
|
|
12
|
+
value: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'header';
|
|
15
|
+
name: string;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
export interface WidgetUpstreamRegistry {
|
|
19
|
+
get(processId: string): WidgetUpstreamValue | null | undefined;
|
|
20
|
+
has(processId: string): boolean;
|
|
21
|
+
set(processId: string, value: WidgetUpstreamValue | null): void;
|
|
22
|
+
invalidate(processId: string): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function createWidgetUpstreamRegistry(opts: {
|
|
25
|
+
ttlMs: number;
|
|
26
|
+
}): WidgetUpstreamRegistry;
|
|
27
|
+
//# sourceMappingURL=widget-upstream-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-upstream-registry.d.ts","sourceRoot":"","sources":["../src/widget-upstream-registry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,YAAY,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,WAAW,sBAAsB;IACrC,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;IAC/D,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI,GAAG,IAAI,CAAC;IAChE,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAOD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,sBAAsB,CA2B5F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function createWidgetUpstreamRegistry(opts) {
|
|
2
|
+
const cache = new Map();
|
|
3
|
+
function getEntry(processId) {
|
|
4
|
+
const entry = cache.get(processId);
|
|
5
|
+
if (!entry)
|
|
6
|
+
return undefined;
|
|
7
|
+
if (Date.now() > entry.expiresAt) {
|
|
8
|
+
cache.delete(processId);
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
return entry;
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
get(processId) {
|
|
15
|
+
return getEntry(processId)?.value;
|
|
16
|
+
},
|
|
17
|
+
has(processId) {
|
|
18
|
+
return getEntry(processId) !== undefined;
|
|
19
|
+
},
|
|
20
|
+
set(processId, value) {
|
|
21
|
+
cache.set(processId, { value, expiresAt: Date.now() + opts.ttlMs });
|
|
22
|
+
},
|
|
23
|
+
invalidate(processId) {
|
|
24
|
+
cache.delete(processId);
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=widget-upstream-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widget-upstream-registry.js","sourceRoot":"","sources":["../src/widget-upstream-registry.ts"],"names":[],"mappings":"AAsBA,MAAM,UAAU,4BAA4B,CAAC,IAAuB;IAClE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE7C,SAAS,QAAQ,CAAC,SAAiB;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAC7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACxB,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO;QACL,GAAG,CAAC,SAAS;YACX,OAAO,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC;QACpC,CAAC;QACD,GAAG,CAAC,SAAS;YACX,OAAO,QAAQ,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;QAC3C,CAAC;QACD,GAAG,CAAC,SAAS,EAAE,KAAK;YAClB,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,UAAU,CAAC,SAAS;YAClB,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "optio-api",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Server-side optio API with Fastify, Express, and Next.js adapters.",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/deai-network/optio.git",
|
|
9
|
+
"directory": "packages/optio-api"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/deai-network/optio/tree/main/packages/optio-api#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/deai-network/optio/issues"
|
|
14
|
+
},
|
|
15
|
+
"author": "Kristof Csillag <kristof.csillag@deai-labs.com>",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"import": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./fastify": {
|
|
28
|
+
"import": "./dist/adapters/fastify.js",
|
|
29
|
+
"types": "./dist/adapters/fastify.d.ts"
|
|
30
|
+
},
|
|
31
|
+
"./express": {
|
|
32
|
+
"import": "./dist/adapters/express.js",
|
|
33
|
+
"types": "./dist/adapters/express.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./nextjs/pages": {
|
|
36
|
+
"import": "./dist/adapters/nextjs-pages.js",
|
|
37
|
+
"types": "./dist/adapters/nextjs-pages.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./nextjs/app": {
|
|
40
|
+
"import": "./dist/adapters/nextjs-app.js",
|
|
41
|
+
"types": "./dist/adapters/nextjs-app.d.ts"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@clamator/over-redis": "^0.1.9",
|
|
46
|
+
"@clamator/protocol": "^0.1.9",
|
|
47
|
+
"@fastify/http-proxy": "^11.0.0",
|
|
48
|
+
"@ts-rest/core": "^3.51.0",
|
|
49
|
+
"ioredis": "^5.4.0",
|
|
50
|
+
"mongodb": "^6.12.0",
|
|
51
|
+
"zod": "^3",
|
|
52
|
+
"optio-contracts": "0.1.0"
|
|
53
|
+
},
|
|
54
|
+
"optionalDependencies": {
|
|
55
|
+
"@ts-rest/fastify": "^3.51.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"express": "^4.21.0 || ^5.0.0",
|
|
59
|
+
"fastify": "^5.2.0",
|
|
60
|
+
"next": "^13.0.0 || ^14.0.0 || ^15.0.0"
|
|
61
|
+
},
|
|
62
|
+
"peerDependenciesMeta": {
|
|
63
|
+
"fastify": {
|
|
64
|
+
"optional": true
|
|
65
|
+
},
|
|
66
|
+
"express": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"next": {
|
|
70
|
+
"optional": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@ts-rest/express": "^3.52.1",
|
|
75
|
+
"@ts-rest/next": "^3.52.1",
|
|
76
|
+
"@ts-rest/serverless": "^3.52.1",
|
|
77
|
+
"@types/express": "^5.0.6",
|
|
78
|
+
"@types/ioredis-mock": "^8.2.7",
|
|
79
|
+
"@types/supertest": "^7.2.0",
|
|
80
|
+
"@types/ws": "^8.5.0",
|
|
81
|
+
"eslint": "^10.3.0",
|
|
82
|
+
"express": "^5.2.1",
|
|
83
|
+
"ioredis-mock": "^8.13.1",
|
|
84
|
+
"mongodb-memory-server": "^11.0.1",
|
|
85
|
+
"next": "^16.2.1",
|
|
86
|
+
"node-mocks-http": "^1.17.2",
|
|
87
|
+
"supertest": "^7.2.2",
|
|
88
|
+
"typescript": "^5.7.0",
|
|
89
|
+
"typescript-eslint": "^8.59.3",
|
|
90
|
+
"vitest": "^3.0.0",
|
|
91
|
+
"ws": "^8.18.0"
|
|
92
|
+
},
|
|
93
|
+
"scripts": {
|
|
94
|
+
"build": "tsc",
|
|
95
|
+
"dev": "tsc --watch",
|
|
96
|
+
"test": "vitest run",
|
|
97
|
+
"test:watch": "vitest",
|
|
98
|
+
"lint": "eslint src --max-warnings=0"
|
|
99
|
+
}
|
|
100
|
+
}
|