@agent-native/core 0.77.10 → 0.77.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/corpus/README.md +1 -1
- package/corpus/core/CHANGELOG.md +6 -0
- package/corpus/core/package.json +3 -3
- package/corpus/core/src/collab/awareness.ts +12 -9
- package/corpus/core/src/collab/client.ts +4 -2
- package/corpus/templates/clips/chrome-extension/package.json +1 -1
- package/corpus/templates/content/actions/list-trashed-content-databases.ts +36 -2
- package/corpus/templates/content/actions/move-document.ts +79 -33
- package/corpus/templates/content/actions/restore-content-database.ts +40 -3
- package/corpus/templates/content/app/components/editor/BubbleToolbar.tsx +84 -2
- package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +177 -49
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +393 -219
- package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +632 -467
- package/corpus/templates/content/app/components/editor/SlashCommandMenu.tsx +114 -14
- package/corpus/templates/content/app/components/editor/VisualEditor.tsx +56 -15
- package/corpus/templates/content/app/components/editor/extensions/NotionExtensions.tsx +6 -5
- package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +12 -4
- package/corpus/templates/content/app/global.css +9 -0
- package/corpus/templates/content/app/hooks/use-create-page.ts +36 -7
- package/corpus/templates/content/app/i18n-data.ts +140 -10
- package/corpus/templates/content/changelog/2026-06-25-comment-cards-now-track-their-highlighted-text-while-scrolli.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-comments-now-scroll-with-the-document-and-stay-below-the-pag.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-creating-a-database-from-the-slash-menu-no-longer-leaves-sta.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-sidebar-hover-controls-no-longer-leave-a-lingering-fade-when.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-sidebar-page-actions-are-now-easier-to-see-when-hovering-ina.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-text-selections-in-the-editor-no-longer-show-white-gaps-when.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-editor-toolbar-now-has-a-one-click-page-link-copy-button.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-editor-toolbar-now-shows-page-breadcrumbs-and-the-latest.md +6 -0
- package/corpus/templates/content/changelog/2026-06-25-the-page-command-now-leaves-a-notion-style-page-reference-an.md +6 -0
- package/corpus/templates/content/shared/nfm.ts +16 -0
- package/dist/collab/awareness.d.ts +1 -1
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/collab/awareness.js +12 -8
- package/dist/collab/awareness.js.map +1 -1
- package/dist/collab/client.d.ts.map +1 -1
- package/dist/collab/client.js +4 -3
- package/dist/collab/client.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +2 -2
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +7 -7
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/package.json +3 -3
|
@@ -1163,6 +1163,11 @@ const editorToolbarMessages = {
|
|
|
1163
1163
|
conflictResolvedFromNotion: "Conflict resolved from Notion.",
|
|
1164
1164
|
connectNotionWorkspaceToLink:
|
|
1165
1165
|
"Connect a Notion workspace to link this document.",
|
|
1166
|
+
copiedPageLink: "Copied page link",
|
|
1167
|
+
copyPageLink: "Copy page link",
|
|
1168
|
+
couldNotCopyLink: "Could not copy link",
|
|
1169
|
+
clipboardAccessUnavailable:
|
|
1170
|
+
"Clipboard access is not available in this browser.",
|
|
1166
1171
|
edited: "Edited",
|
|
1167
1172
|
export: "Export",
|
|
1168
1173
|
exportFailed: "Export failed",
|
|
@@ -1197,6 +1202,7 @@ const editorToolbarMessages = {
|
|
|
1197
1202
|
openInNotion: "Open in Notion",
|
|
1198
1203
|
orgCanFindAndView: "Anyone in your organization can find and view",
|
|
1199
1204
|
orgLinkCanView: "Anyone in your organization with the link can view",
|
|
1205
|
+
pageBreadcrumb: "Page breadcrumb",
|
|
1200
1206
|
printDialogOpened: "Print dialog opened",
|
|
1201
1207
|
printDialogOpenedDescription: "Choose Save as PDF to finish the export.",
|
|
1202
1208
|
pulledFromNotion: "Pulled from Notion.",
|
|
@@ -1443,6 +1449,7 @@ const enUS = {
|
|
|
1443
1449
|
describeWhatToGenerate: "Describe what to generate...",
|
|
1444
1450
|
enterToSubmit: "Enter to submit",
|
|
1445
1451
|
failedToCreateDatabase: "Failed to create database",
|
|
1452
|
+
failedToCreatePage: "Failed to create page",
|
|
1446
1453
|
generateWithAi: "Generate with AI",
|
|
1447
1454
|
dropMedia: "Drop media",
|
|
1448
1455
|
editLink: "Edit link",
|
|
@@ -7524,21 +7531,130 @@ export const messagesByLocale = {
|
|
|
7524
7531
|
} satisfies Record<LocaleCode, Messages>;
|
|
7525
7532
|
|
|
7526
7533
|
const contentExactEnglishTranslations = {
|
|
7527
|
-
"zh-CN": {
|
|
7528
|
-
|
|
7529
|
-
|
|
7534
|
+
"zh-CN": {
|
|
7535
|
+
editor: {
|
|
7536
|
+
failedToCreatePage: "创建页面失败",
|
|
7537
|
+
toolbar: {
|
|
7538
|
+
copiedPageLink: "已复制页面链接",
|
|
7539
|
+
copyPageLink: "复制页面链接",
|
|
7540
|
+
couldNotCopyLink: "无法复制链接",
|
|
7541
|
+
clipboardAccessUnavailable: "此浏览器无法访问剪贴板。",
|
|
7542
|
+
pageBreadcrumb: "页面面包屑",
|
|
7543
|
+
},
|
|
7544
|
+
versionRestoreQuestion: "恢复此版本?",
|
|
7545
|
+
},
|
|
7546
|
+
},
|
|
7547
|
+
"es-ES": {
|
|
7548
|
+
editor: {
|
|
7549
|
+
failedToCreatePage: "No se pudo crear la página",
|
|
7550
|
+
toolbar: {
|
|
7551
|
+
copiedPageLink: "Enlace de página copiado",
|
|
7552
|
+
copyPageLink: "Copiar enlace de página",
|
|
7553
|
+
couldNotCopyLink: "No se pudo copiar el enlace",
|
|
7554
|
+
clipboardAccessUnavailable:
|
|
7555
|
+
"El acceso al portapapeles no está disponible en este navegador.",
|
|
7556
|
+
pageBreadcrumb: "Ruta de la página",
|
|
7557
|
+
},
|
|
7558
|
+
versionRestoreQuestion: "¿Restaurar esta versión?",
|
|
7559
|
+
},
|
|
7560
|
+
},
|
|
7561
|
+
"fr-FR": {
|
|
7562
|
+
editor: {
|
|
7563
|
+
failedToCreatePage: "Impossible de créer la page",
|
|
7564
|
+
toolbar: {
|
|
7565
|
+
copiedPageLink: "Lien de la page copié",
|
|
7566
|
+
copyPageLink: "Copier le lien de la page",
|
|
7567
|
+
couldNotCopyLink: "Impossible de copier le lien",
|
|
7568
|
+
clipboardAccessUnavailable:
|
|
7569
|
+
"L'accès au presse-papiers n'est pas disponible dans ce navigateur.",
|
|
7570
|
+
pageBreadcrumb: "Fil d'Ariane de la page",
|
|
7571
|
+
},
|
|
7572
|
+
versionRestoreQuestion: "Restaurer cette version ?",
|
|
7573
|
+
},
|
|
7574
|
+
},
|
|
7530
7575
|
"de-DE": {
|
|
7531
|
-
editor: {
|
|
7576
|
+
editor: {
|
|
7577
|
+
failedToCreatePage: "Seite konnte nicht erstellt werden",
|
|
7578
|
+
toolbar: {
|
|
7579
|
+
copiedPageLink: "Seitenlink kopiert",
|
|
7580
|
+
copyPageLink: "Seitenlink kopieren",
|
|
7581
|
+
couldNotCopyLink: "Link konnte nicht kopiert werden",
|
|
7582
|
+
clipboardAccessUnavailable:
|
|
7583
|
+
"Der Zugriff auf die Zwischenablage ist in diesem Browser nicht verfügbar.",
|
|
7584
|
+
pageBreadcrumb: "Seitenpfad",
|
|
7585
|
+
},
|
|
7586
|
+
versionRestoreQuestion: "Diese Version wiederherstellen?",
|
|
7587
|
+
},
|
|
7532
7588
|
},
|
|
7533
7589
|
"ja-JP": {
|
|
7534
|
-
editor: {
|
|
7590
|
+
editor: {
|
|
7591
|
+
failedToCreatePage: "ページを作成できませんでした",
|
|
7592
|
+
toolbar: {
|
|
7593
|
+
copiedPageLink: "ページリンクをコピーしました",
|
|
7594
|
+
copyPageLink: "ページリンクをコピー",
|
|
7595
|
+
couldNotCopyLink: "リンクをコピーできませんでした",
|
|
7596
|
+
clipboardAccessUnavailable:
|
|
7597
|
+
"このブラウザではクリップボードにアクセスできません。",
|
|
7598
|
+
pageBreadcrumb: "ページのパンくずリスト",
|
|
7599
|
+
},
|
|
7600
|
+
versionRestoreQuestion: "このバージョンを復元しますか?",
|
|
7601
|
+
},
|
|
7602
|
+
},
|
|
7603
|
+
"ko-KR": {
|
|
7604
|
+
editor: {
|
|
7605
|
+
failedToCreatePage: "페이지를 만들지 못했습니다",
|
|
7606
|
+
toolbar: {
|
|
7607
|
+
copiedPageLink: "페이지 링크를 복사했습니다",
|
|
7608
|
+
copyPageLink: "페이지 링크 복사",
|
|
7609
|
+
couldNotCopyLink: "링크를 복사하지 못했습니다",
|
|
7610
|
+
clipboardAccessUnavailable:
|
|
7611
|
+
"이 브라우저에서는 클립보드에 접근할 수 없습니다.",
|
|
7612
|
+
pageBreadcrumb: "페이지 이동 경로",
|
|
7613
|
+
},
|
|
7614
|
+
versionRestoreQuestion: "이 버전을 복원할까요?",
|
|
7615
|
+
},
|
|
7616
|
+
},
|
|
7617
|
+
"pt-BR": {
|
|
7618
|
+
editor: {
|
|
7619
|
+
failedToCreatePage: "Não foi possível criar a página",
|
|
7620
|
+
toolbar: {
|
|
7621
|
+
copiedPageLink: "Link da página copiado",
|
|
7622
|
+
copyPageLink: "Copiar link da página",
|
|
7623
|
+
couldNotCopyLink: "Não foi possível copiar o link",
|
|
7624
|
+
clipboardAccessUnavailable:
|
|
7625
|
+
"O acesso à área de transferência não está disponível neste navegador.",
|
|
7626
|
+
pageBreadcrumb: "Caminho da página",
|
|
7627
|
+
},
|
|
7628
|
+
versionRestoreQuestion: "Restaurar esta versão?",
|
|
7629
|
+
},
|
|
7535
7630
|
},
|
|
7536
|
-
"ko-KR": { editor: { versionRestoreQuestion: "이 버전을 복원할까요?" } },
|
|
7537
|
-
"pt-BR": { editor: { versionRestoreQuestion: "Restaurar esta versão?" } },
|
|
7538
7631
|
"hi-IN": {
|
|
7539
|
-
editor: {
|
|
7632
|
+
editor: {
|
|
7633
|
+
failedToCreatePage: "पेज नहीं बनाया जा सका",
|
|
7634
|
+
toolbar: {
|
|
7635
|
+
copiedPageLink: "पेज लिंक कॉपी किया गया",
|
|
7636
|
+
copyPageLink: "पेज लिंक कॉपी करें",
|
|
7637
|
+
couldNotCopyLink: "लिंक कॉपी नहीं किया जा सका",
|
|
7638
|
+
clipboardAccessUnavailable: "इस ब्राउज़र में क्लिपबोर्ड एक्सेस उपलब्ध नहीं है।",
|
|
7639
|
+
pageBreadcrumb: "पेज ब्रेडक्रंब",
|
|
7640
|
+
},
|
|
7641
|
+
versionRestoreQuestion: "यह संस्करण पुनर्स्थापित करें?",
|
|
7642
|
+
},
|
|
7643
|
+
},
|
|
7644
|
+
"ar-SA": {
|
|
7645
|
+
editor: {
|
|
7646
|
+
failedToCreatePage: "تعذر إنشاء الصفحة",
|
|
7647
|
+
toolbar: {
|
|
7648
|
+
copiedPageLink: "تم نسخ رابط الصفحة",
|
|
7649
|
+
copyPageLink: "نسخ رابط الصفحة",
|
|
7650
|
+
couldNotCopyLink: "تعذر نسخ الرابط",
|
|
7651
|
+
clipboardAccessUnavailable:
|
|
7652
|
+
"الوصول إلى الحافظة غير متاح في هذا المتصفح.",
|
|
7653
|
+
pageBreadcrumb: "مسار الصفحة",
|
|
7654
|
+
},
|
|
7655
|
+
versionRestoreQuestion: "استعادة هذا الإصدار؟",
|
|
7656
|
+
},
|
|
7540
7657
|
},
|
|
7541
|
-
"ar-SA": { editor: { versionRestoreQuestion: "استعادة هذا الإصدار؟" } },
|
|
7542
7658
|
} satisfies Partial<Record<LocaleCode, PartialMessages>>;
|
|
7543
7659
|
|
|
7544
7660
|
for (const [locale, overrides] of Object.entries(
|
|
@@ -7549,7 +7665,21 @@ for (const [locale, overrides] of Object.entries(
|
|
|
7549
7665
|
for (const [group, groupOverrides] of Object.entries(overrides)) {
|
|
7550
7666
|
const target = (messages as Record<string, Record<string, unknown>>)[group];
|
|
7551
7667
|
if (target && groupOverrides && typeof groupOverrides === "object") {
|
|
7552
|
-
Object.
|
|
7668
|
+
for (const [key, value] of Object.entries(groupOverrides)) {
|
|
7669
|
+
const nestedTarget = target[key];
|
|
7670
|
+
if (
|
|
7671
|
+
nestedTarget &&
|
|
7672
|
+
value &&
|
|
7673
|
+
typeof nestedTarget === "object" &&
|
|
7674
|
+
typeof value === "object" &&
|
|
7675
|
+
!Array.isArray(nestedTarget) &&
|
|
7676
|
+
!Array.isArray(value)
|
|
7677
|
+
) {
|
|
7678
|
+
Object.assign(nestedTarget, value);
|
|
7679
|
+
} else {
|
|
7680
|
+
target[key] = value;
|
|
7681
|
+
}
|
|
7682
|
+
}
|
|
7553
7683
|
}
|
|
7554
7684
|
}
|
|
7555
7685
|
}
|
|
@@ -1798,3 +1798,19 @@ function parseLeafTag(
|
|
|
1798
1798
|
export function canonicalizeNfm(nfm: string | null | undefined): string {
|
|
1799
1799
|
return docToNfm(nfmToDoc(nfm ?? ""));
|
|
1800
1800
|
}
|
|
1801
|
+
|
|
1802
|
+
export function collapseExactRepeatedNfm(
|
|
1803
|
+
nfm: string,
|
|
1804
|
+
options: { requiredText: string },
|
|
1805
|
+
): string {
|
|
1806
|
+
if (!options.requiredText || !nfm.includes(options.requiredText)) return nfm;
|
|
1807
|
+
|
|
1808
|
+
const lines = nfm.split("\n");
|
|
1809
|
+
if (lines.length < 2 || lines.length % 2 !== 0) return nfm;
|
|
1810
|
+
|
|
1811
|
+
const midpoint = lines.length / 2;
|
|
1812
|
+
for (let index = 0; index < midpoint; index += 1) {
|
|
1813
|
+
if (lines[index] !== lines[index + midpoint]) return nfm;
|
|
1814
|
+
}
|
|
1815
|
+
return lines.slice(0, midpoint).join("\n");
|
|
1816
|
+
}
|
|
@@ -42,7 +42,7 @@ export declare function cleanExpired(map: Map<number, AwarenessEntry>): void;
|
|
|
42
42
|
*
|
|
43
43
|
* Client sends its awareness state and receives other clients' states.
|
|
44
44
|
*
|
|
45
|
-
* Body: { clientId: number, state: string (
|
|
45
|
+
* Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }
|
|
46
46
|
* Response: { states: Array<{ clientId: number, state: string }> }
|
|
47
47
|
*/
|
|
48
48
|
export declare const postAwareness: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;
|
|
1
|
+
{"version":3,"file":"awareness.d.ts","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAOD,eAAO,MAAM,sBAAsB,EAAG,kBAA2B,CAAC;AAElE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,MAAM,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,wBAAgB,mBAAmB,IAAI,YAAY,CAElD;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,EAClD,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAUN;AAKD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAO1E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,IAAI,CAOnE;AAUD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa;;;;;;kBAuCa,MAAM;eAAS,MAAM;;GAa1D,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;kBAWM,MAAM;kBAAY,MAAM;;GAMvD,CAAC"}
|
package/dist/collab/awareness.js
CHANGED
|
@@ -64,7 +64,7 @@ function pruneIfEmpty(docId, map) {
|
|
|
64
64
|
*
|
|
65
65
|
* Client sends its awareness state and receives other clients' states.
|
|
66
66
|
*
|
|
67
|
-
* Body: { clientId: number, state: string (
|
|
67
|
+
* Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }
|
|
68
68
|
* Response: { states: Array<{ clientId: number, state: string }> }
|
|
69
69
|
*/
|
|
70
70
|
export const postAwareness = defineEventHandler(async (event) => {
|
|
@@ -75,22 +75,26 @@ export const postAwareness = defineEventHandler(async (event) => {
|
|
|
75
75
|
}
|
|
76
76
|
const body = await readBody(event);
|
|
77
77
|
const { clientId, state } = body;
|
|
78
|
-
if (clientId == null ||
|
|
78
|
+
if (clientId == null || state === undefined) {
|
|
79
79
|
// `!clientId` would wrongly reject clientId === 0, which is a valid
|
|
80
|
-
// (if rare) Yjs client id.
|
|
80
|
+
// (if rare) Yjs client id. A null state is valid: it clears this client.
|
|
81
81
|
setResponseStatus(event, 400);
|
|
82
82
|
return { error: "clientId and state required" };
|
|
83
83
|
}
|
|
84
84
|
const map = getDocAwareness(docId);
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
if (state === null) {
|
|
86
|
+
map.delete(clientId);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// Store this client's state
|
|
90
|
+
map.set(clientId, { clientId, state, lastSeen: Date.now() });
|
|
91
|
+
}
|
|
87
92
|
// Clean expired entries, then prune the outer-map entry if it becomes empty.
|
|
88
93
|
// Without pruning, a deployment with many transient docIds (e.g. one per
|
|
89
94
|
// session) would grow _awarenessMap without bound.
|
|
90
95
|
cleanExpired(map);
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
// that was immediately evicted by a concurrent cleanExpired run).
|
|
96
|
+
// Null-state clears and expiry can empty the map; prune the outer entry so
|
|
97
|
+
// transient document ids do not accumulate.
|
|
94
98
|
pruneIfEmpty(docId, map);
|
|
95
99
|
// Build the full list of current states (all clients including sender).
|
|
96
100
|
const allStates = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"awareness.js","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAG3E,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,iBAAiB,GAAG,MAAM,CAAC,CAAC,aAAa;AAQ/C,8EAA8E;AAC9E,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAE9E,MAAM,CAAC,MAAM,sBAAsB,GAAG,kBAA2B,CAAC;AAclE,MAAM,iBAAiB,GAAG,IAAI,YAAY,EAAE,CAAC;AAC7C,iBAAiB,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;AAErC,MAAM,UAAU,mBAAmB;IACjC,OAAO,iBAAiB,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAAkD,EAClD,KAAc,EACd,KAAc;IAEd,MAAM,KAAK,GAAyB;QAClC,MAAM,EAAE,WAAW;QACnB,IAAI,EAAE,kBAAkB;QACxB,KAAK;QACL,MAAM;QACN,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;KACxB,CAAC;IACF,iBAAiB,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,wCAAwC;AACxC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAuC,CAAC;AAErE,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QAChB,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAgC;IAC3D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;QACpC,IAAI,GAAG,GAAG,KAAK,CAAC,QAAQ,GAAG,iBAAiB,EAAE,CAAC;YAC7C,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC;AAED,2EAA2E;AAC3E,0EAA0E;AAC1E,SAAS,YAAY,CAAC,KAAa,EAAE,GAAgC;IACnE,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnB,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,KAAc,EAAE,EAAE;IACvE,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7C,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,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,IAG3B,CAAC;IAEF,IAAI,QAAQ,IAAI,IAAI,IAAI,
|
|
1
|
+
{"version":3,"file":"awareness.js","sourceRoot":"","sources":["../../src/collab/awareness.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Server-side awareness state management for collaborative editing.\n *\n * Stores per-client awareness state (cursor positions, user info) in memory.\n * Clients POST their state and receive other clients' states via polling.\n * States expire after 30 seconds of no updates.\n *\n * Fast-path: when a client POSTs new awareness state, the server emits an\n * event on the awareness emitter so SSE-connected peers receive cursor moves\n * push-style instead of waiting for the next poll cycle.\n */\n\nimport { EventEmitter } from \"node:events\";\n\nimport { defineEventHandler, setResponseStatus, getRouterParam } from \"h3\";\nimport type { H3Event } from \"h3\";\n\nimport { readBody } from \"../server/h3-helpers.js\";\n\nconst AWARENESS_TIMEOUT = 30_000; // 30 seconds\n\nexport interface AwarenessEntry {\n clientId: number;\n state: string; // JSON-encoded awareness state object\n lastSeen: number;\n}\n\n// ---------------------------------------------------------------------------\n// Awareness event emitter — fast-path for push delivery to SSE-connected peers.\n// The SSE handler (poll-events) subscribes and forwards events to its stream.\n// ---------------------------------------------------------------------------\n\nexport const AWARENESS_CHANGE_EVENT = \"awareness-change\" as const;\n\nexport interface AwarenessChangeEvent {\n source: \"awareness\";\n type: \"awareness-change\";\n docId: string;\n /** Array of updated states for this document (all non-expired clients). */\n states: Array<{ clientId: number; state: string }>;\n /** Owner email for access-scoped delivery (taken from session if available). */\n owner?: string;\n /** Org ID for org-scoped delivery. */\n orgId?: string;\n}\n\nconst _awarenessEmitter = new EventEmitter();\n_awarenessEmitter.setMaxListeners(0);\n\nexport function getAwarenessEmitter(): EventEmitter {\n return _awarenessEmitter;\n}\n\nexport function emitAwarenessChange(\n docId: string,\n states: Array<{ clientId: number; state: string }>,\n owner?: string,\n orgId?: string,\n): void {\n const event: AwarenessChangeEvent = {\n source: \"awareness\",\n type: \"awareness-change\",\n docId,\n states,\n ...(owner && { owner }),\n ...(orgId && { orgId }),\n };\n _awarenessEmitter.emit(AWARENESS_CHANGE_EVENT, event);\n}\n\n// docId → Map<clientId, AwarenessEntry>\nconst _awarenessMap = new Map<string, Map<number, AwarenessEntry>>();\n\nexport function getDocAwareness(docId: string): Map<number, AwarenessEntry> {\n let map = _awarenessMap.get(docId);\n if (!map) {\n map = new Map();\n _awarenessMap.set(docId, map);\n }\n return map;\n}\n\nexport function cleanExpired(map: Map<number, AwarenessEntry>): void {\n const now = Date.now();\n for (const [clientId, entry] of map) {\n if (now - entry.lastSeen > AWARENESS_TIMEOUT) {\n map.delete(clientId);\n }\n }\n}\n\n// Drop the per-document map from the registry once it has no entries left,\n// so the outer map does not grow unbounded with every docId ever touched.\nfunction pruneIfEmpty(docId: string, map: Map<number, AwarenessEntry>): void {\n if (map.size === 0) {\n _awarenessMap.delete(docId);\n }\n}\n\n/**\n * POST /_agent-native/collab/:docId/awareness\n *\n * Client sends its awareness state and receives other clients' states.\n *\n * Body: { clientId: number, state: string | null (JSON-encoded awareness state, or null to clear) }\n * Response: { states: Array<{ clientId: number, state: string }> }\n */\nexport const postAwareness = defineEventHandler(async (event: H3Event) => {\n const docId = getRouterParam(event, \"docId\");\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const body = await readBody(event);\n const { clientId, state } = body as {\n clientId?: number;\n state?: string | null;\n };\n\n if (clientId == null || state === undefined) {\n // `!clientId` would wrongly reject clientId === 0, which is a valid\n // (if rare) Yjs client id. A null state is valid: it clears this client.\n setResponseStatus(event, 400);\n return { error: \"clientId and state required\" };\n }\n\n const map = getDocAwareness(docId);\n\n if (state === null) {\n map.delete(clientId);\n } else {\n // Store this client's state\n map.set(clientId, { clientId, state, lastSeen: Date.now() });\n }\n\n // Clean expired entries, then prune the outer-map entry if it becomes empty.\n // Without pruning, a deployment with many transient docIds (e.g. one per\n // session) would grow _awarenessMap without bound.\n cleanExpired(map);\n // Null-state clears and expiry can empty the map; prune the outer entry so\n // transient document ids do not accumulate.\n pruneIfEmpty(docId, map);\n\n // Build the full list of current states (all clients including sender).\n const allStates: Array<{ clientId: number; state: string }> = [];\n const otherStates: Array<{ clientId: number; state: string }> = [];\n for (const [id, entry] of map) {\n allStates.push({ clientId: id, state: entry.state });\n if (id !== clientId) {\n otherStates.push({ clientId: id, state: entry.state });\n }\n }\n\n // Fast-path: push the updated state set to SSE-connected peers so they\n // don't have to wait for the next poll cycle for cursor/selection updates.\n emitAwarenessChange(docId, allStates);\n\n return { states: otherStates };\n});\n\n/**\n * GET /_agent-native/collab/:docId/users\n *\n * Returns the list of active users for a document (for presence bar).\n */\nexport const getActiveUsers = defineEventHandler(async (event: H3Event) => {\n const docId = getRouterParam(event, \"docId\");\n if (!docId) {\n setResponseStatus(event, 400);\n return { error: \"docId required\" };\n }\n\n const map = getDocAwareness(docId);\n cleanExpired(map);\n pruneIfEmpty(docId, map);\n\n const users: Array<{ clientId: number; lastSeen: number }> = [];\n for (const [, entry] of map) {\n users.push({ clientId: entry.clientId, lastSeen: entry.lastSeen });\n }\n\n return { users };\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAKzB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,IAAI,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAC;CACvB;AAgBD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAYD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAY1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,CA6BT;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,uBAAuB,EAAE,GACtC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B3D;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/collab/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAKzB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kFAAkF;IAClF,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,4EAA4E;IAC5E,IAAI,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,kEAAkE;IAClE,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,YAAY,EAAE,OAAO,CAAC;CACvB;AAgBD,4DAA4D;AAC5D,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAYD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,UAAU,EAAE,CAY1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACvC,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACvC,OAAO,CA6BT;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,uBAAuB,EAAE,GACtC;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,CA2B3D;AA6ED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,0BAA0B,GAClC,yBAAyB,CAgpB3B"}
|
package/dist/collab/client.js
CHANGED
|
@@ -197,12 +197,13 @@ function scheduleAwarenessPush(baseUrl, docId, clientId, getState) {
|
|
|
197
197
|
const timer = setTimeout(() => {
|
|
198
198
|
_awarenessThrottleTimers.delete(key);
|
|
199
199
|
const state = getState();
|
|
200
|
-
if (!state)
|
|
201
|
-
return;
|
|
202
200
|
fetch(`${baseUrl}/${docId}/awareness`, {
|
|
203
201
|
method: "POST",
|
|
204
202
|
headers: { "Content-Type": "application/json" },
|
|
205
|
-
body: JSON.stringify({
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
clientId,
|
|
205
|
+
state: state ? JSON.stringify(state) : null,
|
|
206
|
+
}),
|
|
206
207
|
}).catch(() => { }); // best-effort; poll cycle is the baseline fallback
|
|
207
208
|
}, 150);
|
|
208
209
|
_awarenessThrottleTimers.set(key, timer);
|