@ontahi/runtime-nextjs 1.0.0-alpha.10 → 1.0.0-alpha.12
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
CHANGED
|
@@ -24,12 +24,19 @@ Export a `POST` handler from an App Router route such as `app/api/runtime/route.
|
|
|
24
24
|
import { createRuntimeProtocolDispatcher } from '@ontahi/core/runtime/protocol';
|
|
25
25
|
import { createNextRuntimeProtocolRouteHandler } from '@ontahi/runtime-nextjs/runtime-protocol';
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
type RuntimeAuthority = {
|
|
28
|
+
principal: Awaited<ReturnType<typeof resolvePrincipal>>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const dispatcher = createRuntimeProtocolDispatcher<RuntimeAuthority>({
|
|
28
32
|
handlers: {
|
|
29
|
-
operation:
|
|
33
|
+
operation: (request, authority) =>
|
|
34
|
+
TodoApplication.app.runtime.withInvocationContext(authority, () =>
|
|
35
|
+
operationDispatcher(request),
|
|
36
|
+
),
|
|
30
37
|
'durable.operation': durableObservationHandler,
|
|
31
|
-
'graph.read': graphReadDispatcher,
|
|
32
|
-
'graph.command': graphCommandDispatcher,
|
|
38
|
+
'graph.read': (request, authority) => graphReadDispatcher(request, { authority }),
|
|
39
|
+
'graph.command': (request, authority) => graphCommandDispatcher(request, { authority }),
|
|
33
40
|
},
|
|
34
41
|
});
|
|
35
42
|
|
|
@@ -44,13 +51,27 @@ export const POST = createNextRuntimeProtocolRouteHandler({
|
|
|
44
51
|
The adapter validates JSON, the common envelope, and the canonical family body before calling the
|
|
45
52
|
context factory. It installs no handlers, policies, authorization, or capabilities; the host owns
|
|
46
53
|
the dispatcher and derives trusted context only from the received server request. All registered
|
|
47
|
-
families pass through the same dispatcher without Next.js-specific routing.
|
|
54
|
+
families pass through the same dispatcher without Next.js-specific routing. Family adapters feed
|
|
55
|
+
the server-derived context to the canonical Operation and Graph policy boundaries; clients never
|
|
56
|
+
author authority or policies.
|
|
57
|
+
|
|
58
|
+
Point the Fetch client at the App Router route once; Operations, Graph Reads, Graph Commands, and
|
|
59
|
+
Durable inspection then share that Runtime Transport:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { createFetchGraphClient } from '@ontahi/react/graph';
|
|
63
|
+
|
|
64
|
+
const client = createFetchGraphClient({
|
|
65
|
+
runtimeTransport: { endpoint: '/api/runtime' },
|
|
66
|
+
});
|
|
67
|
+
```
|
|
48
68
|
|
|
49
69
|
Common invalid requests return `400`, a known family without an installed handler returns `501`,
|
|
50
70
|
unavailable dispatch returns `503`, invalid upstream responses return `502`, and complete family
|
|
51
71
|
responses—including semantic rejections and family protocol errors—return `200`. Existing
|
|
52
|
-
`operation-invocation` and `graph-read` adapters remain
|
|
53
|
-
|
|
72
|
+
`operation-invocation` and `graph-read` adapters remain explicit compatibility surfaces. Select
|
|
73
|
+
them with `createFetchGraphClient({ compatibility: ... })` only while a host is migrating; the
|
|
74
|
+
client never falls back or replays a transmitted request against a second endpoint.
|
|
54
75
|
|
|
55
76
|
## Operation invocation
|
|
56
77
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/graph-read/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAE1E,MAAM,MAAM,6BAA6B,CAAC,UAAU,IAAI,CACtD,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,OAAO,KACb,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,KAAK,sCAAsC,GAAG;IAC5C,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,sCAAsC,CAAC,UAAU,GAAG,iBAAiB,IAC/E,sCAAsC,GACpC,CACI;IACE,UAAU,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,GACD;IACE,UAAU,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC5C,SAAS,EAAE,6BAA6B,CAAC,UAAU,CAAC,CAAC;CACtD,CACJ,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/graph-read/route.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,mBAAmB,EAEzB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAErC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAE1E,MAAM,MAAM,6BAA6B,CAAC,UAAU,IAAI,CACtD,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,OAAO,KACb,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,KAAK,sCAAsC,GAAG;IAC5C,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;IACjD,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,MAAM,MAAM,sCAAsC,CAAC,UAAU,GAAG,iBAAiB,IAC/E,sCAAsC,GACpC,CACI;IACE,UAAU,EAAE,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;IACnD,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB,GACD;IACE,UAAU,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAC5C,SAAS,EAAE,6BAA6B,CAAC,UAAU,CAAC,CAAC;CACtD,CACJ,CAAC;AAUN,eAAO,MAAM,+BAA+B,GACzC,UAAU,EAAE,SAAS,sCAAsC,CAAC,UAAU,CAAC,MACjE,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAoCzC,CAAC"}
|
package/dist/graph-read/route.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { graphReadProtocolError,
|
|
1
|
+
import { graphReadProtocolError, parseGraphReadFamilyRequest, } from '@ontahi/core/data-graph';
|
|
2
2
|
import { getCurrentInvocationContext, withInvocationContext, } from '@ontahi/core/runtime/server';
|
|
3
3
|
const responseStatus = (response) => {
|
|
4
|
-
if (response.kind
|
|
4
|
+
if (response.kind !== 'protocol-error')
|
|
5
5
|
return 200;
|
|
6
6
|
if (response.error.code === 'access_denied')
|
|
7
7
|
return 403;
|
|
8
|
+
if (response.error.code === 'cardinality_mismatch')
|
|
9
|
+
return 409;
|
|
8
10
|
if (response.error.code === 'execution_unavailable')
|
|
9
11
|
return 503;
|
|
10
12
|
return 400;
|
|
11
13
|
};
|
|
12
14
|
export const createNextGraphReadRouteHandler = (options) => async (request) => {
|
|
13
|
-
const parsed =
|
|
15
|
+
const parsed = parseGraphReadFamilyRequest(await request.json().catch(() => null));
|
|
14
16
|
if (!parsed.success) {
|
|
15
17
|
return Response.json(parsed.error, { status: 400 });
|
|
16
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/graph-read/route.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../src/graph-read/route.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,2BAA2B,GAG5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GAEtB,MAAM,6BAA6B,CAAC;AA2BrC,MAAM,cAAc,GAAG,CAAC,QAAmC,EAAE,EAAE;IAC7D,IAAI,QAAQ,CAAC,IAAI,KAAK,gBAAgB;QAAE,OAAO,GAAG,CAAC;IACnD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,GAAG,CAAC;IACxD,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,sBAAsB;QAAE,OAAO,GAAG,CAAC;IAC/D,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,uBAAuB;QAAE,OAAO,GAAG,CAAC;IAChE,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAC1C,CAAa,OAA2D,EAAE,EAAE,CAC5E,KAAK,EAAE,OAAgB,EAAqB,EAAE;IAC5C,MAAM,MAAM,GAAG,2BAA2B,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;YAC1B,MAAM,cAAc,GAAG,2BAA2B,EAAE,CAAC;YACrD,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,CAAC;YACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE;oBACxC,SAAS,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,OAAO,CAAC;iBAC5D,CAAC,CAAC;YACL,CAAC;YACD,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC;QACF,MAAM,gBAAgB,GAAG,MAAM,qBAAqB,CAClD,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EACzE,QAAQ,CACT,CAAC;QAEF,OAAO,QAAQ,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,cAAc,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAEtC,OAAO,QAAQ,CAAC,IAAI,CAClB,sBAAsB,CACpB,uBAAuB,EACvB,uDAAuD,CACxD,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;IACJ,CAAC;AACH,CAAC,CAAC","sourcesContent":["import {\n graphReadProtocolError,\n parseGraphReadFamilyRequest,\n type GraphReadDispatcher,\n type GraphReadDispatchResponse,\n} from '@ontahi/core/data-graph';\nimport {\n getCurrentInvocationContext,\n withInvocationContext,\n type InvocationContext,\n} from '@ontahi/core/runtime/server';\n\nimport type { NextInvocationContextFactory } from '../request-context.js';\n\nexport type NextGraphReadAuthorityFactory<TAuthority> = (\n context: InvocationContext,\n request: Request,\n) => TAuthority | Promise<TAuthority>;\n\ntype NextGraphReadRouteHandlerCommonOptions = {\n invocationContext?: NextInvocationContextFactory;\n reportError?: (error: unknown, request: Request) => void;\n};\n\nexport type CreateNextGraphReadRouteHandlerOptions<TAuthority = InvocationContext> =\n NextGraphReadRouteHandlerCommonOptions &\n (\n | {\n dispatcher: GraphReadDispatcher<InvocationContext>;\n authority?: never;\n }\n | {\n dispatcher: GraphReadDispatcher<TAuthority>;\n authority: NextGraphReadAuthorityFactory<TAuthority>;\n }\n );\n\nconst responseStatus = (response: GraphReadDispatchResponse) => {\n if (response.kind !== 'protocol-error') return 200;\n if (response.error.code === 'access_denied') return 403;\n if (response.error.code === 'cardinality_mismatch') return 409;\n if (response.error.code === 'execution_unavailable') return 503;\n return 400;\n};\n\nexport const createNextGraphReadRouteHandler =\n <TAuthority>(options: CreateNextGraphReadRouteHandlerOptions<TAuthority>) =>\n async (request: Request): Promise<Response> => {\n const parsed = parseGraphReadFamilyRequest(await request.json().catch(() => null));\n if (!parsed.success) {\n return Response.json(parsed.error, { status: 400 });\n }\n\n try {\n const dispatch = async () => {\n const currentContext = getCurrentInvocationContext();\n if (!currentContext) {\n throw new Error('Next.js graph read invocation context is unavailable.');\n }\n if (options.authority) {\n return options.dispatcher(parsed.request, {\n authority: await options.authority(currentContext, request),\n });\n }\n return options.dispatcher(parsed.request, { authority: currentContext });\n };\n const protocolResponse = await withInvocationContext(\n options.invocationContext ? await options.invocationContext(request) : {},\n dispatch,\n );\n\n return Response.json(protocolResponse, { status: responseStatus(protocolResponse) });\n } catch (error) {\n options.reportError?.(error, request);\n\n return Response.json(\n graphReadProtocolError(\n 'execution_unavailable',\n 'Data graph read execution is temporarily unavailable.',\n ),\n { status: 503 },\n );\n }\n };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ontahi/runtime-nextjs",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.12",
|
|
4
4
|
"description": "Next.js runtime and transport adapters for Ontahi applications",
|
|
5
5
|
"homepage": "https://github.com/javifernandes/ontahi/tree/main/packages/runtime-nextjs",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -55,13 +55,15 @@
|
|
|
55
55
|
"provenance": true
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
+
"@ontahi/core": "1.0.0-alpha.12",
|
|
58
59
|
"effect": "^3.21.0",
|
|
59
60
|
"next-safe-action": "^8.3.0",
|
|
60
61
|
"server-only": "^0.0.1",
|
|
61
|
-
"zod": "^4.3.6"
|
|
62
|
-
"@ontahi/core": "1.0.0-alpha.10"
|
|
62
|
+
"zod": "^4.3.6"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
+
"@ontahi/react": "1.0.0-alpha.12",
|
|
66
|
+
"@ontahi/runtime-express": "1.0.0-alpha.12",
|
|
65
67
|
"@types/node": "^20.0.0",
|
|
66
68
|
"@types/react": "^18.3.0",
|
|
67
69
|
"@types/react-dom": "^18.3.0",
|