@panphora/clayjs 1.15.2 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -5
- package/THIRD-PARTY-NOTICES.md +16 -0
- package/compat/highlight-11.9.0.min.js +1213 -0
- package/compat/highlight-LICENSE +29 -0
- package/compat/journal-assets.lock.json +22 -0
- package/compat/overtype-2.6.1.min.js +116 -0
- package/compat/overtype-LICENSE +21 -0
- package/dist/all.js +90 -0
- package/dist/clay-dom.js +84 -0
- package/dist/clay-events.js +103 -0
- package/dist/clay-internals.js +85 -0
- package/dist/clay-options.js +93 -0
- package/dist/clay-router.js +98 -0
- package/dist/clay-ui.js +95 -0
- package/dist/clay-utils.js +84 -0
- package/dist/clay.js +146 -0
- package/dist/clay.standalone.js +83090 -58706
- package/dist/m/attrs/add-from-T5LJXFFI.js +1 -0
- package/dist/m/attrs/onaftersave-OKSWEJQF.js +1 -0
- package/dist/m/attrs/refetch-on-save-NWPPXOCZ.js +1 -0
- package/dist/m/attrs/save-freeze-FUP4Q4X3.js +1 -0
- package/dist/m/c-2AZDZWCK.js +1 -0
- package/dist/m/c-2JL6E75N.js +1 -0
- package/dist/m/c-2M73252O.js +1 -0
- package/dist/m/c-2SPVQSHC.js +1 -0
- package/dist/m/c-33HUYEDI.js +1 -0
- package/dist/m/c-33JJ6CBX.js +2 -0
- package/dist/m/c-35NBGMZB.js +1 -0
- package/dist/m/c-3GJ4SDE2.js +1 -0
- package/dist/m/c-3IQRECYS.js +1 -0
- package/dist/m/c-3OWDMNJR.js +2 -0
- package/dist/m/c-46XYM55L.js +1 -0
- package/dist/m/c-4B6H4G5V.js +1 -0
- package/dist/m/c-4DRMS4QG.js +9 -0
- package/dist/m/c-4FFHZM32.js +1 -0
- package/dist/m/c-4JZDZFF6.js +1 -0
- package/dist/m/c-4L3BTFRK.js +1 -0
- package/dist/m/c-4Q2XTQ2N.js +2 -0
- package/dist/m/c-4WKFKEKF.js +1 -0
- package/dist/m/c-4YSCRICO.js +1 -0
- package/dist/m/c-54RCDCBU.js +1 -0
- package/dist/m/c-5M4YEKCX.js +4 -0
- package/dist/m/c-5R4PTRG2.js +1 -0
- package/dist/m/c-5V3MOVJT.js +1 -0
- package/dist/m/c-5VYOWDTI.js +1 -0
- package/dist/m/c-5Y6TNX5W.js +34 -0
- package/dist/m/c-5YIHJ3TJ.js +1 -0
- package/dist/m/c-66O32MV3.js +28 -0
- package/dist/m/c-6HMB24EV.js +1 -0
- package/dist/m/c-7DJDKPGL.js +1 -0
- package/dist/m/c-7O6AFR65.js +1 -0
- package/dist/m/c-7SWMYKAI.js +1 -0
- package/dist/m/c-7VGZ7RU5.js +1 -0
- package/dist/m/c-A7LS5UZW.js +1 -0
- package/dist/m/c-ANQTJ3B5.js +2 -0
- package/dist/m/c-AQLFEATB.js +1 -0
- package/dist/m/c-AYVOREBE.js +1 -0
- package/dist/m/c-B2ZXPOS3.js +3 -0
- package/dist/m/c-BBVGTQG7.js +1 -0
- package/dist/m/c-BMIZKMPV.js +1 -0
- package/dist/m/c-BTDI4Y23.js +1 -0
- package/dist/m/c-BWFVSBDF.js +1 -0
- package/dist/m/c-BYTKL6UX.js +1 -0
- package/dist/m/c-CFHW5AMY.js +6 -0
- package/dist/m/c-CJZSLMVQ.js +1 -0
- package/dist/m/c-CYWLPPUS.js +1 -0
- package/dist/m/c-CZUSOB7V.js +1 -0
- package/dist/m/c-DBE6ORSI.js +1 -0
- package/dist/m/c-DCFSEJZG.js +1 -0
- package/dist/m/c-DNZ5IFM6.js +1 -0
- package/dist/m/c-EDHUR4MX.js +1 -0
- package/dist/m/c-EJTGYSLN.js +1 -0
- package/dist/m/c-EY6UOM54.js +1 -0
- package/dist/m/c-F3CKJTJS.js +1 -0
- package/dist/m/c-F7Y6FLPY.js +1 -0
- package/dist/m/c-FA4DZVTC.js +1 -0
- package/dist/m/c-FILLTJA7.js +1 -0
- package/dist/m/c-G2BUZITR.js +1 -0
- package/dist/m/c-GB3JTV6E.js +1 -0
- package/dist/m/c-GBGWXTX4.js +1 -0
- package/dist/m/c-GHBCCVG4.js +1 -0
- package/dist/m/c-GJAEGGXY.js +1 -0
- package/dist/m/c-GOWBDM6J.js +1 -0
- package/dist/m/c-GQ6F6IDK.js +1 -0
- package/dist/m/c-H4LG442Q.js +1 -0
- package/dist/m/c-HA6INT6J.js +1 -0
- package/dist/m/c-HPURYVZS.js +2 -0
- package/dist/m/c-HRDCD3WN.js +67 -0
- package/dist/m/c-HT33EQRN.js +1 -0
- package/dist/m/c-HVYXIS72.js +1 -0
- package/dist/m/c-IB52R237.js +1 -0
- package/dist/m/c-IJUK2GPW.js +1 -0
- package/dist/m/c-IKWNE4R4.js +1 -0
- package/dist/m/c-IU3IYEU6.js +1 -0
- package/dist/m/c-IZ2EBRAJ.js +1 -0
- package/dist/m/c-J7CA54IP.js +1 -0
- package/dist/m/c-JAX2667S.js +6 -0
- package/dist/m/c-KI7M4AY3.js +1 -0
- package/dist/m/c-KIPQJX4B.js +1 -0
- package/dist/m/c-KKWLDOPM.js +1 -0
- package/dist/m/c-KR4UW4KW.js +1 -0
- package/dist/m/c-KY3VJGUA.js +8 -0
- package/dist/m/c-L4WQSC27.js +1 -0
- package/dist/m/c-LFPHCXY3.js +1 -0
- package/dist/m/c-LR4CGEPT.js +91 -0
- package/dist/m/c-LRPUO2MX.js +1 -0
- package/dist/m/c-LTGMXXKO.js +1 -0
- package/dist/m/c-LXENEBV7.js +1 -0
- package/dist/m/c-LZJPNR2W.js +1 -0
- package/dist/m/c-MMUIUUZG.js +2 -0
- package/dist/m/c-MTQHWQC3.js +1 -0
- package/dist/m/c-N326R2JD.js +1 -0
- package/dist/m/c-N7JPUPGC.js +1 -0
- package/dist/m/c-NMJRXKPC.js +8 -0
- package/dist/m/c-NRPJEVJS.js +1 -0
- package/dist/m/c-NUHP2XDB.js +1 -0
- package/dist/m/c-NZMNXVF6.js +1 -0
- package/dist/m/c-OCSZ4QGN.js +1 -0
- package/dist/m/c-OIBUTDXI.js +1 -0
- package/dist/m/c-OIDRZKAF.js +1 -0
- package/dist/m/c-OYTFP5QN.js +1 -0
- package/dist/m/c-P7KNDG34.js +1 -0
- package/dist/m/c-PPOSCAQD.js +1 -0
- package/dist/m/c-PQ5LK6QE.js +993 -0
- package/dist/m/c-PZ4XEPUP.js +2 -0
- package/dist/m/c-QHIWXHRO.js +1 -0
- package/dist/m/c-QHWJ5ZIJ.js +1 -0
- package/dist/m/c-QIX5BJYN.js +1 -0
- package/dist/m/c-QNKREOL6.js +1 -0
- package/dist/m/c-QQHEX6HA.js +1 -0
- package/dist/m/c-R7RMANJI.js +9 -0
- package/dist/m/c-RI4NT75Y.js +1 -0
- package/dist/m/c-RM7J7BV2.js +1 -0
- package/dist/m/c-RUJKSUQW.js +1 -0
- package/dist/m/c-RVMWGXEJ.js +1 -0
- package/dist/m/c-S7H2DRCB.js +1 -0
- package/dist/m/c-S7LK4KUE.js +1 -0
- package/dist/m/c-SGCCC4FW.js +25 -0
- package/dist/m/c-SGIA4IEQ.js +188 -0
- package/dist/m/c-SWRJFCNN.js +1 -0
- package/dist/m/c-T4VO4OCB.js +1 -0
- package/dist/m/c-TCCA5BZN.js +2 -0
- package/dist/m/c-TQEMVJCS.js +1 -0
- package/dist/m/c-TQZ2JYHD.js +1 -0
- package/dist/m/c-TR6RMDQ7.js +3 -0
- package/dist/m/c-TRS6TM6O.js +1 -0
- package/dist/m/c-UGHH4MB3.js +1 -0
- package/dist/m/c-UKHTLWUW.js +1 -0
- package/dist/m/c-UL2YUY52.js +1 -0
- package/dist/m/c-UNN7LWCT.js +1 -0
- package/dist/m/c-UXBMRDZB.js +235 -0
- package/dist/m/c-V7PZZRG7.js +1 -0
- package/dist/m/c-VAK7SG37.js +1 -0
- package/dist/m/c-VDSS4K3Z.js +1 -0
- package/dist/m/c-VFX45IZQ.js +1 -0
- package/dist/m/c-VHNSBD2M.js +1 -0
- package/dist/m/c-VKEDWYDF.js +1 -0
- package/dist/m/c-VL52ADDR.js +1 -0
- package/dist/m/c-WN5AY3OZ.js +1 -0
- package/dist/m/c-WNYBLIOZ.js +1 -0
- package/dist/m/c-WRBKEJD4.js +1 -0
- package/dist/m/c-WWDBYXLK.js +1 -0
- package/dist/m/c-WYFDLITL.js +1 -0
- package/dist/m/c-XN6MBKI6.js +67 -0
- package/dist/m/c-XNNW2CWK.js +1 -0
- package/dist/m/c-XPELB6E5.js +1 -0
- package/dist/m/c-XQXZAO7N.js +1 -0
- package/dist/m/c-Y6USGTS5.js +5 -0
- package/dist/m/c-YDH7Q3NY.js +1 -0
- package/dist/m/c-YG2NJYS6.js +135 -0
- package/dist/m/c-Z36J63PP.js +1 -0
- package/dist/m/c-Z4VRC7GU.js +7 -0
- package/dist/m/c-Z6K52OLP.js +19 -0
- package/dist/m/c-ZDY2MDAA.js +21 -0
- package/dist/m/c-ZE46QDIH.js +1 -0
- package/dist/m/c-ZUCOKOHT.js +1 -0
- package/dist/m/core/admin-attrs-VGNLAUDK.js +1 -0
- package/dist/m/core/autosave-E4PEFPZ6.js +1 -0
- package/dist/m/core/conflict-notice-VQ6Y64PH.js +1 -0
- package/dist/m/core/draft-mode-WSQAT67S.js +1 -0
- package/dist/m/core/host-permission-XN3K2IW3.js +1 -0
- package/dist/m/core/is-edit-mode-JXHDVGUL.js +1 -0
- package/dist/m/core/persist-HKHA66IY.js +3 -0
- package/dist/m/core/recovery-TBBSICE2.js +1 -0
- package/dist/m/core/save-WUCHTQBE.js +1 -0
- package/dist/m/core/save-core-FJVHT5M3.js +1 -0
- package/dist/m/core/snapshot-F3SWDZMM.js +1 -0
- package/dist/m/core/unsaved-warning-STKBHE6G.js +1 -0
- package/dist/m/dom/all-APS5ZSKP.js +1 -0
- package/dist/m/dom/dom-helpers-L7OSR6S4.js +1 -0
- package/dist/m/events/index-23DPTUT4.js +1 -0
- package/dist/m/internals/index-WOVAP3RU.js +1 -0
- package/dist/m/lib/cache-bust-CGWT6ZJI.js +1 -0
- package/dist/m/lib/region-policy-SB2AWVG5.js +1 -0
- package/dist/m/loader-HXX6YNH5.js +1 -0
- package/dist/m/manifest-F22DEDAC.js +1 -0
- package/dist/m/manifest-edit-C3C7376B.js +1 -0
- package/dist/m/manifest.json +3491 -0
- package/dist/m/options/options-2LH76JQ3.js +1 -0
- package/dist/m/page/editor-XUTB2HB2.js +189 -0
- package/dist/m/plugins/ai-edit-ZQ4CGWIP.js +6 -0
- package/dist/m/plugins/bind-text-NX46N5UV.js +1 -0
- package/dist/m/plugins/cms-HP3LSTPN.js +2293 -0
- package/dist/m/plugins/demo-ZIBFAA3R.js +1 -0
- package/dist/m/plugins/derive-UAAA4V4S.js +1 -0
- package/dist/m/plugins/indicator-PV4YW2ID.js +1 -0
- package/dist/m/plugins/live-NUTTXSBS.js +1 -0
- package/dist/m/plugins/menu-HCKO3DSP.js +138 -0
- package/dist/m/plugins/message-LQ6EDH4V.js +1 -0
- package/dist/m/plugins/page-KSUH7G6J.js +2 -0
- package/dist/m/plugins/page-view-W73OW7WI.js +1 -0
- package/dist/m/plugins/people-AJJ32YCG.js +1 -0
- package/dist/m/plugins/quickcrop-QNY3PKLD.js +26 -0
- package/dist/m/plugins/quickcrop-QNY3PKLD.js.LEGAL.txt +7 -0
- package/dist/m/plugins/richclay-RC3L2F6X.js +517 -0
- package/dist/m/plugins/richclay-RC3L2F6X.js.LEGAL.txt +1 -0
- package/dist/m/plugins/sortable-YRMQX3ZU.js +1 -0
- package/dist/m/plugins/source-KHK5UUSK.js +1 -0
- package/dist/m/plugins/undo-OF2L3CXU.js +1 -0
- package/dist/m/plugins/unsent-HJFLQJ2O.js +1 -0
- package/dist/m/plugins/upgrade-ZNYODP5Y.js +1 -0
- package/dist/m/plugins/upload-XSGNILUY.js +1 -0
- package/dist/m/plugins/visitor-drafts-XK5GW55Q.js +21 -0
- package/dist/m/plugins/visitor-drafts-owner-KSSH75EV.js +1 -0
- package/dist/m/plugins/wire-ZWVWKF76.js +1 -0
- package/dist/m/reader-core-ILWLXVMP.js +68 -0
- package/dist/m/route/route-KOCZSEGN.js +1 -0
- package/dist/m/sync/live-sync-4AUVXVJU.js +1 -0
- package/dist/m/ui/index-EVHKMKBL.js +1 -0
- package/dist/m/utils/index-4TJCVLT7.js +1 -0
- package/dist/m/vendor/Sortable.vendor-A755ITLN.js +3 -0
- package/dist/m/vendor/Sortable.vendor-A755ITLN.js.LEGAL.txt +1 -0
- package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +6 -0
- package/dist/offline-manifest.json +3800 -0
- package/dist/page/themes/light-1.css +406 -0
- package/dist/server/core.cjs +23662 -22860
- package/dist/server/offline-runtime.cjs +4954 -0
- package/dist/server/offline-runtime.mjs +4923 -0
- package/dist/server/rooms.mjs +9 -0
- package/docs/guide.md +1078 -669
- package/entries/all.js +2 -0
- package/entries/clay-data.js +1 -1
- package/entries/clay-dom.js +2 -0
- package/entries/clay-events.js +2 -0
- package/entries/clay-internals.js +2 -0
- package/entries/clay-options.js +2 -0
- package/entries/clay-router.js +2 -0
- package/entries/clay-ui.js +2 -0
- package/entries/clay-utils.js +2 -0
- package/entries/clay.js +2 -0
- package/entries/sap.js +6 -6
- package/fonts/ibm-plex-mono-LICENSE +93 -0
- package/fonts/ibm-plex-mono-latin-300-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-400-italic.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-LICENSE +93 -0
- package/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/fonts/ibm-plex.css +71 -0
- package/fonts/inter-LICENSE +93 -0
- package/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
- package/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-greek-wght-normal.woff2 +0 -0
- package/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
- package/fonts/inter.css +62 -0
- package/fonts/newsreader-LICENSE +93 -0
- package/fonts/newsreader-latin-ext-opsz-normal.woff2 +0 -0
- package/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/fonts/newsreader-vietnamese-opsz-normal.woff2 +0 -0
- package/fonts/newsreader.css +26 -0
- package/fonts/work-sans-LICENSE +93 -0
- package/fonts/work-sans-latin-wght-normal.woff2 +0 -0
- package/fonts/work-sans.css +8 -0
- package/package.json +20 -3
- package/packed-contract.json +1 -0
- package/src/attrs/add-from.js +27 -4
- package/src/attrs/save-freeze.js +7 -52
- package/src/core/admin-attrs.js +119 -12
- package/src/core/admin-contenteditable.js +12 -10
- package/src/core/admin-inputs.js +14 -15
- package/src/core/admin-onclick.js +2 -0
- package/src/core/autosave.js +74 -21
- package/src/core/conflict-download.js +22 -0
- package/src/core/conflict-notice-ui.js +1173 -0
- package/src/core/conflict-notice.js +140 -697
- package/src/core/edit-mode.js +147 -14
- package/src/core/etag.js +30 -12
- package/src/core/host-meta.js +72 -8
- package/src/core/host-permission.js +29 -0
- package/src/core/is-edit-mode.js +145 -12
- package/src/core/mode-key.js +125 -0
- package/src/core/mode-lifecycle.js +544 -0
- package/src/core/mode-receipt.js +30 -0
- package/src/core/mode-refusal.js +13 -0
- package/src/core/mode-resources.js +52 -0
- package/src/core/mode-support.js +82 -0
- package/src/core/mode-switch.js +259 -0
- package/src/core/mode-transition.js +112 -0
- package/src/core/page-data-write.js +305 -0
- package/src/core/page-data.js +26 -227
- package/src/core/page-format-wire.js +4 -0
- package/src/core/page-format.js +58 -0
- package/src/core/persist.js +37 -9
- package/src/core/preserve-authored.js +114 -0
- package/src/core/recovery.js +772 -0
- package/src/core/runtime-url.js +105 -0
- package/src/core/save-core.js +109 -12
- package/src/core/save-replace.js +72 -0
- package/src/core/save-size-notice.js +134 -0
- package/src/core/save-size.js +140 -0
- package/src/core/save.js +805 -118
- package/src/core/snapshot.js +121 -11
- package/src/core/source-map.js +157 -9
- package/src/core/unsaved-warning.js +14 -4
- package/src/core/upgrade-run.js +408 -0
- package/src/core/version.js +18 -0
- package/src/lib/assets.js +30 -0
- package/src/lib/autosave-debug-gate.js +50 -0
- package/src/lib/autosave-scheduler.js +141 -0
- package/src/lib/boot-imports.js +8 -0
- package/src/lib/derived.js +3 -1
- package/src/lib/dirty-gate.js +15 -0
- package/src/lib/doc-storage.js +33 -0
- package/src/lib/effect.js +9 -4
- package/src/lib/mutation.js +4 -2
- package/src/lib/offline-runtime.js +226 -0
- package/src/lib/preload.js +48 -0
- package/src/lib/root-attrs.js +1 -1
- package/src/lib/trash.js +18 -0
- package/src/lib/undo/capture-move.js +152 -0
- package/src/live/local-channel.js +61 -0
- package/src/live/local-lane.js +60 -9
- package/src/live/server-lane.js +6 -3
- package/src/loader-logic.js +76 -15
- package/src/loader.js +218 -30
- package/src/page/adopt-boot.js +76 -22
- package/src/page/adopt.js +25 -4
- package/src/page/awareness.js +230 -0
- package/src/page/blocks.js +79 -5
- package/src/page/blocksel.js +20 -4
- package/src/page/board-face.js +13 -0
- package/src/page/board-panel.js +5 -17
- package/src/page/board-style.js +2 -13
- package/src/page/board-view.js +1 -11
- package/src/page/board-views.js +17 -0
- package/src/page/board.js +2 -2
- package/src/page/boot-pack.js +26 -0
- package/src/page/boot.js +237 -0
- package/src/page/checklist.js +1 -1
- package/src/page/chrome.js +411 -61
- package/src/page/csv-import.js +17 -2
- package/src/page/document-title-dom.js +40 -0
- package/src/page/document-title-runtime.js +76 -0
- package/src/page/document-title.js +9 -0
- package/src/page/drag.js +48 -13
- package/src/page/drop.js +2 -1
- package/src/page/editor.js +330 -86
- package/src/page/feature-loader.js +72 -0
- package/src/page/features/board.js +12 -0
- package/src/page/features/code.js +13 -0
- package/src/page/features/media.js +290 -0
- package/src/page/features/registry.js +23 -0
- package/src/page/features/table.js +383 -0
- package/src/page/{tool-view.js → features/tool.js} +33 -2
- package/src/page/format-codec.js +215 -0
- package/src/page/format-gate.js +179 -0
- package/src/page/format-level.js +157 -0
- package/src/page/highlight-slot.js +23 -0
- package/src/page/highlight.js +30 -16
- package/src/page/history-intent.js +78 -0
- package/src/page/inline.js +18 -25
- package/src/page/items.js +52 -11
- package/src/page/link.js +1 -0
- package/src/page/markdown.js +86 -1
- package/src/page/media-views.js +3 -0
- package/src/page/media.js +33 -245
- package/src/page/outline-cache.js +11 -0
- package/src/page/placeholder.js +27 -7
- package/src/page/projection.js +196 -50
- package/src/page/reader-patch.js +306 -0
- package/src/page/recover.js +1 -1
- package/src/page/rich/page-tool.js +1 -4
- package/src/page/runtime-owner.js +27 -0
- package/src/page/save-projection.js +7 -4
- package/src/page/schema.js +14 -0
- package/src/page/table-rect-key.js +3 -0
- package/src/page/table-select.js +4 -3
- package/src/page/table-style.js +1 -1
- package/src/page/table-views.js +3 -0
- package/src/page/table.js +8 -293
- package/src/page/themes/light-1.css +139 -2
- package/src/page/themes/light-1.source.css +269 -0
- package/src/page/tool-capability.js +3 -0
- package/src/page/tool-views.js +3 -0
- package/src/page/view.js +390 -107
- package/src/page/ybind/awareness.js +172 -0
- package/src/page/ybind/binding.js +9 -1
- package/src/page/ybind/bridge.js +50 -47
- package/src/page/ybind/decode.js +52 -19
- package/src/page/ybind/doc.js +27 -2
- package/src/page/ybind/group.js +12 -3
- package/src/page/ybind/index.js +2 -0
- package/src/page/ybind/lineage.js +71 -0
- package/src/page/ybind/marks.js +25 -1
- package/src/page/ybind/migrate.js +48 -13
- package/src/page/ybind/moves.js +32 -21
- package/src/page/ybind/positions.js +50 -0
- package/src/page/ybind/provider.js +84 -22
- package/src/page/ybind/recovery-proof.js +191 -0
- package/src/page/ybind/recovery-replay.js +130 -0
- package/src/page/ybind/tokens.js +15 -6
- package/src/page/ybind/walk.js +10 -3
- package/src/page/ybind/writer.js +48 -4
- package/src/plugins/ai-edit.js +167 -32
- package/src/plugins/bind-text.js +218 -0
- package/src/plugins/cms.js +93 -0
- package/src/plugins/indicator.js +57 -5
- package/src/plugins/live.js +282 -34
- package/src/plugins/menu/claygoo.svg.js +1 -0
- package/src/plugins/menu/seo-head.js +323 -0
- package/src/plugins/menu/seo.js +849 -0
- package/src/plugins/menu.js +425 -0
- package/src/plugins/page-view.js +131 -0
- package/src/plugins/page.js +1022 -275
- package/src/plugins/people.js +158 -31
- package/src/plugins/richclay.js +119 -9
- package/src/plugins/sortable.js +370 -60
- package/src/plugins/source.js +189 -366
- package/src/plugins/undo.js +289 -19
- package/src/plugins/unsent.js +132 -0
- package/src/plugins/upgrade-run.js +1 -0
- package/src/plugins/upgrade.js +210 -0
- package/src/plugins/upload-task.js +571 -0
- package/src/plugins/upload-ui.js +265 -0
- package/src/plugins/upload.js +34 -153
- package/src/plugins/visitor-drafts/inert.js +32 -0
- package/src/plugins/visitor-drafts/owner-chip.js +3 -0
- package/src/plugins/visitor-drafts/prompt.js +2 -2
- package/src/plugins/visitor-drafts-owner.js +85 -0
- package/src/plugins/visitor-drafts.js +31 -42
- package/src/plugins/wire.js +82 -1
- package/src/reader-core.js +26 -0
- package/src/recovery/conflicts.js +287 -0
- package/src/recovery/identity.js +154 -0
- package/src/recovery/store.js +792 -0
- package/src/recovery/undo.js +257 -0
- package/src/server/checkpoint/index.js +68 -4
- package/src/server/offline-runtime/index.js +214 -0
- package/src/server/rooms/index.js +2 -1
- package/src/server/rooms/live-data-rooms.js +2 -2
- package/src/server/rooms/page-admission.js +33 -0
- package/src/server/rooms/page-lineage.js +56 -0
- package/src/server/rooms/page-rebase.js +11 -5
- package/src/server/rooms/page-state.js +2 -0
- package/src/server/rooms/page-write-admission.js +9 -3
- package/src/source/session.js +705 -0
- package/src/sync/conflict-revert.js +5 -4
- package/src/sync/conflicts-edit.js +119 -0
- package/src/sync/conflicts-facade.js +49 -0
- package/src/sync/conflicts.js +99 -1
- package/src/sync/editing-marker.js +37 -6
- package/src/sync/editing-sender.js +8 -1
- package/src/sync/live-sync-edit.js +63 -0
- package/src/sync/live-sync.js +364 -119
- package/src/sync/local-presence.js +187 -0
- package/src/sync/merge-declarations.js +10 -0
- package/src/sync/merge-engine.js +12 -0
- package/src/sync/presence-store.js +412 -0
- package/src/sync/presence-target.js +243 -0
- package/src/sync/presence.js +72 -41
- package/src/sync/saved-handoff.js +200 -0
- package/src/sync/saved-stream.js +535 -0
- package/src/sync/version-guard.js +92 -0
- package/src/sync/wire-profile.js +81 -0
- package/src/ui/bevel-controls.js +2 -8
- package/src/ui/page-scheme.js +7 -0
- package/src/ui/skins/cms.js +1 -1
- package/src/ui/theme-config.js +150 -0
- package/src/ui/theme.js +6 -138
- package/src/ui/toast-lazy.js +11 -0
- package/src/vendor/LICENSES-optional.md +253 -0
- package/src/vendor/highlight.vendor.js +3 -0
- package/src/vendor/hljs-bash.vendor.js +2 -0
- package/src/vendor/hljs-css.vendor.js +2 -0
- package/src/vendor/hljs-javascript.vendor.js +2 -0
- package/src/vendor/hljs-json.vendor.js +2 -0
- package/src/vendor/hljs-python.vendor.js +2 -0
- package/src/vendor/hljs-xml.vendor.js +2 -0
- package/src/vendor/hyper-html-api-data.vendor.js +1 -1
- package/src/vendor/hyper-html-api-upgrade.vendor.js +5 -0
- package/src/vendor/hyper-morph-identity.vendor.js +2 -0
- package/src/vendor/hyper-morph-json.vendor.js +3 -0
- package/src/vendor/hyper-morph.vendor.js +6 -6
- package/src/vendor/hyper-undo.vendor.js +1 -1
- package/src/vendor/hypercms.vendor.js +169 -84
- package/src/vendor/marked.vendor.js +68 -0
- package/src/vendor/overtype.vendor.js +994 -0
- package/src/vendor/richclay.vendor.js +17 -17
- package/src/vendor/sap-core.vendor.js +5 -5
- package/src/vendor/sap-ownership.vendor.js +11 -7
package/src/live/local-lane.js
CHANGED
|
@@ -18,8 +18,9 @@
|
|
|
18
18
|
// where in the log it starts, the moves after that go back on top, and the
|
|
19
19
|
// merge itself is logged as a diff so a later file stamped before it keeps it.
|
|
20
20
|
|
|
21
|
+
import { localChannel } from "./local-channel.js";
|
|
21
22
|
import { applyOp, applyTracked, checkOp, cloneJson, undoTracked, validateOp, serializeLive, textHash, diffOps } from "./ops.js";
|
|
22
|
-
import {
|
|
23
|
+
import { parseJsonRelaxed } from "../vendor/hyper-morph-json.vendor.js";
|
|
23
24
|
import { movesSince } from "./moves.js";
|
|
24
25
|
|
|
25
26
|
const VERSION = 4;
|
|
@@ -52,6 +53,16 @@ function applyAll(value, ops) {
|
|
|
52
53
|
|
|
53
54
|
const encoder = new TextEncoder();
|
|
54
55
|
|
|
56
|
+
// Floor 1 moves the durable lane to its own channel scope: a tab that cannot read
|
|
57
|
+
// floor 1 never receives future-format updates, and its writes are refused by the
|
|
58
|
+
// host floor. The message protocol inside the scope is unchanged.
|
|
59
|
+
export const FORMAT_SCOPE = "page-format:1";
|
|
60
|
+
|
|
61
|
+
export function localLaneKey(floor = 0, path = window.location.pathname) {
|
|
62
|
+
const base = "clay-live:" + path;
|
|
63
|
+
return floor >= 1 ? `${base}:${FORMAT_SCOPE}` : base;
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
export function localLaneSupported() {
|
|
56
67
|
return typeof BroadcastChannel === "function" && typeof navigator !== "undefined" && typeof navigator.locks?.request === "function";
|
|
57
68
|
}
|
|
@@ -66,10 +77,16 @@ function randomId() {
|
|
|
66
77
|
* @param {() => Map<string, {value: any, ephemeral: boolean}>} options.seed -
|
|
67
78
|
* what this tab holds for each live tag, used for stores the room does not have yet
|
|
68
79
|
* @param {string} [options.key]
|
|
80
|
+
* @param {object} [options.channel] - the document's channel, when a presence
|
|
81
|
+
* service in this tab already owns one: the two share it rather than open a second
|
|
69
82
|
*/
|
|
70
|
-
|
|
83
|
+
// `key` is the room's channel without a floor suffix; `floor` scopes it.
|
|
84
|
+
export function localTransport({ seed, key = "clay-live:" + window.location.pathname, channel: shared = null, floor = 0 }) {
|
|
71
85
|
const clientId = randomId();
|
|
86
|
+
let scopeFloor = floor >= 1 ? 1 : 0;
|
|
87
|
+
let laneKey = scopeFloor ? `${key}:${FORMAT_SCOPE}` : key;
|
|
72
88
|
let channel = null;
|
|
89
|
+
let unsubscribe = null;
|
|
73
90
|
let handlers = null;
|
|
74
91
|
let room = null;
|
|
75
92
|
let stopped = false;
|
|
@@ -101,7 +118,7 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
101
118
|
let mirror = { epoch: null, seq: 0, sequencer: null, closedBy: null, stale: false, seen: new Map(), stores: new Map() };
|
|
102
119
|
|
|
103
120
|
function post(message) {
|
|
104
|
-
channel?.
|
|
121
|
+
channel?.post(message);
|
|
105
122
|
}
|
|
106
123
|
|
|
107
124
|
// Over either cap the oldest entries go, and a file older than them can no
|
|
@@ -164,7 +181,7 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
164
181
|
function alreadyMerged(m, frame) {
|
|
165
182
|
if (!m?.file) return false;
|
|
166
183
|
if (frame.seq != null && m.file.seq != null) return frame.seq <= m.file.seq;
|
|
167
|
-
return m.file.hash === textHash(serializeLive(
|
|
184
|
+
return m.file.hash === textHash(serializeLive(parseJsonRelaxed(frame.text)));
|
|
168
185
|
}
|
|
169
186
|
|
|
170
187
|
function dropMerged() {
|
|
@@ -319,7 +336,7 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
319
336
|
if (lockRequested || stopped) return;
|
|
320
337
|
lockRequested = true;
|
|
321
338
|
navigator.locks
|
|
322
|
-
.request(
|
|
339
|
+
.request(laneKey, async () => {
|
|
323
340
|
if (stopped) return undefined;
|
|
324
341
|
const ordered = await closedFor(mirror.sequencer);
|
|
325
342
|
if (stopped) return undefined;
|
|
@@ -393,7 +410,7 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
393
410
|
if (!m || m.ephemeral) return null;
|
|
394
411
|
let value;
|
|
395
412
|
try {
|
|
396
|
-
value = cloneJson(
|
|
413
|
+
value = cloneJson(parseJsonRelaxed(text));
|
|
397
414
|
} catch {
|
|
398
415
|
return null;
|
|
399
416
|
}
|
|
@@ -559,12 +576,45 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
559
576
|
handlers.open({ clientId, lane: "live" });
|
|
560
577
|
}
|
|
561
578
|
|
|
579
|
+
// The floor rose and an accepted receipt covers the pending work: close this
|
|
580
|
+
// scope's room (its closed state carries every store and the position the
|
|
581
|
+
// receipt covers), then join the new one. An interrupted switch leaves this tab
|
|
582
|
+
// where it was, on floor 0's scope, with every store and its pending work
|
|
583
|
+
// intact; the caller retries it from the receipt.
|
|
584
|
+
function switchScope(next, { covered = false } = {}) {
|
|
585
|
+
const want = next >= 1 ? 1 : 0;
|
|
586
|
+
const held = { floor: scopeFloor, scope: laneKey };
|
|
587
|
+
if (want <= scopeFloor) return { status: "already", ...held };
|
|
588
|
+
if (stopped || !channel) return { status: "refused", code: "lane-stopped", ...held };
|
|
589
|
+
if (shared) return { status: "refused", code: "shared-channel", ...held };
|
|
590
|
+
if (!covered) return { status: "refused", code: "uncovered", ...held };
|
|
591
|
+
closeRoom();
|
|
592
|
+
unsubscribe?.();
|
|
593
|
+
laneKey = want ? `${key}:${FORMAT_SCOPE}` : key;
|
|
594
|
+
scopeFloor = want;
|
|
595
|
+
channel = localChannel(laneKey);
|
|
596
|
+
unsubscribe = channel.subscribe("durable", (data) => onMessage({ data }));
|
|
597
|
+
mirror.sequencer = mirror.closedBy = null;
|
|
598
|
+
lockRequested = false;
|
|
599
|
+
requestLock();
|
|
600
|
+
handlers.close();
|
|
601
|
+
handlers.open({ clientId, lane: "live" });
|
|
602
|
+
return { status: "switched", floor: scopeFloor, scope: laneKey };
|
|
603
|
+
}
|
|
604
|
+
|
|
562
605
|
return {
|
|
563
606
|
clientId,
|
|
607
|
+
get scope() {
|
|
608
|
+
return laneKey;
|
|
609
|
+
},
|
|
610
|
+
get floor() {
|
|
611
|
+
return scopeFloor;
|
|
612
|
+
},
|
|
613
|
+
switchScope,
|
|
564
614
|
start(next) {
|
|
565
615
|
handlers = next;
|
|
566
|
-
channel =
|
|
567
|
-
channel.
|
|
616
|
+
channel = shared ?? localChannel(laneKey);
|
|
617
|
+
unsubscribe = channel.subscribe("durable", (data) => onMessage({ data }));
|
|
568
618
|
window.addEventListener("pagehide", onPageHide);
|
|
569
619
|
window.addEventListener("pageshow", onPageShow);
|
|
570
620
|
requestLock();
|
|
@@ -576,7 +626,8 @@ export function localTransport({ seed, key = "clay-live:" + window.location.path
|
|
|
576
626
|
window.removeEventListener("pagehide", onPageHide);
|
|
577
627
|
window.removeEventListener("pageshow", onPageShow);
|
|
578
628
|
for (const resolve of waiting.values()) resolve(null);
|
|
579
|
-
|
|
629
|
+
unsubscribe?.();
|
|
630
|
+
unsubscribe = null;
|
|
580
631
|
channel = null;
|
|
581
632
|
};
|
|
582
633
|
},
|
package/src/live/server-lane.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { onStream } from "./stream-bridge.js";
|
|
2
|
+
import { PAGE_FORMAT, PAGE_FORMAT_HEADER } from "../core/page-format.js";
|
|
2
3
|
|
|
3
4
|
// The host side of clay.live's fast lane on a host that advertises `live-data`:
|
|
4
5
|
// one POST per frame of ops, one GET for the room's whole state. Both name the
|
|
5
|
-
// document with Document-URL, as the sync relay and presence do
|
|
6
|
+
// document with Document-URL, as the sync relay and presence do, and both declare
|
|
7
|
+
// the page format this client writes: registration, operation and checkpoint are
|
|
8
|
+
// page-writing paths, so each one carries the capability the floor decides on.
|
|
6
9
|
|
|
7
10
|
const DATA_PATH = "/_/sync/data";
|
|
8
11
|
|
|
@@ -21,7 +24,7 @@ export async function relayData(clientId, frame) {
|
|
|
21
24
|
const response = await fetch(url.href, {
|
|
22
25
|
method: "POST",
|
|
23
26
|
credentials: "same-origin",
|
|
24
|
-
headers: { "Content-Type": "application/json", "Document-URL": window.location.href },
|
|
27
|
+
headers: { "Content-Type": "application/json", "Document-URL": window.location.href, [PAGE_FORMAT_HEADER]: String(PAGE_FORMAT) },
|
|
25
28
|
body: JSON.stringify(frame),
|
|
26
29
|
});
|
|
27
30
|
let body = null;
|
|
@@ -47,7 +50,7 @@ export async function fetchLiveState(clientId, since = null, { signal } = {}) {
|
|
|
47
50
|
const response = await fetch(url.href, {
|
|
48
51
|
credentials: "same-origin",
|
|
49
52
|
cache: "no-store",
|
|
50
|
-
headers: { "Document-URL": window.location.href },
|
|
53
|
+
headers: { "Document-URL": window.location.href, [PAGE_FORMAT_HEADER]: String(PAGE_FORMAT) },
|
|
51
54
|
signal,
|
|
52
55
|
});
|
|
53
56
|
if (!response.ok) {
|
package/src/loader-logic.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
export const CORE_WAVES = {
|
|
2
2
|
always: [
|
|
3
3
|
"lib/mutation.js", // first: everything hangs off the hub; cms/sync need it in view mode too
|
|
4
|
+
// Second: records what the served file wrote for the attributes edit mode rewrites,
|
|
5
|
+
// and the authored contents of [freeze] regions, while the page is still in view.
|
|
6
|
+
// Read-only, and the one thing a view to edit to view cycle has to hand back.
|
|
7
|
+
"core/preserve-authored.js",
|
|
4
8
|
"core/edit-mode.js", // both modes — matches today: 'edit-mode' is NOT in EDIT_MODE_ONLY
|
|
5
9
|
// (hyperclay.js:251-273 lists 'edit-mode-helpers', not 'edit-mode');
|
|
6
10
|
// toggleEditMode must exist in view mode, it's the way IN
|
|
11
|
+
"core/mode-key.js", // the way into edit for a document with no toggle of its own
|
|
7
12
|
// always, deliberately: it speaks only when the host is too old to save to, which
|
|
8
13
|
// is exactly the case where edit mode is off, so the editOnly wave would never
|
|
9
14
|
// reach it. It draws nothing on any other page.
|
|
@@ -11,13 +16,16 @@ export const CORE_WAVES = {
|
|
|
11
16
|
"core/page-data.js",
|
|
12
17
|
],
|
|
13
18
|
editOnly: [
|
|
14
|
-
"vendor/hyper-morph.vendor.js",
|
|
15
19
|
"core/snapshot.js",
|
|
16
20
|
// Before save.js: it takes the boot baseline as it evaluates, and a snapshot
|
|
17
21
|
// transform registered after that made an untouched page read as unsaved.
|
|
18
22
|
"core/persist.js", "core/admin-attrs.js",
|
|
19
23
|
"core/save-core.js", "core/save.js",
|
|
20
24
|
"core/conflict-notice.js",
|
|
25
|
+
// The recovery facade: a queue and a status, no storage of its own. It imports
|
|
26
|
+
// the IndexedDB store and the identity only when an adapter registers, which is
|
|
27
|
+
// why neither is in a plan's static graph.
|
|
28
|
+
"core/recovery.js",
|
|
21
29
|
"core/unsaved-warning.js", "core/autosave.js",
|
|
22
30
|
"attrs/save-freeze.js", "attrs/onaftersave.js", "attrs/refetch-on-save.js", "attrs/add-from.js",
|
|
23
31
|
"lib/cache-bust.js",
|
|
@@ -32,8 +40,12 @@ export const PLUGIN_PATHS = {
|
|
|
32
40
|
// tab still shows the game, and its writes stay in that tab.
|
|
33
41
|
live: { path: "plugins/live.js", editOnly: false, default: false },
|
|
34
42
|
page: { path: "plugins/page.js", editOnly: true, default: false },
|
|
43
|
+
// The reader half of `page`, added by resolveModules for a Document in view mode
|
|
44
|
+
// and never named in a URL: the reader's article follows each saved file.
|
|
45
|
+
"page-view": { path: "plugins/page-view.js", editOnly: false, default: false, internal: true },
|
|
35
46
|
sortable: { path: "plugins/sortable.js", editOnly: true, default: false },
|
|
36
47
|
undo: { path: "plugins/undo.js", editOnly: true, default: false },
|
|
48
|
+
unsent: { path: "plugins/unsent.js", editOnly: true, default: false },
|
|
37
49
|
cms: { path: "plugins/cms.js", editOnly: false, default: false },
|
|
38
50
|
quickcrop: { path: "plugins/quickcrop.js", editOnly: false, default: false },
|
|
39
51
|
// editOnly, because a file picker only ever appears in edit mode: the cms
|
|
@@ -42,6 +54,10 @@ export const PLUGIN_PATHS = {
|
|
|
42
54
|
upload: { path: "plugins/upload.js", editOnly: true, default: false },
|
|
43
55
|
// Who is editing and who wrote what. Not editOnly: a reader still sees names.
|
|
44
56
|
people: { path: "plugins/people.js", editOnly: false, default: false },
|
|
57
|
+
// An Edit switch and claygoo in the top right, for anyone who can edit. Not
|
|
58
|
+
// editOnly: an owner who opens a document in view needs the switch that gets
|
|
59
|
+
// them into edit, and the group draws nothing for a reader who cannot edit.
|
|
60
|
+
menu: { path: "plugins/menu.js", editOnly: false, default: false },
|
|
45
61
|
wire: { path: "plugins/wire.js", editOnly: false, default: false },
|
|
46
62
|
// A visitor's contact form to the document's owner. Not editOnly: visitors are
|
|
47
63
|
// who send messages.
|
|
@@ -59,10 +75,19 @@ export const PLUGIN_PATHS = {
|
|
|
59
75
|
// verify is sent as the ordinary full serialization, so the floor is the behaviour
|
|
60
76
|
// it replaces. `exclude=source` turns it off.
|
|
61
77
|
source: { path: "plugins/source.js", editOnly: true, default: true },
|
|
62
|
-
|
|
78
|
+
// Only draft mode loads the draft store and its UI. Everyone else, readers and the
|
|
79
|
+
// owner editing the original, gets the owner module: the chip when it applies and
|
|
80
|
+
// the inert `clay.visitorDrafts`, without the drafts UI's 24 KB.
|
|
81
|
+
"visitor-drafts": { path: "plugins/visitor-drafts.js", ownerPath: "plugins/visitor-drafts-owner.js", editOnly: false, default: false },
|
|
82
|
+
// An editor textarea outside the saved records, bound to one record's text
|
|
83
|
+
// element. Edit mode only: the page that asks for it is the page whose owner
|
|
84
|
+
// writes in it.
|
|
85
|
+
"bind-text": { path: "plugins/bind-text.js", editOnly: true, default: false },
|
|
63
86
|
// The sapjs core. Loaded for any page with a [sap] root at boot (resolveModules'
|
|
64
87
|
// hasSap), in view mode too: a reader's tab paints the same totals.
|
|
65
88
|
derive: { path: "plugins/derive.js", editOnly: false, default: false },
|
|
89
|
+
// The update check a starter template copy gets from its own hyper-source meta.
|
|
90
|
+
upgrade: { path: "plugins/upgrade.js", editOnly: false, default: false },
|
|
66
91
|
};
|
|
67
92
|
|
|
68
93
|
// One literal import per module the loader can ask for, so a bundler can see the
|
|
@@ -80,12 +105,15 @@ export const MODULES = {
|
|
|
80
105
|
"lib/region-policy.js": () => import("./lib/region-policy.js"),
|
|
81
106
|
"lib/mutation.js": () => import("./lib/mutation.js"),
|
|
82
107
|
"core/edit-mode.js": () => import("./core/edit-mode.js"),
|
|
108
|
+
"core/mode-key.js": () => import("./core/mode-key.js"),
|
|
83
109
|
"core/stale-host-notice.js": () => import("./core/stale-host-notice.js"),
|
|
84
110
|
"core/page-data.js": () => import("./core/page-data.js"),
|
|
111
|
+
"core/preserve-authored.js": () => import("./core/preserve-authored.js"),
|
|
85
112
|
"core/snapshot.js": () => import("./core/snapshot.js"),
|
|
86
113
|
"core/save-core.js": () => import("./core/save-core.js"),
|
|
87
114
|
"core/save.js": () => import("./core/save.js"),
|
|
88
115
|
"core/conflict-notice.js": () => import("./core/conflict-notice.js"),
|
|
116
|
+
"core/recovery.js": () => import("./core/recovery.js"),
|
|
89
117
|
"core/unsaved-warning.js": () => import("./core/unsaved-warning.js"),
|
|
90
118
|
"core/persist.js": () => import("./core/persist.js"),
|
|
91
119
|
"core/admin-attrs.js": () => import("./core/admin-attrs.js"),
|
|
@@ -95,30 +123,35 @@ export const MODULES = {
|
|
|
95
123
|
"attrs/refetch-on-save.js": () => import("./attrs/refetch-on-save.js"),
|
|
96
124
|
"attrs/add-from.js": () => import("./attrs/add-from.js"),
|
|
97
125
|
"lib/cache-bust.js": () => import("./lib/cache-bust.js"),
|
|
98
|
-
"vendor/hyper-morph.vendor.js": () => import("./vendor/hyper-morph.vendor.js"),
|
|
99
126
|
"plugins/richclay.js": () => import("./plugins/richclay.js"),
|
|
100
127
|
"plugins/indicator.js": () => import("./plugins/indicator.js"),
|
|
101
128
|
"sync/live-sync.js": () => import("./sync/live-sync.js"),
|
|
102
129
|
"plugins/live.js": () => import("./plugins/live.js"),
|
|
103
130
|
"plugins/page.js": () => import("./plugins/page.js"),
|
|
131
|
+
"plugins/page-view.js": () => import("./plugins/page-view.js"),
|
|
104
132
|
"plugins/sortable.js": () => import("./plugins/sortable.js"),
|
|
105
133
|
"plugins/undo.js": () => import("./plugins/undo.js"),
|
|
134
|
+
"plugins/unsent.js": () => import("./plugins/unsent.js"),
|
|
106
135
|
"plugins/cms.js": () => import("./plugins/cms.js"),
|
|
107
136
|
"plugins/quickcrop.js": () => import("./plugins/quickcrop.js"),
|
|
108
137
|
"plugins/upload.js": () => import("./plugins/upload.js"),
|
|
109
138
|
"plugins/people.js": () => import("./plugins/people.js"),
|
|
139
|
+
"plugins/menu.js": () => import("./plugins/menu.js"),
|
|
110
140
|
"plugins/wire.js": () => import("./plugins/wire.js"),
|
|
111
141
|
"plugins/message.js": () => import("./plugins/message.js"),
|
|
112
142
|
"plugins/ai-edit.js": () => import("./plugins/ai-edit.js"),
|
|
113
143
|
"plugins/demo.js": () => import("./plugins/demo.js"),
|
|
114
144
|
"plugins/visitor-drafts.js": () => import("./plugins/visitor-drafts.js"),
|
|
145
|
+
"plugins/visitor-drafts-owner.js": () => import("./plugins/visitor-drafts-owner.js"),
|
|
146
|
+
"plugins/bind-text.js": () => import("./plugins/bind-text.js"),
|
|
115
147
|
"plugins/source.js": () => import("./plugins/source.js"),
|
|
116
148
|
"plugins/derive.js": () => import("./plugins/derive.js"),
|
|
149
|
+
"plugins/upgrade.js": () => import("./plugins/upgrade.js"),
|
|
117
150
|
};
|
|
118
151
|
|
|
119
152
|
// `source` is last on purpose: its install captures a save clone, so it wants every
|
|
120
153
|
// plugin that registers a document transform to have registered it first.
|
|
121
|
-
const PLUGIN_ORDER = ["visitor-drafts", "richclay", "indicator", "sortable", "undo", "quickcrop", "upload", "people", "cms", "sync", "live", "page", "message", "wire", "ai-edit", "demo", "derive", "source"];
|
|
154
|
+
const PLUGIN_ORDER = ["visitor-drafts", "richclay", "indicator", "sortable", "undo", "unsent", "quickcrop", "upload", "people", "menu", "upgrade", "cms", "page-view", "sync", "live", "page", "message", "wire", "ai-edit", "demo", "derive", "bind-text", "source"];
|
|
122
155
|
|
|
123
156
|
// A plugin that cannot do its whole job alone. hypercms reads the cropper through
|
|
124
157
|
// a capability lookup (`clay.quickcrop`) and silently uploads the raw file when it
|
|
@@ -147,13 +180,21 @@ const PLUGIN_ORDER = ["visitor-drafts", "richclay", "indicator", "sortable", "un
|
|
|
147
180
|
// files answers `unsupported` and the editor offers to embed the file instead.
|
|
148
181
|
const IMPLIES = { cms: ["quickcrop", "upload"], "ai-edit": ["wire"], page: ["live", "sync", "upload"] };
|
|
149
182
|
|
|
183
|
+
// A Document's editor owns its article's rich text, so richclay (for [editable]) has
|
|
184
|
+
// nothing to do there; plugins=page,richclay still loads it.
|
|
185
|
+
const DISPLACES = { page: ["richclay"] };
|
|
186
|
+
// No first paint or keystroke waits for these. source keeps the file's bytes outside
|
|
187
|
+
// the edited parts stable; a save before it installs is the ordinary full serialization.
|
|
188
|
+
// upgrade only asks the host for a newer version once `clay.ready` resolves.
|
|
189
|
+
const LATE = new Set(["source", "sortable", "menu", "upgrade"]);
|
|
190
|
+
|
|
150
191
|
function parseCsv(params, key, enabled, apply) {
|
|
151
192
|
const raw = params.get(key);
|
|
152
193
|
if (!raw) return;
|
|
153
194
|
for (const token of raw.split(",")) {
|
|
154
195
|
const name = token.trim();
|
|
155
196
|
if (!name) continue;
|
|
156
|
-
if (!PLUGIN_PATHS[name]) {
|
|
197
|
+
if (!PLUGIN_PATHS[name] || PLUGIN_PATHS[name].internal) {
|
|
157
198
|
console.warn(`clayjs: unknown plugin "${name}"`);
|
|
158
199
|
continue;
|
|
159
200
|
}
|
|
@@ -163,13 +204,17 @@ function parseCsv(params, key, enabled, apply) {
|
|
|
163
204
|
|
|
164
205
|
// Each of these talks to the host or writes outside the visitor's own record, so a
|
|
165
206
|
// page that keeps its edits in this browser cannot carry them.
|
|
166
|
-
const DRAFT_DROPS = ["sync", "live", "page", "upload", "quickcrop", "cms", "people", "wire", "ai-edit", "demo", "source"];
|
|
207
|
+
const DRAFT_DROPS = ["sync", "live", "page", "upload", "quickcrop", "cms", "people", "menu", "upgrade", "wire", "ai-edit", "demo", "source"];
|
|
167
208
|
|
|
168
209
|
// [refetch-on-save] swaps its element for a fresh GET of the same URL after every
|
|
169
|
-
// save, which on a visitor's own draft is a request to the host.
|
|
170
|
-
|
|
210
|
+
// save, which on a visitor's own draft is a request to the host. The conflict notice
|
|
211
|
+
// answers a host's 412, which a save into this browser never returns.
|
|
212
|
+
const DRAFT_DROPS_CORE = ["attrs/refetch-on-save.js", "core/conflict-notice.js"];
|
|
213
|
+
|
|
214
|
+
// Only that host's copies auto-add the update check; another source names it.
|
|
215
|
+
const TEMPLATE_SOURCE_PREFIX = "https://hyperclay.com/templates/";
|
|
171
216
|
|
|
172
|
-
export function resolveModules(params, isEditMode, { isDraftMode = false, hasSap = false } = {}) {
|
|
217
|
+
export function resolveModules(params, isEditMode, { isDraftMode = false, hasSap = false, canEdit = false, templateSource = null } = {}) {
|
|
173
218
|
const core = [...CORE_WAVES.always];
|
|
174
219
|
if (isEditMode) core.push(...CORE_WAVES.editOnly);
|
|
175
220
|
|
|
@@ -185,11 +230,16 @@ export function resolveModules(params, isEditMode, { isDraftMode = false, hasSap
|
|
|
185
230
|
if (hasSap) enabled.add("derive");
|
|
186
231
|
// ai-edit cannot run without the wire, so excluding the wire excludes it too.
|
|
187
232
|
if (excluded.has("wire")) enabled.delete("ai-edit");
|
|
188
|
-
|
|
189
|
-
//
|
|
233
|
+
if (!isEditMode && !isDraftMode && enabled.has("page")) enabled.add("page-view");
|
|
234
|
+
// A plugin this mode does not load brings nothing with it, whether a default put
|
|
235
|
+
// it in the set or the tag named it. A page that wants what an edit-only plugin
|
|
236
|
+
// implies in view mode names that plugin too. `page` is the case that matters
|
|
237
|
+
// most: a reader loads its reader half and no generic sync, live data service or
|
|
238
|
+
// upload, so `plugins=page` in view mode resolves to page-view alone and the
|
|
239
|
+
// saved transport page-view owns is the only stream.
|
|
190
240
|
for (const name of [...enabled]) {
|
|
191
241
|
if (excluded.has(name)) continue;
|
|
192
|
-
if (
|
|
242
|
+
if (PLUGIN_PATHS[name].editOnly && !isEditMode) continue;
|
|
193
243
|
for (const implied of IMPLIES[name] || []) enabled.add(implied);
|
|
194
244
|
}
|
|
195
245
|
for (const name of excluded) enabled.delete(name);
|
|
@@ -202,13 +252,24 @@ export function resolveModules(params, isEditMode, { isDraftMode = false, hasSap
|
|
|
202
252
|
enabled.add("visitor-drafts");
|
|
203
253
|
}
|
|
204
254
|
|
|
255
|
+
// A copy of a starter template upgrades with no authored tag, so copies shipped
|
|
256
|
+
// between the metas and this plugin upgrade too.
|
|
257
|
+
if (!isDraftMode && canEdit && !excluded.has("upgrade") && templateSource &&
|
|
258
|
+
templateSource.startsWith(TEMPLATE_SOURCE_PREFIX)) {
|
|
259
|
+
enabled.add("upgrade");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
for (const [owner, names] of Object.entries(DISPLACES)) {
|
|
263
|
+
if (enabled.has(owner)) for (const name of names) if (!explicit.has(name)) enabled.delete(name);
|
|
264
|
+
}
|
|
265
|
+
|
|
205
266
|
const plugins = [];
|
|
267
|
+
const late = [];
|
|
206
268
|
for (const name of PLUGIN_ORDER) {
|
|
207
269
|
if (!enabled.has(name)) continue;
|
|
208
270
|
const spec = PLUGIN_PATHS[name];
|
|
209
271
|
if (spec.editOnly && !isEditMode) continue;
|
|
210
|
-
plugins.push(spec.path);
|
|
272
|
+
(LATE.has(name) ? late : plugins).push(spec.ownerPath && !isDraftMode ? spec.ownerPath : spec.path);
|
|
211
273
|
}
|
|
212
|
-
|
|
213
|
-
return { core, plugins };
|
|
274
|
+
return { core, plugins, late };
|
|
214
275
|
}
|