@promptbook/components 0.112.0-59 → 0.112.0-60
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/esm/index.es.js +502 -355
- package/esm/index.es.js.map +1 -1
- package/esm/src/book-components/BookEditor/useBookEditorMonacoInteractions.d.ts +40 -0
- package/esm/src/book-components/BookEditor/useBookEditorMonacoLifecycle.d.ts +34 -0
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +2 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +502 -355
- package/umd/index.umd.js.map +1 -1
- package/umd/src/book-components/BookEditor/useBookEditorMonacoInteractions.d.ts +40 -0
- package/umd/src/book-components/BookEditor/useBookEditorMonacoLifecycle.d.ts +34 -0
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +2 -0
- package/umd/src/version.d.ts +1 -1
package/umd/index.umd.js
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* @generated
|
|
31
31
|
* @see https://github.com/webgptorg/promptbook
|
|
32
32
|
*/
|
|
33
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
33
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-60';
|
|
34
34
|
/**
|
|
35
35
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
36
36
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -23551,6 +23551,241 @@
|
|
|
23551
23551
|
}, [diagnostics, editor, monaco]);
|
|
23552
23552
|
}
|
|
23553
23553
|
|
|
23554
|
+
/**
|
|
23555
|
+
* Clipboard MIME types treated as rich text documents for upload.
|
|
23556
|
+
*
|
|
23557
|
+
* @private function of BookEditorMonaco
|
|
23558
|
+
*/
|
|
23559
|
+
const RICH_CLIPBOARD_TEXT_MIME_TYPES = new Set(['text/html', 'text/rtf']);
|
|
23560
|
+
/**
|
|
23561
|
+
* Uploaded filename mapping for known rich clipboard MIME types.
|
|
23562
|
+
*
|
|
23563
|
+
* @private function of BookEditorMonaco
|
|
23564
|
+
*/
|
|
23565
|
+
const CLIPBOARD_RICH_CONTENT_FILENAMES = {
|
|
23566
|
+
'text/html': 'clipboard-content.html',
|
|
23567
|
+
'text/rtf': 'clipboard-content.rtf',
|
|
23568
|
+
'application/rtf': 'clipboard-content.rtf',
|
|
23569
|
+
};
|
|
23570
|
+
/**
|
|
23571
|
+
* Fallback filename used when clipboard MIME type is unknown.
|
|
23572
|
+
*
|
|
23573
|
+
* @private function of BookEditorMonaco
|
|
23574
|
+
*/
|
|
23575
|
+
const DEFAULT_CLIPBOARD_RICH_CONTENT_FILENAME = 'clipboard-content.txt';
|
|
23576
|
+
/**
|
|
23577
|
+
* Maximum pointer travel still treated as a tap on the touch focus overlay.
|
|
23578
|
+
*
|
|
23579
|
+
* @private function of BookEditorMonaco
|
|
23580
|
+
*/
|
|
23581
|
+
const TOUCH_TAP_THRESHOLD = 10;
|
|
23582
|
+
/**
|
|
23583
|
+
* Lists transferable items from a browser `DataTransfer` object.
|
|
23584
|
+
*
|
|
23585
|
+
* @private function of BookEditorMonaco
|
|
23586
|
+
*/
|
|
23587
|
+
function listDataTransferItems(dataTransfer) {
|
|
23588
|
+
const items = [];
|
|
23589
|
+
for (let index = 0; index < dataTransfer.items.length; index++) {
|
|
23590
|
+
const item = dataTransfer.items[index];
|
|
23591
|
+
if (item) {
|
|
23592
|
+
items.push(item);
|
|
23593
|
+
}
|
|
23594
|
+
}
|
|
23595
|
+
return items;
|
|
23596
|
+
}
|
|
23597
|
+
/**
|
|
23598
|
+
* Removes duplicate files by using stable file metadata signature.
|
|
23599
|
+
*
|
|
23600
|
+
* @private function of BookEditorMonaco
|
|
23601
|
+
*/
|
|
23602
|
+
function deduplicateFiles(files) {
|
|
23603
|
+
const uniqueFiles = new Map();
|
|
23604
|
+
for (const file of files) {
|
|
23605
|
+
uniqueFiles.set(`${file.name}:${file.type}:${file.size}`, file);
|
|
23606
|
+
}
|
|
23607
|
+
return Array.from(uniqueFiles.values());
|
|
23608
|
+
}
|
|
23609
|
+
/**
|
|
23610
|
+
* Extracts all file-like clipboard/drop payloads from a `DataTransfer`.
|
|
23611
|
+
*
|
|
23612
|
+
* @private function of BookEditorMonaco
|
|
23613
|
+
*/
|
|
23614
|
+
function getDataTransferFiles(dataTransfer) {
|
|
23615
|
+
const directFiles = Array.from(dataTransfer.files || []);
|
|
23616
|
+
const itemFiles = listDataTransferItems(dataTransfer)
|
|
23617
|
+
.filter((item) => item.kind === 'file')
|
|
23618
|
+
.map((item) => item.getAsFile())
|
|
23619
|
+
.filter((file) => file !== null);
|
|
23620
|
+
return deduplicateFiles([...directFiles, ...itemFiles]);
|
|
23621
|
+
}
|
|
23622
|
+
/**
|
|
23623
|
+
* Picks the richest textual clipboard item that should be uploaded as a document.
|
|
23624
|
+
*
|
|
23625
|
+
* @private function of BookEditorMonaco
|
|
23626
|
+
*/
|
|
23627
|
+
function getRichClipboardTextItem(dataTransfer) {
|
|
23628
|
+
const items = listDataTransferItems(dataTransfer);
|
|
23629
|
+
const hasPlainTextItem = items.some((item) => item.kind === 'string' && item.type.toLowerCase() === 'text/plain');
|
|
23630
|
+
const applicationItem = items.find((item) => item.kind === 'string' && item.type.toLowerCase().startsWith('application/'));
|
|
23631
|
+
if (applicationItem) {
|
|
23632
|
+
return applicationItem;
|
|
23633
|
+
}
|
|
23634
|
+
if (hasPlainTextItem) {
|
|
23635
|
+
return null;
|
|
23636
|
+
}
|
|
23637
|
+
const richTextItem = items.find((item) => {
|
|
23638
|
+
if (item.kind !== 'string') {
|
|
23639
|
+
return false;
|
|
23640
|
+
}
|
|
23641
|
+
return RICH_CLIPBOARD_TEXT_MIME_TYPES.has(item.type.toLowerCase());
|
|
23642
|
+
});
|
|
23643
|
+
return richTextItem || null;
|
|
23644
|
+
}
|
|
23645
|
+
/**
|
|
23646
|
+
* Resolves whether paste should route into upload workflow instead of text insert.
|
|
23647
|
+
*
|
|
23648
|
+
* @private function of BookEditorMonaco
|
|
23649
|
+
*/
|
|
23650
|
+
function hasUploadableClipboardContent(dataTransfer) {
|
|
23651
|
+
if (getDataTransferFiles(dataTransfer).length > 0) {
|
|
23652
|
+
return true;
|
|
23653
|
+
}
|
|
23654
|
+
return getRichClipboardTextItem(dataTransfer) !== null;
|
|
23655
|
+
}
|
|
23656
|
+
/**
|
|
23657
|
+
* Reads string payload from clipboard item.
|
|
23658
|
+
*
|
|
23659
|
+
* @private function of BookEditorMonaco
|
|
23660
|
+
*/
|
|
23661
|
+
function getClipboardItemString(item) {
|
|
23662
|
+
return new Promise((resolve) => {
|
|
23663
|
+
try {
|
|
23664
|
+
item.getAsString((value) => resolve(value || ''));
|
|
23665
|
+
}
|
|
23666
|
+
catch (_a) {
|
|
23667
|
+
resolve('');
|
|
23668
|
+
}
|
|
23669
|
+
});
|
|
23670
|
+
}
|
|
23671
|
+
/**
|
|
23672
|
+
* Determines filename for generated clipboard rich-content uploads.
|
|
23673
|
+
*
|
|
23674
|
+
* @private function of BookEditorMonaco
|
|
23675
|
+
*/
|
|
23676
|
+
function getClipboardRichContentFilename(mimeType) {
|
|
23677
|
+
return CLIPBOARD_RICH_CONTENT_FILENAMES[mimeType.toLowerCase()] || DEFAULT_CLIPBOARD_RICH_CONTENT_FILENAME;
|
|
23678
|
+
}
|
|
23679
|
+
/**
|
|
23680
|
+
* Converts clipboard payload into upload-ready files.
|
|
23681
|
+
*
|
|
23682
|
+
* @private function of BookEditorMonaco
|
|
23683
|
+
*/
|
|
23684
|
+
async function resolveClipboardUploadFiles(dataTransfer) {
|
|
23685
|
+
const files = getDataTransferFiles(dataTransfer);
|
|
23686
|
+
if (files.length > 0) {
|
|
23687
|
+
return files;
|
|
23688
|
+
}
|
|
23689
|
+
const richTextItem = getRichClipboardTextItem(dataTransfer);
|
|
23690
|
+
if (!richTextItem) {
|
|
23691
|
+
return [];
|
|
23692
|
+
}
|
|
23693
|
+
const content = await getClipboardItemString(richTextItem);
|
|
23694
|
+
const mimeType = richTextItem.type || 'text/plain';
|
|
23695
|
+
if (!content.trim()) {
|
|
23696
|
+
return [];
|
|
23697
|
+
}
|
|
23698
|
+
return [new File([content], getClipboardRichContentFilename(mimeType), { type: mimeType })];
|
|
23699
|
+
}
|
|
23700
|
+
/**
|
|
23701
|
+
* Manages drag, paste and file input interactions for `BookEditorMonaco`.
|
|
23702
|
+
*
|
|
23703
|
+
* @private function of BookEditorMonaco
|
|
23704
|
+
*/
|
|
23705
|
+
function useBookEditorMonacoInteractions({ editor, handleFiles, }) {
|
|
23706
|
+
const [isDragOver, setIsDragOver] = react.useState(false);
|
|
23707
|
+
const touchStartRef = react.useRef(null);
|
|
23708
|
+
const fileUploadInputRef = react.useRef(null);
|
|
23709
|
+
const cameraInputRef = react.useRef(null);
|
|
23710
|
+
const handleDrop = react.useCallback(async (event) => {
|
|
23711
|
+
event.preventDefault();
|
|
23712
|
+
setIsDragOver(false);
|
|
23713
|
+
const files = getDataTransferFiles(event.dataTransfer);
|
|
23714
|
+
await handleFiles(files);
|
|
23715
|
+
}, [handleFiles]);
|
|
23716
|
+
const handlePaste = react.useCallback(async (event) => {
|
|
23717
|
+
const clipboardData = event.clipboardData;
|
|
23718
|
+
if (!hasUploadableClipboardContent(clipboardData)) {
|
|
23719
|
+
return;
|
|
23720
|
+
}
|
|
23721
|
+
event.preventDefault();
|
|
23722
|
+
event.stopPropagation();
|
|
23723
|
+
const files = await resolveClipboardUploadFiles(clipboardData);
|
|
23724
|
+
await handleFiles(files);
|
|
23725
|
+
}, [handleFiles]);
|
|
23726
|
+
const handleUploadDocument = react.useCallback(() => {
|
|
23727
|
+
var _a;
|
|
23728
|
+
(_a = fileUploadInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
23729
|
+
}, []);
|
|
23730
|
+
const handleTakePhoto = react.useCallback(() => {
|
|
23731
|
+
var _a;
|
|
23732
|
+
(_a = cameraInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
23733
|
+
}, []);
|
|
23734
|
+
const handleFileInputChange = react.useCallback((event) => {
|
|
23735
|
+
const files = Array.from(event.target.files || []);
|
|
23736
|
+
void handleFiles(files);
|
|
23737
|
+
event.target.value = '';
|
|
23738
|
+
}, [handleFiles]);
|
|
23739
|
+
const handleDragOver = react.useCallback((event) => {
|
|
23740
|
+
event.preventDefault();
|
|
23741
|
+
setIsDragOver(true);
|
|
23742
|
+
}, []);
|
|
23743
|
+
const handleDragEnter = react.useCallback((event) => {
|
|
23744
|
+
event.preventDefault();
|
|
23745
|
+
setIsDragOver(true);
|
|
23746
|
+
}, []);
|
|
23747
|
+
const handleDragLeave = react.useCallback((event) => {
|
|
23748
|
+
event.preventDefault();
|
|
23749
|
+
setIsDragOver(false);
|
|
23750
|
+
}, []);
|
|
23751
|
+
const handleFocusOverlayTouchStart = react.useCallback((event) => {
|
|
23752
|
+
const touch = event.touches[0];
|
|
23753
|
+
if (touch) {
|
|
23754
|
+
touchStartRef.current = { x: touch.clientX, y: touch.clientY };
|
|
23755
|
+
}
|
|
23756
|
+
}, []);
|
|
23757
|
+
const handleFocusOverlayTouchEnd = react.useCallback((event) => {
|
|
23758
|
+
event.preventDefault();
|
|
23759
|
+
const touch = event.changedTouches[0];
|
|
23760
|
+
if (touch && touchStartRef.current) {
|
|
23761
|
+
const deltaX = Math.abs(touch.clientX - touchStartRef.current.x);
|
|
23762
|
+
const deltaY = Math.abs(touch.clientY - touchStartRef.current.y);
|
|
23763
|
+
if (deltaX < TOUCH_TAP_THRESHOLD && deltaY < TOUCH_TAP_THRESHOLD) {
|
|
23764
|
+
editor === null || editor === void 0 ? void 0 : editor.focus();
|
|
23765
|
+
}
|
|
23766
|
+
}
|
|
23767
|
+
touchStartRef.current = null;
|
|
23768
|
+
}, [editor]);
|
|
23769
|
+
const focusOverlayTouchHandlers = react.useMemo(() => ({
|
|
23770
|
+
onTouchStart: handleFocusOverlayTouchStart,
|
|
23771
|
+
onTouchEnd: handleFocusOverlayTouchEnd,
|
|
23772
|
+
}), [handleFocusOverlayTouchEnd, handleFocusOverlayTouchStart]);
|
|
23773
|
+
return {
|
|
23774
|
+
isDragOver,
|
|
23775
|
+
fileUploadInputRef,
|
|
23776
|
+
cameraInputRef,
|
|
23777
|
+
handleDrop,
|
|
23778
|
+
handlePaste,
|
|
23779
|
+
handleUploadDocument,
|
|
23780
|
+
handleTakePhoto,
|
|
23781
|
+
handleFileInputChange,
|
|
23782
|
+
handleDragOver,
|
|
23783
|
+
handleDragEnter,
|
|
23784
|
+
handleDragLeave,
|
|
23785
|
+
focusOverlayTouchHandlers,
|
|
23786
|
+
};
|
|
23787
|
+
}
|
|
23788
|
+
|
|
23554
23789
|
/**
|
|
23555
23790
|
* Priority order for the important commitments shown first in catalogues and intellisense.
|
|
23556
23791
|
*
|
|
@@ -24213,6 +24448,181 @@
|
|
|
24213
24448
|
}, [monaco, theme]);
|
|
24214
24449
|
}
|
|
24215
24450
|
|
|
24451
|
+
/**
|
|
24452
|
+
* Local storage key that enables BookEditor Monaco lifecycle debug logs in development.
|
|
24453
|
+
*
|
|
24454
|
+
* @private function of BookEditorMonaco
|
|
24455
|
+
*/
|
|
24456
|
+
const BOOK_EDITOR_MONACO_DEBUG_STORAGE_KEY = 'promptbook-debug-book-editor-monaco';
|
|
24457
|
+
/**
|
|
24458
|
+
* Duration of the save notification.
|
|
24459
|
+
*
|
|
24460
|
+
* @private function of BookEditorMonaco
|
|
24461
|
+
*/
|
|
24462
|
+
const SAVE_NOTIFICATION_HIDE_DELAY_MS = 2000;
|
|
24463
|
+
/**
|
|
24464
|
+
* Resolves whether verbose BookEditor Monaco lifecycle logs are enabled.
|
|
24465
|
+
*
|
|
24466
|
+
* @private function of BookEditorMonaco
|
|
24467
|
+
*/
|
|
24468
|
+
function isBookEditorMonacoDebugEnabled() {
|
|
24469
|
+
if (process.env.NODE_ENV === 'production' || typeof window === 'undefined') {
|
|
24470
|
+
return false;
|
|
24471
|
+
}
|
|
24472
|
+
try {
|
|
24473
|
+
return window.localStorage.getItem(BOOK_EDITOR_MONACO_DEBUG_STORAGE_KEY) === '1';
|
|
24474
|
+
}
|
|
24475
|
+
catch (_a) {
|
|
24476
|
+
return false;
|
|
24477
|
+
}
|
|
24478
|
+
}
|
|
24479
|
+
/**
|
|
24480
|
+
* Prints one BookEditor Monaco debug line when the dev debug flag is enabled.
|
|
24481
|
+
*
|
|
24482
|
+
* @param message - Human-readable lifecycle message.
|
|
24483
|
+
*
|
|
24484
|
+
* @private function of BookEditorMonaco
|
|
24485
|
+
*/
|
|
24486
|
+
function logBookEditorMonacoDebug(message) {
|
|
24487
|
+
if (!isBookEditorMonacoDebugEnabled()) {
|
|
24488
|
+
return;
|
|
24489
|
+
}
|
|
24490
|
+
console.info(`[BookEditorMonaco] ${message}`);
|
|
24491
|
+
}
|
|
24492
|
+
/**
|
|
24493
|
+
* Detects whether the current device primarily uses a coarse pointer.
|
|
24494
|
+
*
|
|
24495
|
+
* @private function of BookEditorMonaco
|
|
24496
|
+
*/
|
|
24497
|
+
function detectIsTouchDevice() {
|
|
24498
|
+
if (typeof window === 'undefined') {
|
|
24499
|
+
return false;
|
|
24500
|
+
}
|
|
24501
|
+
return window.matchMedia('(pointer: coarse)').matches;
|
|
24502
|
+
}
|
|
24503
|
+
/**
|
|
24504
|
+
* Manages Monaco lifecycle wiring for `BookEditorMonaco`.
|
|
24505
|
+
*
|
|
24506
|
+
* @private function of BookEditorMonaco
|
|
24507
|
+
*/
|
|
24508
|
+
function useBookEditorMonacoLifecycle({ monaco, theme, }) {
|
|
24509
|
+
const [editor, setEditor] = react.useState(null);
|
|
24510
|
+
const [isFocused, setIsFocused] = react.useState(false);
|
|
24511
|
+
const [isTouchDevice, setIsTouchDevice] = react.useState(false);
|
|
24512
|
+
const [isSavedShown, setIsSavedShown] = react.useState(false);
|
|
24513
|
+
/**
|
|
24514
|
+
* Re-applies Book language + theme to the currently mounted Monaco model.
|
|
24515
|
+
*/
|
|
24516
|
+
const reapplyBookLanguageAndTheme = react.useCallback((reason) => {
|
|
24517
|
+
if (!editor || !monaco) {
|
|
24518
|
+
return;
|
|
24519
|
+
}
|
|
24520
|
+
ensureBookEditorMonacoLanguageForEditor({ monaco, monacoEditor: editor, theme });
|
|
24521
|
+
logBookEditorMonacoDebug(`Re-applied Book Monaco language/theme (${reason}).`);
|
|
24522
|
+
}, [editor, monaco, theme]);
|
|
24523
|
+
/**
|
|
24524
|
+
* Re-triggers the transient save toast without preventing the browser save dialog.
|
|
24525
|
+
*/
|
|
24526
|
+
const showSavedNotification = react.useCallback(() => {
|
|
24527
|
+
setIsSavedShown(false);
|
|
24528
|
+
setTimeout(() => setIsSavedShown(true), 0);
|
|
24529
|
+
}, []);
|
|
24530
|
+
react.useEffect(() => {
|
|
24531
|
+
setIsTouchDevice(detectIsTouchDevice());
|
|
24532
|
+
}, []);
|
|
24533
|
+
react.useEffect(() => {
|
|
24534
|
+
if (!editor || !monaco) {
|
|
24535
|
+
return;
|
|
24536
|
+
}
|
|
24537
|
+
const focusListener = editor.onDidFocusEditorWidget(() => {
|
|
24538
|
+
setIsFocused(true);
|
|
24539
|
+
reapplyBookLanguageAndTheme('focus');
|
|
24540
|
+
});
|
|
24541
|
+
const blurListener = editor.onDidBlurEditorWidget(() => {
|
|
24542
|
+
setIsFocused(false);
|
|
24543
|
+
});
|
|
24544
|
+
const saveAction = editor.addAction({
|
|
24545
|
+
id: 'save-book',
|
|
24546
|
+
label: 'Save',
|
|
24547
|
+
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS],
|
|
24548
|
+
run: () => {
|
|
24549
|
+
showSavedNotification();
|
|
24550
|
+
// Note: We don't prevent default, so browser's save dialog still opens
|
|
24551
|
+
},
|
|
24552
|
+
});
|
|
24553
|
+
return () => {
|
|
24554
|
+
focusListener.dispose();
|
|
24555
|
+
blurListener.dispose();
|
|
24556
|
+
saveAction.dispose();
|
|
24557
|
+
};
|
|
24558
|
+
}, [editor, monaco, reapplyBookLanguageAndTheme, showSavedNotification]);
|
|
24559
|
+
react.useEffect(() => {
|
|
24560
|
+
reapplyBookLanguageAndTheme('editor-ready');
|
|
24561
|
+
}, [reapplyBookLanguageAndTheme]);
|
|
24562
|
+
react.useEffect(() => {
|
|
24563
|
+
if (!editor || !monaco) {
|
|
24564
|
+
return;
|
|
24565
|
+
}
|
|
24566
|
+
const handlePopState = () => {
|
|
24567
|
+
reapplyBookLanguageAndTheme('history-popstate');
|
|
24568
|
+
};
|
|
24569
|
+
const handlePageShow = () => {
|
|
24570
|
+
reapplyBookLanguageAndTheme('pageshow');
|
|
24571
|
+
};
|
|
24572
|
+
const handleWindowFocus = () => {
|
|
24573
|
+
reapplyBookLanguageAndTheme('window-focus');
|
|
24574
|
+
};
|
|
24575
|
+
const handleVisibilityChange = () => {
|
|
24576
|
+
if (document.visibilityState === 'visible') {
|
|
24577
|
+
reapplyBookLanguageAndTheme('visibility-visible');
|
|
24578
|
+
}
|
|
24579
|
+
};
|
|
24580
|
+
window.addEventListener('popstate', handlePopState);
|
|
24581
|
+
window.addEventListener('pageshow', handlePageShow);
|
|
24582
|
+
window.addEventListener('focus', handleWindowFocus);
|
|
24583
|
+
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
24584
|
+
return () => {
|
|
24585
|
+
window.removeEventListener('popstate', handlePopState);
|
|
24586
|
+
window.removeEventListener('pageshow', handlePageShow);
|
|
24587
|
+
window.removeEventListener('focus', handleWindowFocus);
|
|
24588
|
+
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
24589
|
+
};
|
|
24590
|
+
}, [editor, monaco, reapplyBookLanguageAndTheme]);
|
|
24591
|
+
react.useEffect(() => {
|
|
24592
|
+
if (!isSavedShown) {
|
|
24593
|
+
return;
|
|
24594
|
+
}
|
|
24595
|
+
const timer = setTimeout(() => {
|
|
24596
|
+
setIsSavedShown(false);
|
|
24597
|
+
}, SAVE_NOTIFICATION_HIDE_DELAY_MS);
|
|
24598
|
+
return () => {
|
|
24599
|
+
clearTimeout(timer);
|
|
24600
|
+
};
|
|
24601
|
+
}, [isSavedShown]);
|
|
24602
|
+
/**
|
|
24603
|
+
* Ensures Book language/tokenizer is ready before Monaco creates the editor model.
|
|
24604
|
+
*/
|
|
24605
|
+
const handleBeforeMonacoMount = react.useCallback((beforeMountMonaco) => {
|
|
24606
|
+
ensureBookEditorMonacoLanguage(beforeMountMonaco, theme);
|
|
24607
|
+
}, [theme]);
|
|
24608
|
+
/**
|
|
24609
|
+
* Re-applies Book language/theme once Monaco editor is mounted.
|
|
24610
|
+
*/
|
|
24611
|
+
const handleMonacoMount = react.useCallback((mountedEditor, mountedMonaco) => {
|
|
24612
|
+
setEditor(mountedEditor);
|
|
24613
|
+
ensureBookEditorMonacoLanguageForEditor({ monaco: mountedMonaco, monacoEditor: mountedEditor, theme });
|
|
24614
|
+
logBookEditorMonacoDebug('Mounted Monaco editor and re-applied Book language/theme.');
|
|
24615
|
+
}, [theme]);
|
|
24616
|
+
return {
|
|
24617
|
+
editor,
|
|
24618
|
+
isFocused,
|
|
24619
|
+
isTouchDevice,
|
|
24620
|
+
isSavedShown,
|
|
24621
|
+
handleBeforeMonacoMount,
|
|
24622
|
+
handleMonacoMount,
|
|
24623
|
+
};
|
|
24624
|
+
}
|
|
24625
|
+
|
|
24216
24626
|
/**
|
|
24217
24627
|
* Relative Y offset multiplier for aligning line background with Monaco rendering.
|
|
24218
24628
|
*
|
|
@@ -25022,190 +25432,101 @@
|
|
|
25022
25432
|
*/
|
|
25023
25433
|
const INVALID_CSS_IDENTIFIER_CHARACTER_PATTERN = /[^a-zA-Z0-9_-]/g;
|
|
25024
25434
|
/**
|
|
25025
|
-
*
|
|
25435
|
+
* Base Book editor font size before zoom scaling.
|
|
25026
25436
|
*
|
|
25027
25437
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25028
25438
|
*/
|
|
25029
|
-
const
|
|
25439
|
+
const BASE_FONT_SIZE = 20;
|
|
25030
25440
|
/**
|
|
25031
|
-
*
|
|
25441
|
+
* Minimum supported Book editor font size after zoom scaling.
|
|
25032
25442
|
*
|
|
25033
25443
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25034
25444
|
*/
|
|
25035
|
-
const
|
|
25036
|
-
'text/html': 'clipboard-content.html',
|
|
25037
|
-
'text/rtf': 'clipboard-content.rtf',
|
|
25038
|
-
'application/rtf': 'clipboard-content.rtf',
|
|
25039
|
-
};
|
|
25445
|
+
const MIN_FONT_SIZE = 8;
|
|
25040
25446
|
/**
|
|
25041
|
-
*
|
|
25042
|
-
*
|
|
25043
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25044
|
-
*/
|
|
25045
|
-
const DEFAULT_CLIPBOARD_RICH_CONTENT_FILENAME = 'clipboard-content.txt';
|
|
25046
|
-
/**
|
|
25047
|
-
* Local storage key that enables BookEditor Monaco lifecycle debug logs in development.
|
|
25048
|
-
*
|
|
25049
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25050
|
-
*/
|
|
25051
|
-
const BOOK_EDITOR_MONACO_DEBUG_STORAGE_KEY = 'promptbook-debug-book-editor-monaco';
|
|
25052
|
-
/**
|
|
25053
|
-
* Resolves whether verbose BookEditor Monaco lifecycle logs are enabled.
|
|
25447
|
+
* Default Monaco scrollbar size before zoom scaling.
|
|
25054
25448
|
*
|
|
25055
25449
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25056
25450
|
*/
|
|
25057
|
-
|
|
25058
|
-
if (process.env.NODE_ENV === 'production' || typeof window === 'undefined') {
|
|
25059
|
-
return false;
|
|
25060
|
-
}
|
|
25061
|
-
try {
|
|
25062
|
-
return window.localStorage.getItem(BOOK_EDITOR_MONACO_DEBUG_STORAGE_KEY) === '1';
|
|
25063
|
-
}
|
|
25064
|
-
catch (_a) {
|
|
25065
|
-
return false;
|
|
25066
|
-
}
|
|
25067
|
-
}
|
|
25068
|
-
/**
|
|
25069
|
-
* Prints one BookEditor Monaco debug line when the dev debug flag is enabled.
|
|
25070
|
-
*
|
|
25071
|
-
* @param message - Human-readable lifecycle message.
|
|
25072
|
-
*
|
|
25073
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25074
|
-
*/
|
|
25075
|
-
function logBookEditorMonacoDebug(message) {
|
|
25076
|
-
if (!isBookEditorMonacoDebugEnabled()) {
|
|
25077
|
-
return;
|
|
25078
|
-
}
|
|
25079
|
-
console.info(`[BookEditorMonaco] ${message}`);
|
|
25080
|
-
}
|
|
25081
|
-
/**
|
|
25082
|
-
* Lists transferable items from a browser `DataTransfer` object.
|
|
25083
|
-
*
|
|
25084
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25085
|
-
*/
|
|
25086
|
-
function listDataTransferItems(dataTransfer) {
|
|
25087
|
-
const items = [];
|
|
25088
|
-
for (let index = 0; index < dataTransfer.items.length; index++) {
|
|
25089
|
-
const item = dataTransfer.items[index];
|
|
25090
|
-
if (item) {
|
|
25091
|
-
items.push(item);
|
|
25092
|
-
}
|
|
25093
|
-
}
|
|
25094
|
-
return items;
|
|
25095
|
-
}
|
|
25096
|
-
/**
|
|
25097
|
-
* Removes duplicate files by using stable file metadata signature.
|
|
25098
|
-
*
|
|
25099
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25100
|
-
*/
|
|
25101
|
-
function deduplicateFiles(files) {
|
|
25102
|
-
const uniqueFiles = new Map();
|
|
25103
|
-
for (const file of files) {
|
|
25104
|
-
uniqueFiles.set(`${file.name}:${file.type}:${file.size}`, file);
|
|
25105
|
-
}
|
|
25106
|
-
return Array.from(uniqueFiles.values());
|
|
25107
|
-
}
|
|
25108
|
-
/**
|
|
25109
|
-
* Extracts all file-like clipboard/drop payloads from a `DataTransfer`.
|
|
25110
|
-
*
|
|
25111
|
-
* @private Internal utility of `BookEditorMonaco`.
|
|
25112
|
-
*/
|
|
25113
|
-
function getDataTransferFiles(dataTransfer) {
|
|
25114
|
-
const directFiles = Array.from(dataTransfer.files || []);
|
|
25115
|
-
const itemFiles = listDataTransferItems(dataTransfer)
|
|
25116
|
-
.filter((item) => item.kind === 'file')
|
|
25117
|
-
.map((item) => item.getAsFile())
|
|
25118
|
-
.filter((file) => file !== null);
|
|
25119
|
-
return deduplicateFiles([...directFiles, ...itemFiles]);
|
|
25120
|
-
}
|
|
25451
|
+
const BASE_SCROLLBAR_SIZE = 5;
|
|
25121
25452
|
/**
|
|
25122
|
-
*
|
|
25453
|
+
* Minimum Monaco scrollbar size after zoom scaling.
|
|
25123
25454
|
*
|
|
25124
25455
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25125
25456
|
*/
|
|
25126
|
-
|
|
25127
|
-
const items = listDataTransferItems(dataTransfer);
|
|
25128
|
-
const hasPlainTextItem = items.some((item) => item.kind === 'string' && item.type.toLowerCase() === 'text/plain');
|
|
25129
|
-
const applicationItem = items.find((item) => item.kind === 'string' && item.type.toLowerCase().startsWith('application/'));
|
|
25130
|
-
if (applicationItem) {
|
|
25131
|
-
return applicationItem;
|
|
25132
|
-
}
|
|
25133
|
-
if (hasPlainTextItem) {
|
|
25134
|
-
return null;
|
|
25135
|
-
}
|
|
25136
|
-
const richTextItem = items.find((item) => {
|
|
25137
|
-
if (item.kind !== 'string') {
|
|
25138
|
-
return false;
|
|
25139
|
-
}
|
|
25140
|
-
return RICH_CLIPBOARD_TEXT_MIME_TYPES.has(item.type.toLowerCase());
|
|
25141
|
-
});
|
|
25142
|
-
if (richTextItem) {
|
|
25143
|
-
return richTextItem;
|
|
25144
|
-
}
|
|
25145
|
-
return null;
|
|
25146
|
-
}
|
|
25457
|
+
const MIN_SCROLLBAR_SIZE = 2;
|
|
25147
25458
|
/**
|
|
25148
|
-
*
|
|
25459
|
+
* Minimum left padding Monaco reserves for custom line decorations.
|
|
25149
25460
|
*
|
|
25150
25461
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25151
25462
|
*/
|
|
25152
|
-
|
|
25153
|
-
if (getDataTransferFiles(dataTransfer).length > 0) {
|
|
25154
|
-
return true;
|
|
25155
|
-
}
|
|
25156
|
-
return getRichClipboardTextItem(dataTransfer) !== null;
|
|
25157
|
-
}
|
|
25463
|
+
const MIN_CONTENT_PADDING_LEFT = 8;
|
|
25158
25464
|
/**
|
|
25159
|
-
*
|
|
25465
|
+
* Creates a hydration-stable CSS class name from React's `useId()` value.
|
|
25160
25466
|
*
|
|
25161
25467
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25162
25468
|
*/
|
|
25163
|
-
function
|
|
25164
|
-
return
|
|
25165
|
-
try {
|
|
25166
|
-
item.getAsString((value) => resolve(value || ''));
|
|
25167
|
-
}
|
|
25168
|
-
catch (_a) {
|
|
25169
|
-
resolve('');
|
|
25170
|
-
}
|
|
25171
|
-
});
|
|
25469
|
+
function createStableBookEditorInstanceClassName(reactId) {
|
|
25470
|
+
return `book-editor-instance-${reactId.replace(INVALID_CSS_IDENTIFIER_CHARACTER_PATTERN, '-')}`;
|
|
25172
25471
|
}
|
|
25173
25472
|
/**
|
|
25174
|
-
*
|
|
25473
|
+
* Resolves Monaco layout values from the active Book editor zoom level.
|
|
25175
25474
|
*
|
|
25176
25475
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25177
25476
|
*/
|
|
25178
|
-
function
|
|
25179
|
-
return
|
|
25477
|
+
function createBookEditorMonacoScale(zoomLevel) {
|
|
25478
|
+
return {
|
|
25479
|
+
scaledLineHeight: Math.round(BookEditorMonacoConstants.LINE_HEIGHT * zoomLevel),
|
|
25480
|
+
scaledContentPaddingLeft: Math.max(MIN_CONTENT_PADDING_LEFT, Math.round(BookEditorMonacoConstants.CONTENT_PADDING_LEFT * zoomLevel)),
|
|
25481
|
+
scaledVerticalLineLeft: Math.max(0, Math.round(BookEditorMonacoConstants.VERTICAL_LINE_LEFT * zoomLevel)),
|
|
25482
|
+
scaledFontSize: Math.max(MIN_FONT_SIZE, Math.round(BASE_FONT_SIZE * zoomLevel)),
|
|
25483
|
+
scaledScrollbarSize: Math.max(MIN_SCROLLBAR_SIZE, Math.round(BASE_SCROLLBAR_SIZE * zoomLevel)),
|
|
25484
|
+
};
|
|
25180
25485
|
}
|
|
25181
25486
|
/**
|
|
25182
|
-
*
|
|
25487
|
+
* Determines whether the Book editor action bar should be shown.
|
|
25183
25488
|
*
|
|
25184
25489
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25185
25490
|
*/
|
|
25186
|
-
function
|
|
25187
|
-
return
|
|
25491
|
+
function isBookEditorMonacoActionbarVisible({ hoistedMenuItems, isUploadButtonShown, isCameraButtonShown, isDownloadButtonShown, isAboutButtonShown, isFullscreenButtonShown, }) {
|
|
25492
|
+
return (Boolean(hoistedMenuItems && hoistedMenuItems.length > 0) ||
|
|
25493
|
+
Boolean(isUploadButtonShown) ||
|
|
25494
|
+
Boolean(isCameraButtonShown) ||
|
|
25495
|
+
Boolean(isDownloadButtonShown) ||
|
|
25496
|
+
Boolean(isAboutButtonShown) ||
|
|
25497
|
+
Boolean(isFullscreenButtonShown));
|
|
25188
25498
|
}
|
|
25189
25499
|
/**
|
|
25190
|
-
*
|
|
25500
|
+
* Builds the Monaco editor options consumed by `MonacoEditorWithShadowDom`.
|
|
25191
25501
|
*
|
|
25192
25502
|
* @private Internal utility of `BookEditorMonaco`.
|
|
25193
25503
|
*/
|
|
25194
|
-
|
|
25195
|
-
|
|
25196
|
-
|
|
25197
|
-
|
|
25198
|
-
|
|
25199
|
-
|
|
25200
|
-
|
|
25201
|
-
|
|
25202
|
-
|
|
25203
|
-
|
|
25204
|
-
|
|
25205
|
-
|
|
25206
|
-
|
|
25207
|
-
|
|
25208
|
-
|
|
25504
|
+
function createBookEditorMonacoOptions({ isReadonly, translations, scaledFontSize, scaledLineHeight, scaledContentPaddingLeft, scaledScrollbarSize, }) {
|
|
25505
|
+
return {
|
|
25506
|
+
readOnly: isReadonly,
|
|
25507
|
+
readOnlyMessage: {
|
|
25508
|
+
value: (translations === null || translations === void 0 ? void 0 : translations.readonlyMessage) || 'You cannot edit this book',
|
|
25509
|
+
},
|
|
25510
|
+
wordWrap: 'on',
|
|
25511
|
+
minimap: { enabled: false },
|
|
25512
|
+
lineNumbers: 'off',
|
|
25513
|
+
fontSize: scaledFontSize,
|
|
25514
|
+
fontFamily: `"Playfair Display", serif`,
|
|
25515
|
+
lineHeight: scaledLineHeight,
|
|
25516
|
+
renderLineHighlight: 'none',
|
|
25517
|
+
lineDecorationsWidth: scaledContentPaddingLeft,
|
|
25518
|
+
glyphMargin: false,
|
|
25519
|
+
folding: false,
|
|
25520
|
+
lineNumbersMinChars: 0,
|
|
25521
|
+
links: true,
|
|
25522
|
+
scrollbar: {
|
|
25523
|
+
vertical: 'auto',
|
|
25524
|
+
horizontal: 'hidden',
|
|
25525
|
+
verticalScrollbarSize: scaledScrollbarSize,
|
|
25526
|
+
arrowSize: 0,
|
|
25527
|
+
useShadows: false,
|
|
25528
|
+
},
|
|
25529
|
+
};
|
|
25209
25530
|
}
|
|
25210
25531
|
/**
|
|
25211
25532
|
* Handles book editor monaco.
|
|
@@ -25215,29 +25536,40 @@
|
|
|
25215
25536
|
function BookEditorMonaco(props) {
|
|
25216
25537
|
const { value, onChange, diagnostics, isReadonly, theme = 'LIGHT', translations, onFileUpload, isUploadButtonShown, isCameraButtonShown, isDownloadButtonShown, isAboutButtonShown = true, isFullscreenButtonShown = true, onFullscreenClick, isFullscreen, zoom = 1, monacoModelPath, hoistedMenuItems, } = props;
|
|
25217
25538
|
const zoomLevel = zoom;
|
|
25218
|
-
const scaledLineHeight =
|
|
25219
|
-
const scaledContentPaddingLeft = Math.max(8, Math.round(BookEditorMonacoConstants.CONTENT_PADDING_LEFT * zoomLevel));
|
|
25220
|
-
const scaledVerticalLineLeft = Math.max(0, Math.round(BookEditorMonacoConstants.VERTICAL_LINE_LEFT * zoomLevel));
|
|
25221
|
-
const baseFontSize = 20;
|
|
25222
|
-
const scaledFontSize = Math.max(8, Math.round(baseFontSize * zoomLevel));
|
|
25223
|
-
const scaledScrollbarSize = Math.max(2, Math.round(5 * zoomLevel));
|
|
25224
|
-
const [isDragOver, setIsDragOver] = react.useState(false);
|
|
25225
|
-
const [editor, setEditor] = react.useState(null);
|
|
25226
|
-
const [isFocused, setIsFocused] = react.useState(false);
|
|
25227
|
-
const [isTouchDevice, setIsTouchDevice] = react.useState(false);
|
|
25228
|
-
const [isSavedShown, setIsSavedShown] = react.useState(false);
|
|
25539
|
+
const { scaledLineHeight, scaledContentPaddingLeft, scaledVerticalLineLeft, scaledFontSize, scaledScrollbarSize } = createBookEditorMonacoScale(zoomLevel);
|
|
25229
25540
|
const monaco = MonacoEditor.useMonaco();
|
|
25230
25541
|
const reactId = react.useId();
|
|
25231
25542
|
const instanceClass = createStableBookEditorInstanceClassName(reactId);
|
|
25232
|
-
const
|
|
25233
|
-
|
|
25234
|
-
|
|
25543
|
+
const { editor, isFocused, isTouchDevice, isSavedShown, handleBeforeMonacoMount, handleMonacoMount } = useBookEditorMonacoLifecycle({
|
|
25544
|
+
monaco,
|
|
25545
|
+
theme,
|
|
25546
|
+
});
|
|
25235
25547
|
const { activeUploadItems, uploadStats, pauseUpload, resumeUpload, handleFiles } = useBookEditorMonacoUploads({
|
|
25236
25548
|
editor,
|
|
25237
25549
|
monaco,
|
|
25238
25550
|
onFileUpload,
|
|
25239
25551
|
});
|
|
25552
|
+
const { isDragOver, fileUploadInputRef, cameraInputRef, handleDrop, handlePaste, handleUploadDocument, handleTakePhoto, handleFileInputChange, handleDragOver, handleDragEnter, handleDragLeave, focusOverlayTouchHandlers, } = useBookEditorMonacoInteractions({
|
|
25553
|
+
editor,
|
|
25554
|
+
handleFiles,
|
|
25555
|
+
});
|
|
25240
25556
|
const combinedDiagnostics = [...(diagnostics || []), ...createDeprecatedCommitmentDiagnostics(value)];
|
|
25557
|
+
const isActionBarVisible = isBookEditorMonacoActionbarVisible({
|
|
25558
|
+
hoistedMenuItems,
|
|
25559
|
+
isUploadButtonShown,
|
|
25560
|
+
isCameraButtonShown,
|
|
25561
|
+
isDownloadButtonShown,
|
|
25562
|
+
isAboutButtonShown,
|
|
25563
|
+
isFullscreenButtonShown,
|
|
25564
|
+
});
|
|
25565
|
+
const monacoOptions = createBookEditorMonacoOptions({
|
|
25566
|
+
isReadonly,
|
|
25567
|
+
translations,
|
|
25568
|
+
scaledFontSize,
|
|
25569
|
+
scaledLineHeight,
|
|
25570
|
+
scaledContentPaddingLeft,
|
|
25571
|
+
scaledScrollbarSize,
|
|
25572
|
+
});
|
|
25241
25573
|
useBookEditorMonacoLanguage({ monaco, theme });
|
|
25242
25574
|
useBookEditorMonacoDiagnostics({ monaco, editor, diagnostics: combinedDiagnostics });
|
|
25243
25575
|
useBookEditorMonacoDecorations({ editor, monaco });
|
|
@@ -25249,171 +25581,6 @@
|
|
|
25249
25581
|
zoomLevel,
|
|
25250
25582
|
theme,
|
|
25251
25583
|
});
|
|
25252
|
-
/**
|
|
25253
|
-
* Re-applies Book language + theme to the currently mounted Monaco model.
|
|
25254
|
-
*/
|
|
25255
|
-
const reapplyBookLanguageAndTheme = react.useCallback((reason) => {
|
|
25256
|
-
if (!editor || !monaco) {
|
|
25257
|
-
return;
|
|
25258
|
-
}
|
|
25259
|
-
ensureBookEditorMonacoLanguageForEditor({ monaco, monacoEditor: editor, theme });
|
|
25260
|
-
logBookEditorMonacoDebug(`Re-applied Book Monaco language/theme (${reason}).`);
|
|
25261
|
-
}, [editor, monaco, theme]);
|
|
25262
|
-
react.useEffect(() => {
|
|
25263
|
-
setIsTouchDevice(typeof window !== 'undefined' && window.matchMedia('(pointer: coarse)').matches);
|
|
25264
|
-
}, []);
|
|
25265
|
-
react.useEffect(() => {
|
|
25266
|
-
if (!editor || !monaco) {
|
|
25267
|
-
return;
|
|
25268
|
-
}
|
|
25269
|
-
const focusListener = editor.onDidFocusEditorWidget(() => {
|
|
25270
|
-
setIsFocused(true);
|
|
25271
|
-
reapplyBookLanguageAndTheme('focus');
|
|
25272
|
-
});
|
|
25273
|
-
const blurListener = editor.onDidBlurEditorWidget(() => {
|
|
25274
|
-
setIsFocused(false);
|
|
25275
|
-
});
|
|
25276
|
-
const saveAction = editor.addAction({
|
|
25277
|
-
id: 'save-book',
|
|
25278
|
-
label: 'Save',
|
|
25279
|
-
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS],
|
|
25280
|
-
run: () => {
|
|
25281
|
-
setIsSavedShown(false);
|
|
25282
|
-
setTimeout(() => setIsSavedShown(true), 0);
|
|
25283
|
-
// Note: We don't prevent default, so browser's save dialog still opens
|
|
25284
|
-
},
|
|
25285
|
-
});
|
|
25286
|
-
return () => {
|
|
25287
|
-
focusListener.dispose();
|
|
25288
|
-
blurListener.dispose();
|
|
25289
|
-
saveAction.dispose();
|
|
25290
|
-
};
|
|
25291
|
-
}, [editor, monaco, reapplyBookLanguageAndTheme]);
|
|
25292
|
-
react.useEffect(() => {
|
|
25293
|
-
reapplyBookLanguageAndTheme('editor-ready');
|
|
25294
|
-
}, [reapplyBookLanguageAndTheme]);
|
|
25295
|
-
react.useEffect(() => {
|
|
25296
|
-
if (!editor || !monaco) {
|
|
25297
|
-
return;
|
|
25298
|
-
}
|
|
25299
|
-
const handlePopState = () => {
|
|
25300
|
-
reapplyBookLanguageAndTheme('history-popstate');
|
|
25301
|
-
};
|
|
25302
|
-
const handlePageShow = () => {
|
|
25303
|
-
reapplyBookLanguageAndTheme('pageshow');
|
|
25304
|
-
};
|
|
25305
|
-
const handleWindowFocus = () => {
|
|
25306
|
-
reapplyBookLanguageAndTheme('window-focus');
|
|
25307
|
-
};
|
|
25308
|
-
const handleVisibilityChange = () => {
|
|
25309
|
-
if (document.visibilityState === 'visible') {
|
|
25310
|
-
reapplyBookLanguageAndTheme('visibility-visible');
|
|
25311
|
-
}
|
|
25312
|
-
};
|
|
25313
|
-
window.addEventListener('popstate', handlePopState);
|
|
25314
|
-
window.addEventListener('pageshow', handlePageShow);
|
|
25315
|
-
window.addEventListener('focus', handleWindowFocus);
|
|
25316
|
-
document.addEventListener('visibilitychange', handleVisibilityChange);
|
|
25317
|
-
return () => {
|
|
25318
|
-
window.removeEventListener('popstate', handlePopState);
|
|
25319
|
-
window.removeEventListener('pageshow', handlePageShow);
|
|
25320
|
-
window.removeEventListener('focus', handleWindowFocus);
|
|
25321
|
-
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
25322
|
-
};
|
|
25323
|
-
}, [editor, monaco, reapplyBookLanguageAndTheme]);
|
|
25324
|
-
react.useEffect(() => {
|
|
25325
|
-
if (!isSavedShown) {
|
|
25326
|
-
return;
|
|
25327
|
-
}
|
|
25328
|
-
const timer = setTimeout(() => {
|
|
25329
|
-
setIsSavedShown(false);
|
|
25330
|
-
}, 2000);
|
|
25331
|
-
return () => {
|
|
25332
|
-
clearTimeout(timer);
|
|
25333
|
-
};
|
|
25334
|
-
}, [isSavedShown]);
|
|
25335
|
-
const handleDrop = react.useCallback(async (event) => {
|
|
25336
|
-
event.preventDefault();
|
|
25337
|
-
setIsDragOver(false);
|
|
25338
|
-
const files = getDataTransferFiles(event.dataTransfer);
|
|
25339
|
-
await handleFiles(files);
|
|
25340
|
-
}, [handleFiles]);
|
|
25341
|
-
const handlePaste = react.useCallback(async (event) => {
|
|
25342
|
-
const clipboardData = event.clipboardData;
|
|
25343
|
-
if (!hasUploadableClipboardContent(clipboardData)) {
|
|
25344
|
-
return;
|
|
25345
|
-
}
|
|
25346
|
-
event.preventDefault();
|
|
25347
|
-
event.stopPropagation();
|
|
25348
|
-
const files = await resolveClipboardUploadFiles(clipboardData);
|
|
25349
|
-
await handleFiles(files);
|
|
25350
|
-
}, [handleFiles]);
|
|
25351
|
-
const handleUploadDocument = react.useCallback(() => {
|
|
25352
|
-
var _a;
|
|
25353
|
-
(_a = fileUploadInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
25354
|
-
}, []);
|
|
25355
|
-
const handleTakePhoto = react.useCallback(() => {
|
|
25356
|
-
var _a;
|
|
25357
|
-
(_a = cameraInputRef.current) === null || _a === void 0 ? void 0 : _a.click();
|
|
25358
|
-
}, []);
|
|
25359
|
-
const handleFileInputChange = react.useCallback((event) => {
|
|
25360
|
-
const files = Array.from(event.target.files || []);
|
|
25361
|
-
void handleFiles(files);
|
|
25362
|
-
event.target.value = '';
|
|
25363
|
-
}, [handleFiles]);
|
|
25364
|
-
/**
|
|
25365
|
-
* Ensures Book language/tokenizer is ready before Monaco creates the editor model.
|
|
25366
|
-
*/
|
|
25367
|
-
const handleBeforeMonacoMount = react.useCallback((beforeMountMonaco) => {
|
|
25368
|
-
ensureBookEditorMonacoLanguage(beforeMountMonaco, theme);
|
|
25369
|
-
}, [theme]);
|
|
25370
|
-
/**
|
|
25371
|
-
* Re-applies Book language/theme once Monaco editor is mounted.
|
|
25372
|
-
*/
|
|
25373
|
-
const handleMonacoMount = react.useCallback((mountedEditor, mountedMonaco) => {
|
|
25374
|
-
setEditor(mountedEditor);
|
|
25375
|
-
ensureBookEditorMonacoLanguageForEditor({ monaco: mountedMonaco, monacoEditor: mountedEditor, theme });
|
|
25376
|
-
logBookEditorMonacoDebug('Mounted Monaco editor and re-applied Book language/theme.');
|
|
25377
|
-
}, [theme]);
|
|
25378
|
-
const handleDragOver = react.useCallback((event) => {
|
|
25379
|
-
event.preventDefault();
|
|
25380
|
-
setIsDragOver(true);
|
|
25381
|
-
}, []);
|
|
25382
|
-
const handleDragEnter = react.useCallback((event) => {
|
|
25383
|
-
event.preventDefault();
|
|
25384
|
-
setIsDragOver(true);
|
|
25385
|
-
}, []);
|
|
25386
|
-
const handleDragLeave = react.useCallback((event) => {
|
|
25387
|
-
event.preventDefault();
|
|
25388
|
-
setIsDragOver(false);
|
|
25389
|
-
}, []);
|
|
25390
|
-
const focusOverlayTouchHandlers = {
|
|
25391
|
-
onTouchStart: (event) => {
|
|
25392
|
-
const touch = event.touches[0];
|
|
25393
|
-
if (touch) {
|
|
25394
|
-
touchStartRef.current = { x: touch.clientX, y: touch.clientY };
|
|
25395
|
-
}
|
|
25396
|
-
},
|
|
25397
|
-
onTouchEnd: (event) => {
|
|
25398
|
-
event.preventDefault();
|
|
25399
|
-
const touch = event.changedTouches[0];
|
|
25400
|
-
if (touch && touchStartRef.current) {
|
|
25401
|
-
const deltaX = Math.abs(touch.clientX - touchStartRef.current.x);
|
|
25402
|
-
const deltaY = Math.abs(touch.clientY - touchStartRef.current.y);
|
|
25403
|
-
const threshold = 10;
|
|
25404
|
-
if (deltaX < threshold && deltaY < threshold) {
|
|
25405
|
-
editor === null || editor === void 0 ? void 0 : editor.focus();
|
|
25406
|
-
}
|
|
25407
|
-
}
|
|
25408
|
-
touchStartRef.current = null;
|
|
25409
|
-
},
|
|
25410
|
-
};
|
|
25411
|
-
const isActionBarVisible = Boolean(hoistedMenuItems && hoistedMenuItems.length > 0) ||
|
|
25412
|
-
isUploadButtonShown ||
|
|
25413
|
-
isCameraButtonShown ||
|
|
25414
|
-
isDownloadButtonShown ||
|
|
25415
|
-
isAboutButtonShown ||
|
|
25416
|
-
isFullscreenButtonShown;
|
|
25417
25584
|
return (jsxRuntime.jsxs("div", { className: classNames(styles$d.bookEditorContainer, instanceClass), onDrop: handleDrop, onPaste: handlePaste, onDragOver: handleDragOver, onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, children: [isActionBarVisible && (jsxRuntime.jsx(BookEditorActionbar, { value,
|
|
25418
25585
|
isUploadButtonShown,
|
|
25419
25586
|
isCameraButtonShown: isCameraButtonShown !== null && isCameraButtonShown !== void 0 ? isCameraButtonShown : isTouchDevice,
|
|
@@ -25439,31 +25606,7 @@
|
|
|
25439
25606
|
height: '100%',
|
|
25440
25607
|
width: '100%',
|
|
25441
25608
|
backgroundColor: 'transparent',
|
|
25442
|
-
}, ...focusOverlayTouchHandlers })), jsxRuntime.jsx(MonacoEditorWithShadowDom, { language: BookEditorMonacoConstants.BOOK_LANGUAGE_ID, theme: BookEditorMonacoConstants.BOOK_THEME_ID, path: monacoModelPath, saveViewState: Boolean(monacoModelPath), value: value, beforeMount: handleBeforeMonacoMount, onMount: handleMonacoMount, onChange: (newValue) => onChange === null || onChange === void 0 ? void 0 : onChange(newValue), options: {
|
|
25443
|
-
readOnly: isReadonly,
|
|
25444
|
-
readOnlyMessage: {
|
|
25445
|
-
value: (translations === null || translations === void 0 ? void 0 : translations.readonlyMessage) || 'You cannot edit this book',
|
|
25446
|
-
},
|
|
25447
|
-
wordWrap: 'on',
|
|
25448
|
-
minimap: { enabled: false },
|
|
25449
|
-
lineNumbers: 'off',
|
|
25450
|
-
fontSize: scaledFontSize,
|
|
25451
|
-
fontFamily: `"Playfair Display", serif`,
|
|
25452
|
-
lineHeight: scaledLineHeight,
|
|
25453
|
-
renderLineHighlight: 'none',
|
|
25454
|
-
lineDecorationsWidth: scaledContentPaddingLeft,
|
|
25455
|
-
glyphMargin: false,
|
|
25456
|
-
folding: false,
|
|
25457
|
-
lineNumbersMinChars: 0,
|
|
25458
|
-
links: true,
|
|
25459
|
-
scrollbar: {
|
|
25460
|
-
vertical: 'auto',
|
|
25461
|
-
horizontal: 'hidden',
|
|
25462
|
-
verticalScrollbarSize: scaledScrollbarSize,
|
|
25463
|
-
arrowSize: 0,
|
|
25464
|
-
useShadows: false,
|
|
25465
|
-
},
|
|
25466
|
-
}, loading: jsxRuntime.jsx("div", { className: styles$d.loading, children: "\uD83D\uDCD6" }) })] })] }));
|
|
25609
|
+
}, ...focusOverlayTouchHandlers })), jsxRuntime.jsx(MonacoEditorWithShadowDom, { language: BookEditorMonacoConstants.BOOK_LANGUAGE_ID, theme: BookEditorMonacoConstants.BOOK_THEME_ID, path: monacoModelPath, saveViewState: Boolean(monacoModelPath), value: value, beforeMount: handleBeforeMonacoMount, onMount: handleMonacoMount, onChange: (newValue) => onChange === null || onChange === void 0 ? void 0 : onChange(newValue), options: monacoOptions, loading: jsxRuntime.jsx("div", { className: styles$d.loading, children: "\uD83D\uDCD6" }) })] })] }));
|
|
25467
25610
|
}
|
|
25468
25611
|
|
|
25469
25612
|
/**
|
|
@@ -41080,8 +41223,8 @@
|
|
|
41080
41223
|
* Prepares an AgentKit agent with optional knowledge sources and tool definitions.
|
|
41081
41224
|
*/
|
|
41082
41225
|
async prepareAgentKitAgent(options) {
|
|
41083
|
-
var _a, _b;
|
|
41084
|
-
const { name, instructions, knowledgeSources, tools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;
|
|
41226
|
+
var _a, _b, _c;
|
|
41227
|
+
const { name, instructions, knowledgeSources, tools, nativeAgentKitTools, vectorStoreId: cachedVectorStoreId, storeAsPrepared, } = options;
|
|
41085
41228
|
await this.ensureAgentKitDefaults();
|
|
41086
41229
|
if (this.options.isVerbose) {
|
|
41087
41230
|
console.info('[🤰]', 'Preparing OpenAI AgentKit agent', {
|
|
@@ -41089,6 +41232,7 @@
|
|
|
41089
41232
|
instructionsLength: instructions.length,
|
|
41090
41233
|
knowledgeSourcesCount: (_a = knowledgeSources === null || knowledgeSources === void 0 ? void 0 : knowledgeSources.length) !== null && _a !== void 0 ? _a : 0,
|
|
41091
41234
|
toolsCount: (_b = tools === null || tools === void 0 ? void 0 : tools.length) !== null && _b !== void 0 ? _b : 0,
|
|
41235
|
+
nativeAgentKitToolsCount: (_c = nativeAgentKitTools === null || nativeAgentKitTools === void 0 ? void 0 : nativeAgentKitTools.length) !== null && _c !== void 0 ? _c : 0,
|
|
41092
41236
|
});
|
|
41093
41237
|
}
|
|
41094
41238
|
let vectorStoreId = cachedVectorStoreId;
|
|
@@ -41107,7 +41251,7 @@
|
|
|
41107
41251
|
vectorStoreId,
|
|
41108
41252
|
});
|
|
41109
41253
|
}
|
|
41110
|
-
const agentKitTools = this.buildAgentKitTools({ tools, vectorStoreId });
|
|
41254
|
+
const agentKitTools = this.buildAgentKitTools({ tools, nativeAgentKitTools, vectorStoreId });
|
|
41111
41255
|
const openAiAgentKitAgent = new agents.Agent({
|
|
41112
41256
|
name,
|
|
41113
41257
|
model: this.agentKitModelName,
|
|
@@ -41146,11 +41290,14 @@
|
|
|
41146
41290
|
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
41147
41291
|
*/
|
|
41148
41292
|
buildAgentKitTools(options) {
|
|
41149
|
-
const { tools, vectorStoreId } = options;
|
|
41293
|
+
const { tools, nativeAgentKitTools, vectorStoreId } = options;
|
|
41150
41294
|
const agentKitTools = [];
|
|
41151
41295
|
if (vectorStoreId) {
|
|
41152
41296
|
agentKitTools.push(agents.fileSearchTool(vectorStoreId));
|
|
41153
41297
|
}
|
|
41298
|
+
if (nativeAgentKitTools && nativeAgentKitTools.length > 0) {
|
|
41299
|
+
agentKitTools.push(...nativeAgentKitTools);
|
|
41300
|
+
}
|
|
41154
41301
|
if (tools && tools.length > 0) {
|
|
41155
41302
|
let scriptTools = null;
|
|
41156
41303
|
for (const toolDefinition of tools) {
|