@jami-studio/core 0.92.28 → 0.92.30
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/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +33 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/route-warmup.tsx +565 -543
- package/corpus/core/src/collab/param.ts +24 -0
- package/corpus/core/src/collab/routes.ts +187 -191
- package/corpus/core/src/collab/struct-routes.ts +134 -133
- package/corpus/core/src/deploy/build.ts +64 -0
- package/dist/client/route-warmup.d.ts +10 -0
- package/dist/client/route-warmup.d.ts.map +1 -1
- package/dist/client/route-warmup.js +18 -1
- package/dist/client/route-warmup.js.map +1 -1
- package/dist/collab/param.d.ts +3 -0
- package/dist/collab/param.d.ts.map +1 -0
- package/dist/collab/param.js +26 -0
- package/dist/collab/param.js.map +1 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/routes.d.ts.map +1 -1
- package/dist/collab/routes.js +6 -5
- package/dist/collab/routes.js.map +1 -1
- package/dist/collab/struct-routes.d.ts.map +1 -1
- package/dist/collab/struct-routes.js +5 -4
- package/dist/collab/struct-routes.js.map +1 -1
- package/dist/deploy/build.d.ts +21 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +55 -0
- package/dist/deploy/build.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +2 -2
- package/package.json +1 -1
package/dist/collab/routes.d.ts
CHANGED
|
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
|
|
|
26
26
|
* Body: { update: string (base64), requestSource?: string }
|
|
27
27
|
*/
|
|
28
28
|
export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
29
|
-
ok?: undefined;
|
|
30
29
|
error: string;
|
|
30
|
+
ok?: undefined;
|
|
31
31
|
} | {
|
|
32
32
|
error?: undefined;
|
|
33
33
|
ok: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/collab/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/collab/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgCH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;;;GA4BzB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB;;;;;;GAyB3B,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;;;;;;GA8BzB,CAAC;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;GAgCnC,CAAC"}
|
package/dist/collab/routes.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Mounted under /_agent-native/collab/ by the collab plugin.
|
|
5
5
|
*/
|
|
6
|
-
import { defineEventHandler, setResponseStatus,
|
|
6
|
+
import { defineEventHandler, setResponseStatus, getQuery } from "h3";
|
|
7
7
|
import { readBody } from "../server/h3-helpers.js";
|
|
8
|
+
import { getCollabDocIdParam } from "./param.js";
|
|
8
9
|
import { uint8ArrayToBase64, base64ToUint8Array } from "./storage.js";
|
|
9
10
|
import * as manager from "./ydoc-manager.js";
|
|
10
11
|
import { searchAndReplace as doSearchAndReplace } from "./ydoc-manager.js";
|
|
@@ -32,7 +33,7 @@ function enforcePayloadLimit(event, body) {
|
|
|
32
33
|
* Returns full Yjs document state as base64 for initial client load.
|
|
33
34
|
*/
|
|
34
35
|
export const getCollabState = defineEventHandler(async (event) => {
|
|
35
|
-
const docId =
|
|
36
|
+
const docId = getCollabDocIdParam(event);
|
|
36
37
|
if (!docId) {
|
|
37
38
|
setResponseStatus(event, 400);
|
|
38
39
|
return { error: "docId required" };
|
|
@@ -66,7 +67,7 @@ export const getCollabState = defineEventHandler(async (event) => {
|
|
|
66
67
|
* Body: { update: string (base64), requestSource?: string }
|
|
67
68
|
*/
|
|
68
69
|
export const postCollabUpdate = defineEventHandler(async (event) => {
|
|
69
|
-
const docId =
|
|
70
|
+
const docId = getCollabDocIdParam(event);
|
|
70
71
|
if (!docId) {
|
|
71
72
|
setResponseStatus(event, 400);
|
|
72
73
|
return { error: "docId required" };
|
|
@@ -93,7 +94,7 @@ export const postCollabUpdate = defineEventHandler(async (event) => {
|
|
|
93
94
|
* Body: { text: string, fieldName?: string, requestSource?: string }
|
|
94
95
|
*/
|
|
95
96
|
export const postCollabText = defineEventHandler(async (event) => {
|
|
96
|
-
const docId =
|
|
97
|
+
const docId = getCollabDocIdParam(event);
|
|
97
98
|
if (!docId) {
|
|
98
99
|
setResponseStatus(event, 400);
|
|
99
100
|
return { error: "docId required" };
|
|
@@ -119,7 +120,7 @@ export const postCollabText = defineEventHandler(async (event) => {
|
|
|
119
120
|
* Body: { find: string, replace: string, requestSource?: string }
|
|
120
121
|
*/
|
|
121
122
|
export const postCollabSearchReplace = defineEventHandler(async (event) => {
|
|
122
|
-
const docId =
|
|
123
|
+
const docId = getCollabDocIdParam(event);
|
|
123
124
|
if (!docId) {
|
|
124
125
|
setResponseStatus(event, 400);
|
|
125
126
|
return { error: "docId required" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/collab/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * HTTP route handlers for collaborative editing.\r\n *\r\n * Mounted under /_agent-native/collab/ by the collab plugin.\r\n */\r\n\r\nimport {\r\n defineEventHandler,\r\n setResponseStatus,\r\n getRouterParam,\r\n getQuery,\r\n} from \"h3\";\r\nimport type { H3Event } from \"h3\";\r\n\r\nimport { readBody } from \"../server/h3-helpers.js\";\r\nimport { uint8ArrayToBase64, base64ToUint8Array } from \"./storage.js\";\r\nimport * as manager from \"./ydoc-manager.js\";\r\nimport { searchAndReplace as doSearchAndReplace } from \"./ydoc-manager.js\";\r\n\r\n/** Default maximum payload size (2 MB). Overridden by plugin via event.context. */\r\nconst DEFAULT_MAX_BYTES = 2 * 1024 * 1024;\r\n\r\nfunction getMaxPayloadBytes(event: H3Event): number {\r\n return (event.context as any)?._collabMaxPayloadBytes ?? DEFAULT_MAX_BYTES;\r\n}\r\n\r\n/**\r\n * Check the serialized body length against the configured limit.\r\n * Returns true if within limits; sets 413 status and returns false otherwise.\r\n */\r\nfunction enforcePayloadLimit(event: H3Event, body: unknown): boolean {\r\n const maxBytes = getMaxPayloadBytes(event);\r\n const encoded = typeof body === \"string\" ? body : JSON.stringify(body ?? \"\");\r\n if (encoded.length > maxBytes) {\r\n setResponseStatus(event, 413);\r\n return false;\r\n }\r\n return true;\r\n}\r\n\r\n/**\r\n * GET /_agent-native/collab/:docId/state\r\n *\r\n * Returns full Yjs document state as base64 for initial client load.\r\n */\r\nexport const getCollabState = defineEventHandler(async (event: H3Event) => {\r\n const docId = getRouterParam(event, \"docId\");\r\n if (!docId) {\r\n setResponseStatus(event, 400);\r\n return { error: \"docId required\" };\r\n }\r\n\r\n const query = getQuery(event);\r\n const encodedStateVector =\r\n typeof query.stateVector === \"string\" ? query.stateVector : null;\r\n let state: Uint8Array;\r\n if (encodedStateVector) {\r\n try {\r\n state = await manager.getIncUpdate(\r\n docId,\r\n base64ToUint8Array(encodedStateVector),\r\n );\r\n } catch {\r\n setResponseStatus(event, 400);\r\n return { error: \"stateVector must be base64-encoded\" };\r\n }\r\n } else {\r\n state = await manager.getState(docId);\r\n }\r\n return {\r\n docId,\r\n state: uint8ArrayToBase64(state),\r\n };\r\n});\r\n\r\n/**\r\n * POST /_agent-native/collab/:docId/update\r\n *\r\n * Client sends a Yjs update (base64). Server applies it, persists, and\r\n * emits a change event so other clients pick it up via polling.\r\n *\r\n * Body: { update: string (base64), requestSource?: string }\r\n */\r\nexport const postCollabUpdate = defineEventHandler(async (event: H3Event) => {\r\n const docId = getRouterParam(event, \"docId\");\r\n if (!docId) {\r\n setResponseStatus(event, 400);\r\n return { error: \"docId required\" };\r\n }\r\n\r\n const rawBody = await readBody(event);\r\n if (!enforcePayloadLimit(event, rawBody)) {\r\n return { error: \"Payload too large\" };\r\n }\r\n const { update, requestSource } = rawBody as {\r\n update?: string;\r\n requestSource?: string;\r\n };\r\n\r\n if (!update) {\r\n setResponseStatus(event, 400);\r\n return { error: \"update (base64) required\" };\r\n }\r\n\r\n const binary = base64ToUint8Array(update);\r\n await manager.applyUpdate(docId, binary, requestSource);\r\n\r\n return { ok: true };\r\n});\r\n\r\n/**\r\n * POST /_agent-native/collab/:docId/text\r\n *\r\n * Agent sends full text content. Server computes diff against current\r\n * Yjs state and applies minimal operations.\r\n *\r\n * Body: { text: string, fieldName?: string, requestSource?: string }\r\n */\r\nexport const postCollabText = defineEventHandler(async (event: H3Event) => {\r\n const docId = getRouterParam(event, \"docId\");\r\n if (!docId) {\r\n setResponseStatus(event, 400);\r\n return { error: \"docId required\" };\r\n }\r\n\r\n const rawBody = await readBody(event);\r\n if (!enforcePayloadLimit(event, rawBody)) {\r\n return { error: \"Payload too large\" };\r\n }\r\n const { text, fieldName, requestSource } = rawBody as {\r\n text?: string;\r\n fieldName?: string;\r\n requestSource?: string;\r\n };\r\n\r\n if (text === undefined) {\r\n setResponseStatus(event, 400);\r\n return { error: \"text required\" };\r\n }\r\n\r\n const result = await manager.applyText(\r\n docId,\r\n text,\r\n fieldName ?? \"content\",\r\n requestSource ?? \"agent\",\r\n );\r\n\r\n return { ok: true, text: result };\r\n});\r\n\r\n/**\r\n * POST /_agent-native/collab/:docId/search-replace\r\n *\r\n * Search-and-replace text in the Y.XmlFragment (ProseMirror tree).\r\n * Produces minimal Yjs operations for cursor-preserving updates.\r\n *\r\n * Body: { find: string, replace: string, requestSource?: string }\r\n */\r\nexport const postCollabSearchReplace = defineEventHandler(\r\n async (event: H3Event) => {\r\n const docId = getRouterParam(event, \"docId\");\r\n if (!docId) {\r\n setResponseStatus(event, 400);\r\n return { error: \"docId required\" };\r\n }\r\n\r\n const rawBody = await readBody(event);\r\n if (!enforcePayloadLimit(event, rawBody)) {\r\n return { error: \"Payload too large\" };\r\n }\r\n const { find, replace, requestSource } = rawBody as {\r\n find?: string;\r\n replace?: string;\r\n requestSource?: string;\r\n };\r\n\r\n if (!find) {\r\n setResponseStatus(event, 400);\r\n return { error: \"find required\" };\r\n }\r\n\r\n const result = await doSearchAndReplace(\r\n docId,\r\n find,\r\n replace ?? \"\",\r\n requestSource ?? \"agent\",\r\n );\r\n\r\n return { ok: true, found: result.found };\r\n },\r\n);\r\n"]}
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/collab/routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAGrE,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACtE,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,IAAI,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE3E,mFAAmF;AACnF,MAAM,iBAAiB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAE1C,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAQ,KAAK,CAAC,OAAe,EAAE,sBAAsB,IAAI,iBAAiB,CAAC;AAC7E,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,KAAc,EAAE,IAAa;IACxD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7E,IAAI,OAAO,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC9B,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IACxE,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9B,MAAM,kBAAkB,GACtB,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;IACnE,IAAI,KAAiB,CAAC;IACtB,IAAI,kBAAkB,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,OAAO,CAAC,YAAY,CAChC,KAAK,EACL,kBAAkB,CAAC,kBAAkB,CAAC,CACvC,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC9B,OAAO,EAAE,KAAK,EAAE,oCAAoC,EAAE,CAAC;QACzD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IACD,OAAO;QACL,KAAK;QACL,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC;KACjC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IAC1E,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAGjC,CAAC;IAEF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC;IAC/C,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IAExD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IACxE,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAI1C,CAAC;IAEF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,CACpC,KAAK,EACL,IAAI,EACJ,SAAS,IAAI,SAAS,EACtB,aAAa,IAAI,OAAO,CACzB,CAAC;IAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,kBAAkB,CACvD,KAAK,EAAE,KAAc,EAAE,EAAE;IACvB,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACrC,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;QACzC,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;IACxC,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAIxC,CAAC;IAEF,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9B,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,KAAK,EACL,IAAI,EACJ,OAAO,IAAI,EAAE,EACb,aAAa,IAAI,OAAO,CACzB,CAAC;IAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;AAC3C,CAAC,CACF,CAAC","sourcesContent":["/**\n * HTTP route handlers for collaborative editing.\n *\n * Mounted under /_agent-native/collab/ by the collab plugin.\n */\n\nimport { defineEventHandler, setResponseStatus, getQuery } from \"h3\";\nimport type { H3Event } from \"h3\";\n\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getCollabDocIdParam } from \"./param.js\";\nimport { uint8ArrayToBase64, base64ToUint8Array } from \"./storage.js\";\nimport * as manager from \"./ydoc-manager.js\";\nimport { searchAndReplace as doSearchAndReplace } from \"./ydoc-manager.js\";\n\n/** Default maximum payload size (2 MB). Overridden by plugin via event.context. */\nconst DEFAULT_MAX_BYTES = 2 * 1024 * 1024;\n\nfunction getMaxPayloadBytes(event: H3Event): number {\n return (event.context as any)?._collabMaxPayloadBytes ?? DEFAULT_MAX_BYTES;\n}\n\n/**\n * Check the serialized body length against the configured limit.\n * Returns true if within limits; sets 413 status and returns false otherwise.\n */\nfunction enforcePayloadLimit(event: H3Event, body: unknown): boolean {\n const maxBytes = getMaxPayloadBytes(event);\n const encoded = typeof body === \"string\" ? body : JSON.stringify(body ?? \"\");\n if (encoded.length > maxBytes) {\n setResponseStatus(event, 413);\n return false;\n }\n return true;\n}\n\n/**\n * GET /_agent-native/collab/:docId/state\n *\n * Returns full Yjs document state as base64 for initial client load.\n */\nexport const getCollabState = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const query = getQuery(event);\n const encodedStateVector =\n typeof query.stateVector === \"string\" ? query.stateVector : null;\n let state: Uint8Array;\n if (encodedStateVector) {\n try {\n state = await manager.getIncUpdate(\n docId,\n base64ToUint8Array(encodedStateVector),\n );\n } catch {\n setResponseStatus(event, 400);\n return { error: \"stateVector must be base64-encoded\" };\n }\n } else {\n state = await manager.getState(docId);\n }\n return {\n docId,\n state: uint8ArrayToBase64(state),\n };\n});\n\n/**\n * POST /_agent-native/collab/:docId/update\n *\n * Client sends a Yjs update (base64). Server applies it, persists, and\n * emits a change event so other clients pick it up via polling.\n *\n * Body: { update: string (base64), requestSource?: string }\n */\nexport const postCollabUpdate = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const rawBody = await readBody(event);\n if (!enforcePayloadLimit(event, rawBody)) {\n return { error: \"Payload too large\" };\n }\n const { update, requestSource } = rawBody as {\n update?: string;\n requestSource?: string;\n };\n\n if (!update) {\n setResponseStatus(event, 400);\n return { error: \"update (base64) required\" };\n }\n\n const binary = base64ToUint8Array(update);\n await manager.applyUpdate(docId, binary, requestSource);\n\n return { ok: true };\n});\n\n/**\n * POST /_agent-native/collab/:docId/text\n *\n * Agent sends full text content. Server computes diff against current\n * Yjs state and applies minimal operations.\n *\n * Body: { text: string, fieldName?: string, requestSource?: string }\n */\nexport const postCollabText = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const rawBody = await readBody(event);\n if (!enforcePayloadLimit(event, rawBody)) {\n return { error: \"Payload too large\" };\n }\n const { text, fieldName, requestSource } = rawBody as {\n text?: string;\n fieldName?: string;\n requestSource?: string;\n };\n\n if (text === undefined) {\n setResponseStatus(event, 400);\n return { error: \"text required\" };\n }\n\n const result = await manager.applyText(\n docId,\n text,\n fieldName ?? \"content\",\n requestSource ?? \"agent\",\n );\n\n return { ok: true, text: result };\n});\n\n/**\n * POST /_agent-native/collab/:docId/search-replace\n *\n * Search-and-replace text in the Y.XmlFragment (ProseMirror tree).\n * Produces minimal Yjs operations for cursor-preserving updates.\n *\n * Body: { find: string, replace: string, requestSource?: string }\n */\nexport const postCollabSearchReplace = defineEventHandler(\n async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const rawBody = await readBody(event);\n if (!enforcePayloadLimit(event, rawBody)) {\n return { error: \"Payload too large\" };\n }\n const { find, replace, requestSource } = rawBody as {\n find?: string;\n replace?: string;\n requestSource?: string;\n };\n\n if (!find) {\n setResponseStatus(event, 400);\n return { error: \"find required\" };\n }\n\n const result = await doSearchAndReplace(\n docId,\n find,\n replace ?? \"\",\n requestSource ?? \"agent\",\n );\n\n return { ok: true, found: result.found };\n },\n);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"struct-routes.d.ts","sourceRoot":"","sources":["../../src/collab/struct-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"struct-routes.d.ts","sourceRoot":"","sources":["../../src/collab/struct-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc;;;;;;GAgCzB,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;;;;;;GA8B1B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,aAAa;;;;;;;;GAYxB,CAAC"}
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Mounted under /_agent-native/collab/ by the collab plugin alongside
|
|
5
5
|
* the text-based routes in routes.ts.
|
|
6
6
|
*/
|
|
7
|
-
import { defineEventHandler, setResponseStatus
|
|
7
|
+
import { defineEventHandler, setResponseStatus } from "h3";
|
|
8
8
|
import { getQuery } from "h3";
|
|
9
9
|
import { readBody } from "../server/h3-helpers.js";
|
|
10
|
+
import { getCollabDocIdParam } from "./param.js";
|
|
10
11
|
import * as manager from "./ydoc-manager.js";
|
|
11
12
|
/** Default maximum payload size (2 MB). Overridden by plugin via event.context. */
|
|
12
13
|
const DEFAULT_MAX_BYTES = 2 * 1024 * 1024;
|
|
@@ -31,7 +32,7 @@ function enforcePayloadLimit(event, body) {
|
|
|
31
32
|
* Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
|
|
32
33
|
*/
|
|
33
34
|
export const postCollabJson = defineEventHandler(async (event) => {
|
|
34
|
-
const docId =
|
|
35
|
+
const docId = getCollabDocIdParam(event);
|
|
35
36
|
if (!docId) {
|
|
36
37
|
setResponseStatus(event, 400);
|
|
37
38
|
return { error: "docId required" };
|
|
@@ -56,7 +57,7 @@ export const postCollabJson = defineEventHandler(async (event) => {
|
|
|
56
57
|
* Body: { ops: PatchOp[], fieldName?: string, requestSource?: string }
|
|
57
58
|
*/
|
|
58
59
|
export const postCollabPatch = defineEventHandler(async (event) => {
|
|
59
|
-
const docId =
|
|
60
|
+
const docId = getCollabDocIdParam(event);
|
|
60
61
|
if (!docId) {
|
|
61
62
|
setResponseStatus(event, 400);
|
|
62
63
|
return { error: "docId required" };
|
|
@@ -81,7 +82,7 @@ export const postCollabPatch = defineEventHandler(async (event) => {
|
|
|
81
82
|
* Query param: fieldName (default: "data")
|
|
82
83
|
*/
|
|
83
84
|
export const getCollabJson = defineEventHandler(async (event) => {
|
|
84
|
-
const docId =
|
|
85
|
+
const docId = getCollabDocIdParam(event);
|
|
85
86
|
if (!docId) {
|
|
86
87
|
setResponseStatus(event, 400);
|
|
87
88
|
return { error: "docId required" };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"struct-routes.js","sourceRoot":"","sources":["../../src/collab/struct-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"struct-routes.js","sourceRoot":"","sources":["../../src/collab/struct-routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP route handlers for structured (JSON) collaborative editing.\n *\n * Mounted under /_agent-native/collab/ by the collab plugin alongside\n * the text-based routes in routes.ts.\n */\n\nimport { defineEventHandler, setResponseStatus } from \"h3\";\nimport type { H3Event } from \"h3\";\nimport { getQuery } from \"h3\";\n\nimport { readBody } from \"../server/h3-helpers.js\";\nimport type { PatchOp } from \"./json-to-yjs.js\";\nimport { getCollabDocIdParam } from \"./param.js\";\nimport * as manager from \"./ydoc-manager.js\";\n\n/** Default maximum payload size (2 MB). Overridden by plugin via event.context. */\nconst DEFAULT_MAX_BYTES = 2 * 1024 * 1024;\n\nfunction getMaxPayloadBytes(event: H3Event): number {\n return (event.context as any)?._collabMaxPayloadBytes ?? DEFAULT_MAX_BYTES;\n}\n\nfunction enforcePayloadLimit(event: H3Event, body: unknown): boolean {\n const maxBytes = getMaxPayloadBytes(event);\n const encoded = typeof body === \"string\" ? body : JSON.stringify(body ?? \"\");\n if (encoded.length > maxBytes) {\n setResponseStatus(event, 413);\n return false;\n }\n return true;\n}\n\n/**\n * POST /_agent-native/collab/:docId/json\n *\n * Apply full JSON content to a collaborative document. The server diffs\n * against the current Yjs state and applies minimal operations.\n *\n * Body: { json: any, fieldName?: string, type?: \"map\"|\"array\", requestSource?: string }\n */\nexport const postCollabJson = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const rawBody = await readBody(event);\n if (!enforcePayloadLimit(event, rawBody)) {\n return { error: \"Payload too large\" };\n }\n const { json, fieldName, type, requestSource } = rawBody as {\n json?: any;\n fieldName?: string;\n type?: \"map\" | \"array\";\n requestSource?: string;\n };\n\n if (json === undefined) {\n setResponseStatus(event, 400);\n return { error: \"json required\" };\n }\n\n await manager.applyJson(\n docId,\n json,\n fieldName ?? \"data\",\n type ?? (Array.isArray(json) ? \"array\" : \"map\"),\n requestSource ?? \"agent\",\n );\n\n return { ok: true };\n});\n\n/**\n * POST /_agent-native/collab/:docId/patch\n *\n * Apply surgical JSON patch operations to a collaborative document.\n *\n * Body: { ops: PatchOp[], fieldName?: string, requestSource?: string }\n */\nexport const postCollabPatch = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const rawBody = await readBody(event);\n if (!enforcePayloadLimit(event, rawBody)) {\n return { error: \"Payload too large\" };\n }\n const { ops, fieldName, requestSource } = rawBody as {\n ops?: PatchOp[];\n fieldName?: string;\n requestSource?: string;\n };\n\n if (!ops || !Array.isArray(ops)) {\n setResponseStatus(event, 400);\n return { error: \"ops (array) required\" };\n }\n\n await manager.applyPatchOps(\n docId,\n ops,\n fieldName ?? \"data\",\n requestSource ?? \"agent\",\n );\n\n return { ok: true };\n});\n\n/**\n * GET /_agent-native/collab/:docId/json\n *\n * Returns the current JSON state of a collaborative document.\n *\n * Query param: fieldName (default: \"data\")\n */\nexport const getCollabJson = defineEventHandler(async (event: H3Event) => {\n const docId = getCollabDocIdParam(event);\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const query = getQuery(event);\n const fieldName = (query.fieldName as string) ?? \"data\";\n\n const data = await manager.getJson(docId, fieldName);\n return { docId, data };\n});\n"]}
|
package/dist/deploy/build.d.ts
CHANGED
|
@@ -70,6 +70,7 @@ interface ReactRouterAssetManifestRoute {
|
|
|
70
70
|
imports?: string[];
|
|
71
71
|
css?: string[];
|
|
72
72
|
hasLoader?: boolean;
|
|
73
|
+
hasAction?: boolean;
|
|
73
74
|
clientActionModule?: string;
|
|
74
75
|
clientLoaderModule?: string;
|
|
75
76
|
clientMiddlewareModule?: string;
|
|
@@ -90,6 +91,26 @@ export declare function addImmutableAssetRouteRulesForClientBuild(routeRules: Ro
|
|
|
90
91
|
* inheritance model: app local > workspace core > framework default.
|
|
91
92
|
*/
|
|
92
93
|
export declare function generateWorkerEntry(routes: DiscoveredRoute[], pluginPaths: string[], defaultPluginStems?: string[], actions?: DiscoveredAction[], workspaceCore?: WorkspaceCoreExports | null, immutableAssetPaths?: string[], builtAppBasePath?: string, options?: GenerateWorkerEntryOptions): string;
|
|
94
|
+
/**
|
|
95
|
+
* Align the React Router CLIENT manifest with the static-shell worker.
|
|
96
|
+
*
|
|
97
|
+
* The Cloudflare Pages worker intentionally ships NO React Router request
|
|
98
|
+
* handler (`includeReactRouterSsr = false` keeps the merged worker under the
|
|
99
|
+
* platform bundle-size limit; navigations get the static app shell instead).
|
|
100
|
+
* Templates build with `ssr: true`, so the emitted client manifest still
|
|
101
|
+
* advertises `hasLoader`/`hasAction` for routes with server exports — and the
|
|
102
|
+
* hydrated router then issues single-fetch `GET <route>.data` requests on
|
|
103
|
+
* every client-side navigation into such a route. Nothing serves them: the
|
|
104
|
+
* request 404s and React Router trips the route ErrorBoundary
|
|
105
|
+
* (`No result found for routeId "..."`), breaking in-app navigation on every
|
|
106
|
+
* app of a unified workspace deployment.
|
|
107
|
+
*
|
|
108
|
+
* Stripping the server-only flags makes client-side navigation behave exactly
|
|
109
|
+
* like the initial static-shell load already does: render with client data
|
|
110
|
+
* only (server loaders never run anywhere in this deployment shape).
|
|
111
|
+
* `hasClientLoader` / `hasClientAction` are preserved untouched.
|
|
112
|
+
*/
|
|
113
|
+
export declare function stripServerDataFlagsFromClientManifest(distDir: string): void;
|
|
93
114
|
export declare function generateCloudflarePagesStaticShellFromManifest(manifest: ReactRouterAssetManifest, basePath?: string): string;
|
|
94
115
|
export declare function getNodeBuiltinNames(): string[];
|
|
95
116
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;GAYG;AAmCH,OAAO,EAML,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,qBAAqB,CAAC;AAI7B,eAAO,MAAM,6BAA6B,UAiBzC,CAAC;AAEF,eAAO,MAAM,mCAAmC,UAiB/C,CAAC;AACF,eAAO,MAAM,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuIjE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,UAUnC,CAAC;AAEF,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAaxB;AAoCD,eAAO,MAAM,2CAA2C,EAAE,MAAM,CAC9D,MAAM,EACN,MAAM,CAmSP,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACzC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAQlE;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,IAAI,CAKf;AAED,UAAU,wBAAwB;IAChC,KAAK,EAAE,6BAA6B,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IACtD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,UAAU,6BAA6B;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,UAAU,6BAA6B;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAwBD,wBAAgB,wCAAwC,CACtD,WAAW,EAAE,MAAM,EAAE,GACpB,MAAM,CAaR;AAgBD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAAC;AAgBvE,wBAAgB,yCAAyC,CACvD,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,SAAK,GACf,IAAI,CAQN;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,eAAe,EAAE,EACzB,WAAW,EAAE,MAAM,EAAE,EACrB,kBAAkB,GAAE,MAAM,EAAO,EACjC,OAAO,GAAE,gBAAgB,EAAO,EAChC,aAAa,GAAE,oBAAoB,GAAG,IAAW,EACjD,mBAAmB,GAAE,MAAM,EAAO,EAClC,gBAAgB,SAAmC,EACnD,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAipBR;
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/deploy/build.ts"],"names":[],"mappings":"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"}
|
package/dist/deploy/build.js
CHANGED
|
@@ -1250,6 +1250,56 @@ function findReactRouterManifest(distDir) {
|
|
|
1250
1250
|
}
|
|
1251
1251
|
return JSON.parse(match[1].replace(/;$/, ""));
|
|
1252
1252
|
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Align the React Router CLIENT manifest with the static-shell worker.
|
|
1255
|
+
*
|
|
1256
|
+
* The Cloudflare Pages worker intentionally ships NO React Router request
|
|
1257
|
+
* handler (`includeReactRouterSsr = false` keeps the merged worker under the
|
|
1258
|
+
* platform bundle-size limit; navigations get the static app shell instead).
|
|
1259
|
+
* Templates build with `ssr: true`, so the emitted client manifest still
|
|
1260
|
+
* advertises `hasLoader`/`hasAction` for routes with server exports — and the
|
|
1261
|
+
* hydrated router then issues single-fetch `GET <route>.data` requests on
|
|
1262
|
+
* every client-side navigation into such a route. Nothing serves them: the
|
|
1263
|
+
* request 404s and React Router trips the route ErrorBoundary
|
|
1264
|
+
* (`No result found for routeId "..."`), breaking in-app navigation on every
|
|
1265
|
+
* app of a unified workspace deployment.
|
|
1266
|
+
*
|
|
1267
|
+
* Stripping the server-only flags makes client-side navigation behave exactly
|
|
1268
|
+
* like the initial static-shell load already does: render with client data
|
|
1269
|
+
* only (server loaders never run anywhere in this deployment shape).
|
|
1270
|
+
* `hasClientLoader` / `hasClientAction` are preserved untouched.
|
|
1271
|
+
*/
|
|
1272
|
+
export function stripServerDataFlagsFromClientManifest(distDir) {
|
|
1273
|
+
const assetsDir = path.join(distDir, "assets");
|
|
1274
|
+
if (!fs.existsSync(assetsDir))
|
|
1275
|
+
return;
|
|
1276
|
+
const manifestFile = fs
|
|
1277
|
+
.readdirSync(assetsDir)
|
|
1278
|
+
.find((file) => /^manifest-[\w-]+\.js$/.test(file));
|
|
1279
|
+
if (!manifestFile)
|
|
1280
|
+
return;
|
|
1281
|
+
const manifestPath = path.join(assetsDir, manifestFile);
|
|
1282
|
+
const source = fs.readFileSync(manifestPath, "utf8");
|
|
1283
|
+
const match = source.match(/^window\.__reactRouterManifest=(.*);?\s*$/);
|
|
1284
|
+
if (!match)
|
|
1285
|
+
return;
|
|
1286
|
+
const manifest = JSON.parse(match[1].replace(/;$/, ""));
|
|
1287
|
+
let stripped = 0;
|
|
1288
|
+
for (const route of Object.values(manifest.routes ?? {})) {
|
|
1289
|
+
if (route.hasLoader) {
|
|
1290
|
+
route.hasLoader = false;
|
|
1291
|
+
stripped++;
|
|
1292
|
+
}
|
|
1293
|
+
if (route.hasAction) {
|
|
1294
|
+
route.hasAction = false;
|
|
1295
|
+
stripped++;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
if (stripped === 0)
|
|
1299
|
+
return;
|
|
1300
|
+
fs.writeFileSync(manifestPath, `window.__reactRouterManifest=${JSON.stringify(manifest)};`);
|
|
1301
|
+
console.log(`[deploy] Stripped ${stripped} server loader/action flag(s) from ${manifestFile} — the static-shell worker has no React Router handler, so single-fetch .data requests would 404.`);
|
|
1302
|
+
}
|
|
1253
1303
|
function collectModulePreloads(manifest, route) {
|
|
1254
1304
|
const paths = new Set();
|
|
1255
1305
|
const add = (value) => {
|
|
@@ -1404,6 +1454,11 @@ async function buildCloudflarePages() {
|
|
|
1404
1454
|
const tmpDir = path.join(cwd, ".deploy-tmp");
|
|
1405
1455
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
1406
1456
|
writeCloudflarePagesStaticShell({ serverDir, distDir, tmpDir });
|
|
1457
|
+
// AFTER the shell is written (its manifest fallback reads the original
|
|
1458
|
+
// hasLoader flag to pick the embedded root-loader turbo stream): align the
|
|
1459
|
+
// client manifest with the handler-less worker so client-side navigations
|
|
1460
|
+
// don't issue .data single-fetch requests that can only 404.
|
|
1461
|
+
stripServerDataFlagsFromClientManifest(distDir);
|
|
1407
1462
|
// Exclude _worker.js from being served as a public asset
|
|
1408
1463
|
fs.writeFileSync(path.join(distDir, ".assetsignore"), "_worker.js\n");
|
|
1409
1464
|
// Write package metadata inside _worker.js/ for the ES module worker that
|