@heycys/gallery 0.1.1 → 0.2.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/THIRD-PARTY-NOTICES.md +2 -2
- package/browser/editor/components/align.mjs +58 -0
- package/browser/editor/components/code/index.mjs +1 -1
- package/browser/editor/components/columns/page.mjs +4 -4
- package/browser/editor/components/embed/index.mjs +2 -2
- package/browser/editor/components/embed/page.mjs +1 -1
- package/browser/editor/components/file/page.mjs +4 -4
- package/browser/editor/components/flowchart/add.mjs +7 -6
- package/browser/editor/components/flowchart/page.mjs +1 -1
- package/browser/editor/components/heading/index.mjs +7 -6
- package/browser/editor/components/icons.mjs +11 -0
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/image/index.mjs +2 -0
- package/browser/editor/components/image/page.mjs +172 -90
- package/browser/editor/components/installed/index.mjs +15 -4
- package/browser/editor/components/installed/page.mjs +103 -25
- package/browser/editor/components/installed/served.mjs +6 -5
- package/browser/editor/components/instances.mjs +18 -0
- package/browser/editor/components/list/page.mjs +3 -6
- package/browser/editor/components/media/icons.mjs +13 -8
- package/browser/editor/components/media/page.mjs +5 -3
- package/browser/editor/components/media/toolbar.mjs +12 -3
- package/browser/editor/components/paragraph/index.mjs +4 -3
- package/browser/editor/components/registry.mjs +30 -9
- package/browser/editor/components/table/index.mjs +61 -2
- package/browser/editor/components/table/page.mjs +1 -1
- package/browser/editor/page/after/index.mjs +288 -0
- package/browser/editor/page/align.mjs +91 -0
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/autosave.mjs +310 -37
- package/browser/editor/page/beside.mjs +5 -6
- package/browser/editor/page/block-menu/index.mjs +6 -3
- package/browser/editor/page/blocks.mjs +3 -1
- package/browser/editor/page/board/client.mjs +57 -0
- package/browser/editor/page/board/hint.mjs +182 -0
- package/browser/editor/page/board/history.mjs +119 -0
- package/browser/editor/page/board/index.mjs +1059 -0
- package/browser/editor/page/board/motion.mjs +177 -0
- package/browser/editor/page/board/settings.mjs +210 -0
- package/browser/editor/page/caret.mjs +1 -1
- package/browser/editor/page/changes/bar.mjs +6 -14
- package/browser/editor/page/changes/index.mjs +2 -2
- package/browser/editor/page/clipboard/import/html.mjs +29 -6
- package/browser/editor/page/clipboard/import/inline.mjs +32 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
- package/browser/editor/page/clipboard/import/read.mjs +6 -1
- package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
- package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
- package/browser/editor/page/clipboard/index.mjs +133 -15
- package/browser/editor/page/clipboard/own/blocks.mjs +13 -14
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- package/browser/editor/page/clipboard/own/describe.mjs +6 -2
- package/browser/editor/page/clipboard/own/selection.mjs +1 -1
- package/browser/editor/page/columns/index.mjs +48 -46
- package/browser/editor/page/commit.mjs +80 -22
- package/browser/editor/page/conflicts.mjs +7 -7
- package/browser/editor/page/core.mjs +34 -16
- package/browser/editor/page/custom-page.mjs +110 -0
- package/browser/editor/page/editor.mjs +71 -17
- package/browser/editor/page/emoji-picker/styles.mjs +7 -12
- package/browser/editor/page/emoji-picker/upload.mjs +2 -2
- package/browser/editor/page/handle/index.mjs +5 -8
- package/browser/editor/page/history.mjs +41 -6
- package/browser/editor/page/insert/index.mjs +20 -22
- package/browser/editor/page/links/index.mjs +5 -3
- package/browser/editor/page/links/pages.mjs +27 -9
- package/browser/editor/page/look.mjs +54 -3
- package/browser/editor/page/margin.mjs +18 -3
- package/browser/editor/page/media-menu/index.mjs +6 -7
- package/browser/editor/page/menu.mjs +33 -14
- package/browser/editor/page/notices.mjs +2 -2
- package/browser/editor/page/page-objects.mjs +9 -2
- package/browser/editor/page/panel.mjs +4 -9
- package/browser/editor/page/present-links.mjs +15 -5
- package/browser/editor/page/present-shell.mjs +63 -0
- package/browser/editor/page/resize/index.mjs +42 -29
- package/browser/editor/page/selection/index.mjs +10 -2
- package/browser/editor/page/served.mjs +14 -0
- package/browser/editor/page/session.mjs +48 -4
- package/browser/editor/page/slash-menu/index.mjs +3 -3
- package/browser/editor/page/table/binding.mjs +87 -0
- package/browser/editor/page/table/cells.mjs +102 -46
- package/browser/editor/page/table/index.mjs +24 -9
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +103 -0
- package/browser/editor/page/table/widths.mjs +82 -10
- package/browser/editor/page/text-select/index.mjs +26 -12
- package/browser/editor/page/todo-writes.mjs +75 -0
- package/browser/editor/page/typing/index.mjs +97 -15
- package/browser/editor/page/typing/leave.mjs +19 -5
- package/browser/editor/page/ui.mjs +13 -0
- package/browser/shared/block-packs.mjs +419 -0
- package/browser/shared/board-places.mjs +224 -0
- package/browser/shared/card-size.mjs +59 -0
- package/browser/shared/colors.mjs +3 -2
- package/browser/shared/component-catalog.mjs +330 -46
- package/browser/shared/component-source.mjs +39 -0
- package/browser/shared/components/heading.mjs +2 -1
- package/browser/shared/components/index.mjs +12 -3
- package/browser/shared/components/installed.mjs +35 -3
- package/browser/shared/components/page.mjs +20 -8
- package/browser/shared/components/paragraph.mjs +8 -1
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/components/table.mjs +1 -0
- package/browser/shared/document-look.mjs +10 -5
- package/browser/shared/drafts.mjs +432 -0
- package/browser/shared/emoji/line-icons.mjs +37 -0
- package/browser/shared/extension-sidebar.mjs +126 -0
- package/browser/shared/extensions.mjs +79 -0
- package/browser/shared/file-table.mjs +101 -0
- package/browser/shared/http.mjs +9 -0
- package/browser/shared/i18n/en.mjs +330 -27
- package/browser/shared/json-layout.mjs +47 -0
- package/browser/shared/net-cache.mjs +133 -0
- package/browser/shared/net-keys.mjs +32 -0
- package/browser/shared/net-policy.mjs +177 -0
- package/browser/shared/outline-shape.mjs +128 -0
- package/browser/shared/outline.mjs +359 -67
- package/browser/shared/pack-manifest.mjs +88 -0
- package/browser/shared/page-address.mjs +6 -3
- package/browser/shared/page-cards.mjs +308 -0
- package/browser/shared/page-links.mjs +69 -6
- package/browser/shared/pages.mjs +500 -0
- package/browser/shared/paths.mjs +6 -0
- package/browser/shared/pinyin.mjs +92 -0
- package/browser/shared/present-step.mjs +17 -0
- package/browser/shared/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +8 -1
- package/browser/shared/shipped-blocks.mjs +299 -0
- package/browser/shared/sidebar-head.mjs +70 -0
- package/browser/shared/table-chart.mjs +33 -1
- package/browser/shared/todos.mjs +83 -0
- package/browser/shared/user-directory.mjs +24 -0
- package/browser/shared/versions.mjs +14 -0
- package/browser/shared/web-links.mjs +139 -0
- package/browser/shared/workspace-columns.mjs +120 -0
- package/browser/shared/workspace-name.mjs +154 -0
- package/browser/shared/workspace-query.mjs +125 -0
- package/browser/shared/workspace-registry.mjs +272 -0
- package/browser/shared/workspace.mjs +171 -20
- package/dist/chunk-2OHANJ6Q.mjs +2 -0
- package/dist/chunk-3MBRL2PM.mjs +16 -0
- package/dist/chunk-4OKWZY5E.mjs +2 -0
- package/dist/chunk-4OZWXZE5.mjs +5 -0
- package/dist/chunk-5K44HLTZ.mjs +2 -0
- package/dist/{chunk-5ZKJ3H4P.mjs → chunk-5XA2ZBAE.mjs} +3 -3
- package/dist/{chunk-4FS7Z7WR.mjs → chunk-67N2QJYT.mjs} +1 -1
- package/dist/chunk-6KBYRA2C.mjs +2 -0
- package/dist/chunk-6N3PX4XX.mjs +8 -0
- package/dist/{chunk-V5JTW2LH.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/chunk-7JDX4E65.mjs +13 -0
- package/dist/chunk-7M2BQQGZ.mjs +2 -0
- package/dist/chunk-7OG26PGF.mjs +2 -0
- package/dist/chunk-AHN3NFKJ.mjs +3 -0
- package/dist/chunk-ALZ6ZENZ.mjs +3 -0
- package/dist/chunk-AR5D57ZD.mjs +170 -0
- package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
- package/dist/{chunk-LS4F7JUM.mjs → chunk-BZ5RAF7L.mjs} +1 -1
- package/dist/chunk-CMA72MAG.mjs +2 -0
- package/dist/{chunk-LCTHTZIL.mjs → chunk-DAZL73VK.mjs} +91 -91
- package/dist/{chunk-Y6RLRPG3.mjs → chunk-DJISHPUL.mjs} +1 -1
- package/dist/chunk-DR73Y2UJ.mjs +3 -0
- package/dist/{chunk-FDLXYYG4.mjs → chunk-EAIFITAV.mjs} +1 -1
- package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
- package/dist/chunk-EP25HDAJ.mjs +2 -0
- package/dist/{chunk-GB5SOYQJ.mjs → chunk-ERLAIBOA.mjs} +2 -2
- package/dist/chunk-EURLTOTZ.mjs +4 -0
- package/dist/chunk-F4ZA6JRZ.mjs +3 -0
- package/dist/chunk-F6HVDZR4.mjs +2 -0
- package/dist/chunk-FDMAXMQA.mjs +2 -0
- package/dist/chunk-FETSREUN.mjs +5 -0
- package/dist/chunk-GHOYKMQ3.mjs +4 -0
- package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
- package/dist/chunk-HDWTZ763.mjs +12 -0
- package/dist/chunk-HPOI4ZX7.mjs +6 -0
- package/dist/{chunk-BGGDRNYQ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
- package/dist/chunk-IA4PSIMD.mjs +2 -0
- package/dist/{chunk-E7LWZRXY.mjs → chunk-ITOH5EGO.mjs} +1 -1
- package/dist/chunk-IV64FFI4.mjs +2 -0
- package/dist/chunk-J43Z6LSS.mjs +2 -0
- package/dist/chunk-J5PUIV3Y.mjs +4 -0
- package/dist/chunk-JA7G53PC.mjs +2 -0
- package/dist/chunk-JEUK3ZO7.mjs +2 -0
- package/dist/chunk-JLTZF4LA.mjs +2 -0
- package/dist/chunk-JZT7I2OJ.mjs +2 -0
- package/dist/chunk-K5XATEOO.mjs +2 -0
- package/dist/chunk-L2SUIS5S.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/chunk-LM4XFQHZ.mjs +2 -0
- package/dist/chunk-MN7BZL4R.mjs +2 -0
- package/dist/chunk-MTYYHM2G.mjs +15 -0
- package/dist/chunk-MXUBKDRO.mjs +15 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-SYGN7GLU.mjs → chunk-OEXWRJME.mjs} +1 -1
- package/dist/chunk-OFHXGWOX.mjs +2 -0
- package/dist/chunk-ORID3AE7.mjs +166 -0
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-PGDE24N5.mjs +2 -0
- package/dist/chunk-POTA2FV4.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/chunk-Q4UEPUWF.mjs +2 -0
- package/dist/chunk-QE5RG76S.mjs +549 -0
- package/dist/chunk-R2ZDLJYT.mjs +10 -0
- package/dist/{chunk-7DTINW6U.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
- package/dist/chunk-SWUTTZCN.mjs +2 -0
- package/dist/chunk-TANZRINB.mjs +2 -0
- package/dist/chunk-TR7TWGHB.mjs +2 -0
- package/dist/chunk-U5XL7D6A.mjs +3 -0
- package/dist/{chunk-XNROSH2T.mjs → chunk-U7NZI6N4.mjs} +2 -2
- package/dist/chunk-UGWMMEJ5.mjs +15 -0
- package/dist/chunk-UJQJKNGK.mjs +2 -0
- package/dist/chunk-UYVCQK3H.mjs +22 -0
- package/dist/chunk-VFX2KNHP.mjs +4 -0
- package/dist/chunk-VS7JIGJW.mjs +24 -0
- package/dist/chunk-W7665ZEC.mjs +6 -0
- package/dist/chunk-WQDQWCX5.mjs +2 -0
- package/dist/chunk-YI43RG4P.mjs +2 -0
- package/dist/chunk-YLPSMDIS.mjs +5 -0
- package/dist/chunk-YNAWBAYN.mjs +3 -0
- package/dist/chunk-YROX2O22.mjs +2 -0
- package/dist/chunk-ZDLPUOAG.mjs +6 -0
- package/dist/{chunk-IVDLMMBD.mjs → chunk-ZHEHPMBK.mjs} +1 -1
- package/dist/chunk-ZQS6H473.mjs +16 -0
- package/dist/chunk-ZTHICSSF.mjs +2 -0
- package/dist/chunk-ZWWC4KLF.mjs +20 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{chunk-U6KNPJPR.mjs → update-fetch.mjs} +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/board.css +95 -0
- package/kit/board.js +250 -0
- package/kit/charts.js +5 -71
- package/kit/code.js +17 -17
- package/kit/report.css +335 -18
- package/kit/runtime.js +1638 -125
- package/kit/state.js +10 -1
- package/kit/tables.js +130 -43
- package/kit/ui.js +79 -35
- package/package.json +2 -1
- package/packs/gallery/card/component.json +14 -0
- package/packs/gallery/card/example.html +10 -0
- package/packs/gallery/card/preview.svg +1 -0
- package/packs/gallery/card/style.css +6 -0
- package/packs/gallery/card/template.html +6 -0
- package/packs/gallery/card/writing.md +14 -0
- package/packs/gallery/chart-card/component.json +15 -0
- package/packs/gallery/chart-card/example.html +14 -0
- package/packs/gallery/chart-card/kit.js +130 -0
- package/packs/gallery/chart-card/preview.svg +1 -0
- package/packs/gallery/chart-card/style.css +42 -0
- package/packs/gallery/chart-card/template.html +13 -0
- package/packs/gallery/chart-card/writing.md +20 -0
- package/packs/gallery/chart-view/component.json +20 -0
- package/packs/gallery/chart-view/example.html +13 -0
- package/packs/gallery/chart-view/kit.js +355 -0
- package/packs/gallery/chart-view/preview.svg +1 -0
- package/packs/gallery/chart-view/style.css +94 -0
- package/packs/gallery/chart-view/template.html +3 -0
- package/packs/gallery/chart-view/writing.md +22 -0
- package/packs/gallery/countdown/component.json +18 -0
- package/packs/gallery/countdown/example.html +3 -0
- package/packs/gallery/countdown/kit.js +216 -0
- package/packs/gallery/countdown/preview.svg +1 -0
- package/packs/gallery/countdown/style.css +118 -0
- package/packs/gallery/countdown/template.html +3 -0
- package/packs/gallery/countdown/writing.md +22 -0
- package/packs/gallery/habit/component.json +14 -0
- package/packs/gallery/habit/example.html +3 -0
- package/packs/gallery/habit/kit.js +334 -0
- package/packs/gallery/habit/preview.svg +1 -0
- package/packs/gallery/habit/style.css +174 -0
- package/packs/gallery/habit/template.html +3 -0
- package/packs/gallery/habit/writing.md +21 -0
- package/packs/gallery/heatmap/component.json +18 -0
- package/packs/gallery/heatmap/example.html +3 -0
- package/packs/gallery/heatmap/kit.js +513 -0
- package/packs/gallery/heatmap/preview.svg +1 -0
- package/packs/gallery/heatmap/style.css +189 -0
- package/packs/gallery/heatmap/template.html +3 -0
- package/packs/gallery/heatmap/writing.md +21 -0
- package/packs/gallery/kanban/component.json +18 -0
- package/packs/gallery/kanban/example.html +12 -0
- package/packs/gallery/kanban/kit.js +540 -0
- package/packs/gallery/kanban/preview.svg +1 -0
- package/packs/gallery/kanban/style.css +212 -0
- package/packs/gallery/kanban/template.html +3 -0
- package/packs/gallery/kanban/writing.md +20 -0
- package/packs/gallery/metric/component.json +22 -0
- package/packs/gallery/metric/example.html +15 -0
- package/packs/gallery/metric/kit.js +248 -0
- package/packs/gallery/metric/preview.svg +1 -0
- package/packs/gallery/metric/style.css +92 -0
- package/packs/gallery/metric/template.html +3 -0
- package/packs/gallery/metric/writing.md +23 -0
- package/packs/gallery/note/component.json +14 -0
- package/packs/gallery/note/example.html +3 -0
- package/packs/gallery/note/kit.js +129 -0
- package/packs/gallery/note/preview.svg +1 -0
- package/packs/gallery/note/style.css +97 -0
- package/packs/gallery/note/template.html +3 -0
- package/packs/gallery/note/writing.md +18 -0
- package/packs/gallery/pack.json +8 -0
- package/packs/gallery/recent/component.json +13 -0
- package/packs/gallery/recent/example.html +1 -0
- package/packs/gallery/recent/kit.js +293 -0
- package/packs/gallery/recent/preview.svg +1 -0
- package/packs/gallery/recent/style.css +85 -0
- package/packs/gallery/recent/template.html +1 -0
- package/packs/gallery/recent/writing.md +15 -0
- package/packs/gallery/static/component.json +13 -0
- package/packs/gallery/static/example.html +11 -0
- package/packs/gallery/static/preview.svg +1 -0
- package/packs/gallery/static/style.css +171 -0
- package/packs/gallery/static/template.html +1 -0
- package/packs/gallery/static/writing.md +18 -0
- package/packs/gallery/stats/component.json +13 -0
- package/packs/gallery/stats/example.html +1 -0
- package/packs/gallery/stats/kit.js +347 -0
- package/packs/gallery/stats/preview.svg +1 -0
- package/packs/gallery/stats/style.css +73 -0
- package/packs/gallery/stats/template.html +1 -0
- package/packs/gallery/stats/writing.md +11 -0
- package/packs/gallery/today/component.json +12 -0
- package/packs/gallery/today/example.html +1 -0
- package/packs/gallery/today/kit.js +220 -0
- package/packs/gallery/today/preview.svg +1 -0
- package/packs/gallery/today/style.css +149 -0
- package/packs/gallery/today/template.html +1 -0
- package/packs/gallery/today/writing.md +14 -0
- package/packs/gallery/todos/component.json +19 -0
- package/packs/gallery/todos/example.html +3 -0
- package/packs/gallery/todos/kit.js +489 -0
- package/packs/gallery/todos/preview.svg +1 -0
- package/packs/gallery/todos/style.css +214 -0
- package/packs/gallery/todos/template.html +3 -0
- package/packs/gallery/todos/writing.md +30 -0
- package/packs/gallery/weather/component.json +19 -0
- package/packs/gallery/weather/example.html +3 -0
- package/packs/gallery/weather/kit.js +387 -0
- package/packs/gallery/weather/preview.svg +1 -0
- package/packs/gallery/weather/style.css +140 -0
- package/packs/gallery/weather/template.html +3 -0
- package/packs/gallery/weather/writing.md +26 -0
- package/packs/gallery-soft/countdown/component.json +18 -0
- package/packs/gallery-soft/countdown/example.html +3 -0
- package/packs/gallery-soft/countdown/kit.js +206 -0
- package/packs/gallery-soft/countdown/preview.svg +1 -0
- package/packs/gallery-soft/countdown/style.css +211 -0
- package/packs/gallery-soft/countdown/template.html +3 -0
- package/packs/gallery-soft/countdown/writing.md +24 -0
- package/packs/gallery-soft/habit/component.json +14 -0
- package/packs/gallery-soft/habit/example.html +3 -0
- package/packs/gallery-soft/habit/kit.js +366 -0
- package/packs/gallery-soft/habit/preview.svg +1 -0
- package/packs/gallery-soft/habit/style.css +251 -0
- package/packs/gallery-soft/habit/template.html +3 -0
- package/packs/gallery-soft/habit/writing.md +23 -0
- package/packs/gallery-soft/heatmap/component.json +18 -0
- package/packs/gallery-soft/heatmap/example.html +3 -0
- package/packs/gallery-soft/heatmap/kit.js +498 -0
- package/packs/gallery-soft/heatmap/preview.svg +1 -0
- package/packs/gallery-soft/heatmap/style.css +181 -0
- package/packs/gallery-soft/heatmap/template.html +3 -0
- package/packs/gallery-soft/heatmap/writing.md +23 -0
- package/packs/gallery-soft/note/component.json +14 -0
- package/packs/gallery-soft/note/example.html +3 -0
- package/packs/gallery-soft/note/kit.js +162 -0
- package/packs/gallery-soft/note/preview.svg +1 -0
- package/packs/gallery-soft/note/style.css +148 -0
- package/packs/gallery-soft/note/template.html +3 -0
- package/packs/gallery-soft/note/writing.md +20 -0
- package/packs/gallery-soft/pack.json +8 -0
- package/packs/gallery-soft/recent/component.json +13 -0
- package/packs/gallery-soft/recent/example.html +1 -0
- package/packs/gallery-soft/recent/kit.js +335 -0
- package/packs/gallery-soft/recent/preview.svg +1 -0
- package/packs/gallery-soft/recent/style.css +160 -0
- package/packs/gallery-soft/recent/template.html +1 -0
- package/packs/gallery-soft/recent/writing.md +17 -0
- package/packs/gallery-soft/static/component.json +13 -0
- package/packs/gallery-soft/static/example.html +12 -0
- package/packs/gallery-soft/static/preview.svg +1 -0
- package/packs/gallery-soft/static/style.css +186 -0
- package/packs/gallery-soft/static/template.html +1 -0
- package/packs/gallery-soft/static/writing.md +20 -0
- package/packs/gallery-soft/stats/component.json +13 -0
- package/packs/gallery-soft/stats/example.html +1 -0
- package/packs/gallery-soft/stats/kit.js +341 -0
- package/packs/gallery-soft/stats/preview.svg +1 -0
- package/packs/gallery-soft/stats/style.css +119 -0
- package/packs/gallery-soft/stats/template.html +1 -0
- package/packs/gallery-soft/stats/writing.md +13 -0
- package/packs/gallery-soft/today/component.json +12 -0
- package/packs/gallery-soft/today/example.html +1 -0
- package/packs/gallery-soft/today/kit.js +222 -0
- package/packs/gallery-soft/today/preview.svg +1 -0
- package/packs/gallery-soft/today/style.css +178 -0
- package/packs/gallery-soft/today/template.html +1 -0
- package/packs/gallery-soft/today/writing.md +16 -0
- package/packs/gallery-soft/todos/component.json +19 -0
- package/packs/gallery-soft/todos/example.html +3 -0
- package/packs/gallery-soft/todos/kit.js +527 -0
- package/packs/gallery-soft/todos/preview.svg +1 -0
- package/packs/gallery-soft/todos/style.css +212 -0
- package/packs/gallery-soft/todos/template.html +3 -0
- package/packs/gallery-soft/todos/writing.md +32 -0
- package/packs/gallery-soft/weather/component.json +19 -0
- package/packs/gallery-soft/weather/example.html +3 -0
- package/packs/gallery-soft/weather/kit.js +411 -0
- package/packs/gallery-soft/weather/preview.svg +1 -0
- package/packs/gallery-soft/weather/style.css +185 -0
- package/packs/gallery-soft/weather/template.html +3 -0
- package/packs/gallery-soft/weather/writing.md +28 -0
- package/release.json +12 -10
- package/sdk/doc-kit.d.ts +396 -5
- package/sdk/doc-state.d.ts +2 -0
- package/skill/SKILL.md +56 -23
- package/skill/references/block-script.md +140 -0
- package/skill/references/building-blocks.md +257 -0
- package/skill/references/extensions.md +59 -0
- package/skill/references/pages-and-data.md +225 -0
- package/skill/references/writing-html.md +8 -4
- package/skill/sdk/doc-kit.d.ts +396 -5
- package/skill/sdk/doc-state.d.ts +2 -0
- package/web/assets/index-BM_K-Auu.css +1 -0
- package/web/assets/index-DRslOBiv.js +15 -0
- package/web/index.html +2 -2
- package/dist/chunk-3HIRPVLU.mjs +0 -2
- package/dist/chunk-5MHMDLZD.mjs +0 -4
- package/dist/chunk-64K7IPLO.mjs +0 -255
- package/dist/chunk-6QXGZM36.mjs +0 -8
- package/dist/chunk-6RGJOMJP.mjs +0 -16
- package/dist/chunk-AJ73XJF3.mjs +0 -2
- package/dist/chunk-AUZGSZJH.mjs +0 -13
- package/dist/chunk-BFE45AKL.mjs +0 -2
- package/dist/chunk-BXO2ZY5P.mjs +0 -2
- package/dist/chunk-CEH4MRCC.mjs +0 -2
- package/dist/chunk-CY2FNNAB.mjs +0 -16
- package/dist/chunk-DFUDV4LX.mjs +0 -2
- package/dist/chunk-DKXG4XDG.mjs +0 -2
- package/dist/chunk-EZQ34M3F.mjs +0 -124
- package/dist/chunk-EZY3WC6Z.mjs +0 -15
- package/dist/chunk-FUKQNOQS.mjs +0 -9
- package/dist/chunk-JPOSLGOC.mjs +0 -6
- package/dist/chunk-JVHHHGEA.mjs +0 -3
- package/dist/chunk-L3QKH4OK.mjs +0 -26
- package/dist/chunk-LAE5NQ4B.mjs +0 -2
- package/dist/chunk-LEF6DRCK.mjs +0 -59
- package/dist/chunk-NO5NJCHO.mjs +0 -2
- package/dist/chunk-NQPVAU63.mjs +0 -2
- package/dist/chunk-NSKUTQ5J.mjs +0 -5
- package/dist/chunk-O35FIXRB.mjs +0 -2
- package/dist/chunk-P2CAZPDP.mjs +0 -3
- package/dist/chunk-PL6GHLGD.mjs +0 -15
- package/dist/chunk-QJIR2BLP.mjs +0 -6
- package/dist/chunk-QUPLVPB2.mjs +0 -7
- package/dist/chunk-R7BNENLY.mjs +0 -4
- package/dist/chunk-S6O4UHLC.mjs +0 -2
- package/dist/chunk-SGJWQKEI.mjs +0 -2
- package/dist/chunk-TX6JH7TR.mjs +0 -2
- package/dist/chunk-TYK6VNAB.mjs +0 -10
- package/dist/chunk-UALRNVSE.mjs +0 -4
- package/dist/chunk-V3HXVQEM.mjs +0 -2
- package/dist/chunk-V5VXUJKG.mjs +0 -2
- package/dist/chunk-VBXMADMP.mjs +0 -2
- package/dist/chunk-VNV55RUA.mjs +0 -2
- package/dist/chunk-VPD2PS35.mjs +0 -2
- package/dist/chunk-W4VKN3GF.mjs +0 -7
- package/dist/chunk-W5BXXPDJ.mjs +0 -3
- package/dist/chunk-XUNHRCOG.mjs +0 -6
- package/skill/references/building-components.md +0 -367
- package/web/assets/index-Bh74DfsV.css +0 -1
- package/web/assets/index-UW0RyFFt.js +0 -13
|
@@ -14,6 +14,8 @@ import { BLOCK_TYPES, LEAVES_BY_ENTER, accepts } from "../../components/registry
|
|
|
14
14
|
// too) moves out after the box, which goes if nothing is left in it (`leaveBox`).
|
|
15
15
|
// - A block of a type that says `resettable` (a quote's paragraph, a list item) turns into a
|
|
16
16
|
// paragraph where it stands, its container splitting around it (convert.mjs).
|
|
17
|
+
// - Backspace in an empty block of a type that says `emptyToText` (a heading, small text) turns it
|
|
18
|
+
// into an empty paragraph where it stands (`emptied`; the user's, 2026-11-09).
|
|
17
19
|
// Enter in a title that goes into its content (a disclosure, a card, a code block) is another rule
|
|
18
20
|
// (their components').
|
|
19
21
|
|
|
@@ -36,8 +38,10 @@ export function leaveBox(host) {
|
|
|
36
38
|
* and touchedBy (a structural undo step), convertHost, typeOf and targetsOf (convert.mjs).
|
|
37
39
|
*/
|
|
38
40
|
export function createLeaving({ struct, touchedBy, convertHost, typeOf, targetsOf }) {
|
|
39
|
-
// A block of a type that
|
|
40
|
-
const
|
|
41
|
+
// A block of a type that says `field` (resettable, emptyToText), which can be body text where it stands.
|
|
42
|
+
const says = (host, field) => BLOCK_TYPES[typeOf(host)]?.[field] === true && targetsOf(host).includes("paragraph");
|
|
43
|
+
const resets = (host) => says(host, "resettable");
|
|
44
|
+
const toText = (host) => convertHost(host, "paragraph");
|
|
41
45
|
|
|
42
46
|
// Enter on an empty text block. True when it left its container or became text.
|
|
43
47
|
function enter(host) {
|
|
@@ -52,7 +56,7 @@ export function createLeaving({ struct, touchedBy, convertHost, typeOf, targetsO
|
|
|
52
56
|
return true;
|
|
53
57
|
}
|
|
54
58
|
if (!resets(host)) return false;
|
|
55
|
-
|
|
59
|
+
toText(host);
|
|
56
60
|
return true;
|
|
57
61
|
}
|
|
58
62
|
|
|
@@ -60,9 +64,19 @@ export function createLeaving({ struct, touchedBy, convertHost, typeOf, targetsO
|
|
|
60
64
|
// quote's first paragraph), turns into body text before the container. True when it did.
|
|
61
65
|
function backspace(host) {
|
|
62
66
|
if (!resets(host) || host.parentElement?.firstElementChild !== host) return false;
|
|
63
|
-
|
|
67
|
+
toText(host);
|
|
64
68
|
return true;
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
// Backspace in an empty text block of a type that says `emptyToText` (a heading, small text): it turns
|
|
72
|
+
// into an empty paragraph where it stands, the caret in it, one undo step (the user's, 2026-11-09: as an
|
|
73
|
+
// emptied item or quote paragraph, and as every container left empty, goes back to body text). True
|
|
74
|
+
// when it did.
|
|
75
|
+
function emptied(host) {
|
|
76
|
+
if (!isEmpty(host) || !says(host, "emptyToText")) return false;
|
|
77
|
+
toText(host);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { enter, backspace, emptied };
|
|
68
82
|
}
|
|
@@ -55,6 +55,19 @@ export function button(label, action, { primary = false, ...props } = {}) {
|
|
|
55
55
|
return node;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* A text button in the editor's one button look (look.mjs BUTTONS, `.ge-btn`): no line, no fill, a gray
|
|
60
|
+
* under the pointer. `primary` the pale blue one (add, confirm, save; `data-primary`), `danger` with it the
|
|
61
|
+
* pale red (a delete), `quiet` a small one for looking, not deciding (`data-quiet`). A press on it leaves
|
|
62
|
+
* the selection where it is (button()).
|
|
63
|
+
*/
|
|
64
|
+
export function textButton(label, action, { primary = false, danger = false, quiet = false, class: own = "", ...props } = {}) {
|
|
65
|
+
const node = button(label, action, { primary, class: `ge-btn${own ? ` ${own}` : ""}`, ...props });
|
|
66
|
+
if (danger) node.dataset.danger = "";
|
|
67
|
+
if (quiet) node.dataset.quiet = "";
|
|
68
|
+
return node;
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
// Editor UI lives in the top layer with an open modal dialog, otherwise it would be inert.
|
|
59
72
|
export function layer() {
|
|
60
73
|
return document.querySelector(DIALOG.open) ?? document.body;
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { componentSettings, problemIn, writeComponentSettings } from "./component-catalog.mjs";
|
|
4
|
+
import { refusal, said } from "./i18n/index.mjs";
|
|
5
|
+
import { DEFAULT_PACK, OWN_SCOPE, PACK_FILE, PACK_ID, readPackManifest } from "./pack-manifest.mjs";
|
|
6
|
+
import { packsDirectory } from "./paths.mjs";
|
|
7
|
+
import { filesIn, fingerprintOf, fingerprintOfFiles, isSystemFile, recordOf, shippedBlocks, shippedPackIds, versionAfter, writeRecord, writingOrder } from "./shipped-blocks.mjs";
|
|
8
|
+
import { DEVICE_NAMES, PACKAGE_MANIFEST, layoutOf, markerOf, packageFolders } from "./workspace.mjs";
|
|
9
|
+
|
|
10
|
+
// Block packs (自定义块包: notes/plans/block-packs-plan-2026-11-09.md; docs/render.md "Block packs"). A pack
|
|
11
|
+
// is a scope of the workspace's custom blocks, components/<id>/, with its pack.json (./pack-manifest.mjs)
|
|
12
|
+
// and a folder of each of its blocks, <id>/<name>/, the blocks' ids <id>/<name> as ever, so that nothing
|
|
13
|
+
// written of a block changes; a scope with no pack.json is a pack of its own, named by its scope, and
|
|
14
|
+
// local/ (OWN_SCOPE: gallery block new <name>'s, where an Agent's block goes when it names no pack) is the
|
|
15
|
+
// default pack (默认块包, pack-manifest.mjs DEFAULT_PACK), always listed, first. A pack is shared as its folder, or a zip of it (the folder itself, or what it
|
|
16
|
+
// holds, at the zip's top), and installed into a workspace by gallery block pack install (src/cli/component.mjs)
|
|
17
|
+
// or 设置 › 组件列表's 导入 (src/server/component-settings.mjs), which both read it (src/transfer/pack-source.mjs)
|
|
18
|
+
// and hand its files here, checked alike:
|
|
19
|
+
//
|
|
20
|
+
// installPack its files copied in, as gallery block add copies one of Gallery's own: each block's
|
|
21
|
+
// manifest last; .gallery/blocks.json records each block's version and fingerprint, and
|
|
22
|
+
// under `packs` the pack's version, the fingerprint of its own files (pack.json, and what
|
|
23
|
+
// else stands at its top) and its blocks. Installed again (a newer version), a block as it
|
|
24
|
+
// was installed is replaced, one changed since kept as it is (someone's work), a block
|
|
25
|
+
// the new version has not taken out where it is as installed; pack.json the same way.
|
|
26
|
+
// Refused, with why (said()'s, a \`code\`): a file that points out of the pack ("path"),
|
|
27
|
+
// one too large ("size"), a pack.json missing or that does not read ("manifest"), a block
|
|
28
|
+
// folder of no component.json naming it <id>/<name> ("block"), the id of one of Gallery's
|
|
29
|
+
// own packs ("official"), an id a scope of the workspace has that no install put there
|
|
30
|
+
// ("taken": another pack, or blocks someone wrote).
|
|
31
|
+
// removePack a pack installed taken out, its folder and records; never one of Gallery's own (its
|
|
32
|
+
// switch turns it off), nor a scope no install put there ("own": someone's work).
|
|
33
|
+
// workspacePacks the workspace's packs as 设置 › 组件列表 and gallery block pack list say them.
|
|
34
|
+
//
|
|
35
|
+
// Gallery's own packs (src/packs/<id>/: gallery, Gallery 风格; gallery-soft, 柔光风格) are installed the
|
|
36
|
+
// same way as a workspace's server starts and by gallery init (installOfficialPacks): once each, a pack
|
|
37
|
+
// switched off at first where OFF_AT_FIRST says so (gallery.json's components.packs), and again at each
|
|
38
|
+
// start with the same rule, so that a block as it was installed follows Gallery, a block Gallery's pack
|
|
39
|
+
// has come to hold is added, and one taken away by hand stays away (its record says it was there).
|
|
40
|
+
// A pack's switch (components.packs, { "<id>": { "enabled": false } }, none written on) keeps all its
|
|
41
|
+
// blocks out of every menu and library, as each one's master switch does (shared/components/installed.mjs
|
|
42
|
+
// inDocumentMenus); what is written of them shows as ever.
|
|
43
|
+
|
|
44
|
+
/** Gallery's own packs that a workspace has switched off when they are first installed. */
|
|
45
|
+
export const OFF_AT_FIRST = Object.freeze(["gallery-soft"]);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The ids of Gallery's own packs that are off though gallery.json names no switch for them: one off at first
|
|
49
|
+
* (OFF_AT_FIRST) that this workspace has not installed yet, which its first install will switch off. A
|
|
50
|
+
* start that installs none (NO_PACKS, a workspace made by hand) has the library offer Gallery's own blocks
|
|
51
|
+
* from the package, and a pack that is off when it comes in is not one of them. `switches` is the catalog
|
|
52
|
+
* settings' `packs` (true on, false off, by id).
|
|
53
|
+
*/
|
|
54
|
+
export function offUntilInstalled(root, switches = {}) {
|
|
55
|
+
const installed = recordOf(root).packs;
|
|
56
|
+
return OFF_AT_FIRST.filter((id) => switches?.[id] === undefined && !isTable(installed?.[id]));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The environment variable that keeps a start (and gallery init) from installing Gallery's own packs: the tests' workspaces. */
|
|
60
|
+
export const NO_PACKS = "GALLERY_NO_PACKS";
|
|
61
|
+
|
|
62
|
+
/** Whether `env` says to install none of Gallery's own packs (NO_PACKS set, not to "", "0" or "false"). */
|
|
63
|
+
export const packsSkipped = (env = process.env) => !["", "0", "false", undefined].includes(env[NO_PACKS]);
|
|
64
|
+
|
|
65
|
+
const MOST_FILES = 2000;
|
|
66
|
+
const MOST_BYTES = 64 * 1024 * 1024;
|
|
67
|
+
const NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
68
|
+
const isTable = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
69
|
+
const fail = (code, message) => {
|
|
70
|
+
throw refusal(message, { code });
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/** The files of `folder`, [{ name (its path in it, with "/"), data }]: a link is none of them. */
|
|
74
|
+
export function folderFiles(folder) {
|
|
75
|
+
const files = [];
|
|
76
|
+
for (const entry of fs.readdirSync(folder, { recursive: true, withFileTypes: true })) {
|
|
77
|
+
if (!entry.isFile()) continue;
|
|
78
|
+
if (files.length >= MOST_FILES) fail("size", said("块包太大:最多 {0} 个文件、{1} MB", MOST_FILES, MOST_BYTES / 1024 / 1024));
|
|
79
|
+
const name = path.relative(folder, path.join(entry.parentPath, entry.name)).split(path.sep).join("/");
|
|
80
|
+
files.push({ name, data: fs.readFileSync(path.join(folder, ...name.split("/"))) });
|
|
81
|
+
}
|
|
82
|
+
return files;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A pack's files ([{ name, data }], as a folder or a zip gives them) read as one: { manifest, blocks: Map
|
|
87
|
+
* of each block's folder name to its files, own: the files at its top, pack.json among them }. A pack
|
|
88
|
+
* zipped with its folder (one folder at the top, pack.json in it) is read from that folder; what a
|
|
89
|
+
* system wrote (.DS_Store, __MACOSX/…) is passed over. Refused as installPack says; `refuse(manifest)`, run
|
|
90
|
+
* once its pack.json reads, before its blocks are looked at, refuses what it will.
|
|
91
|
+
*/
|
|
92
|
+
export function readPack(given, { refuse = () => {} } = {}) {
|
|
93
|
+
const files = [];
|
|
94
|
+
let bytes = 0;
|
|
95
|
+
for (const { name: written, data } of given) {
|
|
96
|
+
const name = String(written).replace(/\\/g, "/");
|
|
97
|
+
if (name.endsWith("/")) continue; // a folder of a zip
|
|
98
|
+
const parts = name.split("/");
|
|
99
|
+
if (name.startsWith("/") || /^[A-Za-z]:/.test(name) || name.includes("\u0000") || parts.some((part) => part === "" || part === "." || part === "..")) fail("path", said("{0} 指向块包外面,不能装", String(written)));
|
|
100
|
+
if (parts[0] === "__MACOSX" || isSystemFile(parts.at(-1))) continue;
|
|
101
|
+
bytes += data.length;
|
|
102
|
+
files.push({ name, data });
|
|
103
|
+
}
|
|
104
|
+
if (files.length > MOST_FILES || bytes > MOST_BYTES) fail("size", said("块包太大:最多 {0} 个文件、{1} MB", MOST_FILES, MOST_BYTES / 1024 / 1024));
|
|
105
|
+
let inner = files;
|
|
106
|
+
if (!files.some(({ name }) => name === PACK_FILE)) {
|
|
107
|
+
const tops = new Set(files.map(({ name }) => name.split("/")[0]));
|
|
108
|
+
const [top] = tops;
|
|
109
|
+
if (tops.size !== 1 || !files.some(({ name }) => name === `${top}/${PACK_FILE}`)) fail("manifest", said("最上一层没有 pack.json:块包是一个文件夹,最上一层放 pack.json,每个块一个文件夹"));
|
|
110
|
+
inner = files.map(({ name, data }) => ({ name: name.slice(top.length + 1), data }));
|
|
111
|
+
}
|
|
112
|
+
const manifest = readPackManifest(inner.find(({ name }) => name === PACK_FILE).data.toString("utf8"));
|
|
113
|
+
refuse(manifest);
|
|
114
|
+
const blocks = new Map();
|
|
115
|
+
const own = [];
|
|
116
|
+
for (const file of inner) {
|
|
117
|
+
const [first, ...rest] = file.name.split("/");
|
|
118
|
+
if (rest.length === 0) {
|
|
119
|
+
own.push(file);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
if (!blocks.has(first)) blocks.set(first, []);
|
|
123
|
+
blocks.get(first).push({ name: rest.join("/"), data: file.data });
|
|
124
|
+
}
|
|
125
|
+
for (const [name, list] of blocks) {
|
|
126
|
+
if (!NAME.test(name) || DEVICE_NAMES.has(name)) fail("block", said("{0} 不是块的文件夹名:只用小写字母、数字和连字符", name));
|
|
127
|
+
const file = list.find((each) => each.name === PACKAGE_MANIFEST);
|
|
128
|
+
if (!file) fail("block", said("{0}/ 里没有 component.json", name));
|
|
129
|
+
let id;
|
|
130
|
+
try {
|
|
131
|
+
id = JSON.parse(file.data.toString("utf8").replace(/^/, "")).id;
|
|
132
|
+
} catch {
|
|
133
|
+
fail("block", said("{0}/component.json 不是 JSON", name));
|
|
134
|
+
}
|
|
135
|
+
if (id !== `${manifest.id}/${name}`) fail("block", said("{0}/component.json 的 id 要写成 {1}", name, `${manifest.id}/${name}`));
|
|
136
|
+
}
|
|
137
|
+
return { manifest, blocks, own };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// A block's version, as its manifest says it, or null.
|
|
141
|
+
function versionIn(list) {
|
|
142
|
+
try {
|
|
143
|
+
const version = JSON.parse(list.find(({ name }) => name === PACKAGE_MANIFEST).data.toString("utf8").replace(/^/, "")).version;
|
|
144
|
+
return typeof version === "string" ? version : null;
|
|
145
|
+
} catch {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// The files right at the top of a pack's folder (pack.json and what else stands beside the blocks).
|
|
151
|
+
function topFiles(folder) {
|
|
152
|
+
try {
|
|
153
|
+
return fs.readdirSync(folder, { withFileTypes: true }).filter((entry) => entry.isFile() && !isSystemFile(entry.name)).map((entry) => entry.name).sort();
|
|
154
|
+
} catch {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// What the top of a pack's folder holds, as a fingerprint, or null for nothing there.
|
|
160
|
+
function ownFingerprint(folder) {
|
|
161
|
+
const names = topFiles(folder);
|
|
162
|
+
return names.length ? fingerprintOfFiles(names.map((name) => ({ name, data: fs.readFileSync(path.join(folder, name)) }))) : null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Whether a folder holds anything a system did not write there.
|
|
166
|
+
function holds(folder) {
|
|
167
|
+
try {
|
|
168
|
+
return fs.readdirSync(folder).some((name) => !isSystemFile(name));
|
|
169
|
+
} catch {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// `files` written into `folder`, the files of what was there that they have not taken out first
|
|
175
|
+
// (`replacing`), the manifest last: what makes a folder a block to a running server's watcher.
|
|
176
|
+
function writeFiles(folder, files, { replacing = false, last = PACKAGE_MANIFEST } = {}) {
|
|
177
|
+
const names = files.map(({ name }) => name);
|
|
178
|
+
if (replacing) for (const old of filesIn(folder)) if (!names.includes(old)) fs.rmSync(path.join(folder, ...old.split("/")), { force: true });
|
|
179
|
+
const byName = new Map(files.map((file) => [file.name, file.data]));
|
|
180
|
+
const order = last === PACKAGE_MANIFEST ? writingOrder(names) : [...names.filter((name) => name !== last), ...(names.includes(last) ? [last] : [])];
|
|
181
|
+
for (const name of order) {
|
|
182
|
+
const target = path.join(folder, ...name.split("/"));
|
|
183
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
184
|
+
fs.writeFileSync(target, byName.get(name));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The pack `given` holds ([{ name, data }]: src/transfer/pack-source.mjs reads a folder or a zip into
|
|
190
|
+
* them) installed into the workspace at `root` (above): { id, name, version, from (the version installed
|
|
191
|
+
* before, or null), did ("installed", "updated" or "same"), folder, added, updated, same, kept (blocks
|
|
192
|
+
* changed since they were installed, left as they are), removed (blocks the new version has not), skipped
|
|
193
|
+
* (blocks of Gallery's own taken away by hand, which stay away), ownKept (its pack.json changed since,
|
|
194
|
+
* left) }, each list of block ids. `official`: one of Gallery's own packs (installOfficialPacks), whose
|
|
195
|
+
* id is its own and whose scope may hold its blocks already, as gallery block add put them there.
|
|
196
|
+
*/
|
|
197
|
+
export function installPack(root, given, { official = false, shippedIds = shippedPackIds() } = {}) {
|
|
198
|
+
const { manifest, blocks, own } = readPack(given, {
|
|
199
|
+
refuse: ({ id }) => {
|
|
200
|
+
if (!official && shippedIds.includes(id)) fail("official", said("{0} 是 Gallery 自带的块包用的 id:换一个 id 再装", id));
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
const { id } = manifest;
|
|
204
|
+
const folder = path.join(layoutOf(root).components, id);
|
|
205
|
+
const record = recordOf(root);
|
|
206
|
+
const packs = isTable(record.packs) ? record.packs : {};
|
|
207
|
+
const was = isTable(packs[id]) ? packs[id] : null;
|
|
208
|
+
if (!official && !was && holds(folder)) fail("taken", said("工作区里已经有 components/{0}:这个名字被别的块包或别人写的块用着,换一个 id,或先把那个文件夹挪走", id));
|
|
209
|
+
const done = { id, name: manifest.name, version: manifest.version, from: was?.version ?? null, folder, added: [], updated: [], same: [], kept: [], removed: [], skipped: [], ownKept: false };
|
|
210
|
+
const names = [...blocks.keys()].sort();
|
|
211
|
+
for (const name of names) {
|
|
212
|
+
const block = `${id}/${name}`;
|
|
213
|
+
const list = blocks.get(name);
|
|
214
|
+
const target = path.join(folder, name);
|
|
215
|
+
const next = fingerprintOfFiles(list);
|
|
216
|
+
const now = fingerprintOf(target);
|
|
217
|
+
const kept = isTable(record[block]) ? record[block] : null;
|
|
218
|
+
if (now === null) {
|
|
219
|
+
if (official && kept) {
|
|
220
|
+
done.skipped.push(block);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
writeFiles(target, list);
|
|
224
|
+
done.added.push(block);
|
|
225
|
+
} else if (now === next) done.same.push(block);
|
|
226
|
+
else if (kept && now === kept.fingerprint) {
|
|
227
|
+
writeFiles(target, list, { replacing: true });
|
|
228
|
+
done.updated.push(block);
|
|
229
|
+
} else {
|
|
230
|
+
done.kept.push(block);
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
record[block] = { version: versionIn(list), fingerprint: next };
|
|
234
|
+
}
|
|
235
|
+
// The blocks of the pack as it was installed that this version has not: out, where they are as installed.
|
|
236
|
+
for (const block of Array.isArray(was?.blocks) ? was.blocks : []) {
|
|
237
|
+
const name = String(block).split("/")[1];
|
|
238
|
+
if (!name || blocks.has(name) || !NAME.test(name)) continue;
|
|
239
|
+
const target = path.join(folder, name);
|
|
240
|
+
const now = fingerprintOf(target);
|
|
241
|
+
if (now !== null && now !== record[block]?.fingerprint) {
|
|
242
|
+
done.kept.push(block);
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (now !== null) {
|
|
246
|
+
fs.rmSync(target, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
247
|
+
done.removed.push(block);
|
|
248
|
+
}
|
|
249
|
+
delete record[block];
|
|
250
|
+
}
|
|
251
|
+
// Its own files, pack.json last, the same way.
|
|
252
|
+
const ownNow = ownFingerprint(folder);
|
|
253
|
+
const ownNext = fingerprintOfFiles(own);
|
|
254
|
+
if (ownNow !== ownNext) {
|
|
255
|
+
if (ownNow === null || ownNow === was?.fingerprint) {
|
|
256
|
+
const names = own.map(({ name }) => name);
|
|
257
|
+
for (const old of topFiles(folder)) if (!names.includes(old)) fs.rmSync(path.join(folder, old), { force: true });
|
|
258
|
+
fs.mkdirSync(folder, { recursive: true });
|
|
259
|
+
writeFiles(folder, own, { last: PACK_FILE });
|
|
260
|
+
} else done.ownKept = true;
|
|
261
|
+
}
|
|
262
|
+
const changed = done.added.length + done.updated.length + done.removed.length > 0 || (ownNow !== ownNext && !done.ownKept);
|
|
263
|
+
done.did = !was ? "installed" : changed ? "updated" : "same";
|
|
264
|
+
record.packs = { ...packs, [id]: { version: manifest.version, fingerprint: done.ownKept ? was.fingerprint : ownNext, blocks: names.map((name) => `${id}/${name}`), ...(official ? { official: true } : {}) } };
|
|
265
|
+
writeRecord(root, record);
|
|
266
|
+
return done;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* The pack `id` taken out of the workspace at `root`: its folder and what .gallery/blocks.json records of
|
|
271
|
+
* it ({ id, version, blocks }). What documents and pages hold of its blocks stays, shown as blocks that
|
|
272
|
+
* are not there. Refused: one of Gallery's own ("official": its switch in 设置 › 组件列表 turns it off), none
|
|
273
|
+
* there ("missing"), a scope no install put there ("own": blocks someone wrote, theirs to delete).
|
|
274
|
+
*/
|
|
275
|
+
export function removePack(root, id, { shippedIds = shippedPackIds() } = {}) {
|
|
276
|
+
if (shippedIds.includes(id)) fail("official", said("{0} 是 Gallery 自带的块包,不能删除:在 设置 › 组件列表 里把它关掉", id));
|
|
277
|
+
const folder = path.join(layoutOf(root).components, id);
|
|
278
|
+
if (!PACK_ID.test(id) || !fs.existsSync(folder)) fail("missing", said("工作区里没有块包 {0}", id));
|
|
279
|
+
const record = recordOf(root);
|
|
280
|
+
const was = isTable(record.packs) && isTable(record.packs[id]) ? record.packs[id] : null;
|
|
281
|
+
if (!was) fail("own", said("components/{0} 不是装进来的块包,里面的块是有人在这个工作区写的:要删就自己删掉这个文件夹", id));
|
|
282
|
+
fs.rmSync(folder, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
|
|
283
|
+
for (const key of Object.keys(record)) if (key.startsWith(`${id}/`)) delete record[key];
|
|
284
|
+
const { [id]: _gone, ...rest } = record.packs;
|
|
285
|
+
writeRecord(root, { ...record, packs: rest });
|
|
286
|
+
return { id, version: was.version ?? null, blocks: Array.isArray(was.blocks) ? was.blocks : [] };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// Why, in both languages.
|
|
290
|
+
const both = (problem) => ({ zh: problemIn("zh", problem), en: problemIn("en", problem) });
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* The workspace's packs, as 设置 › 组件列表's cards and gallery block pack list say them: each scope of
|
|
294
|
+
* components/ that holds a block or a pack.json, [{ id, name: { zh, en } (its scope's for one with no
|
|
295
|
+
* pack.json), description, version, author, homepage, icon (null where it says none), kind ("official":
|
|
296
|
+
* one of Gallery's own; "installed": put there by an install; "own": a scope of blocks someone wrote
|
|
297
|
+
* here), problem ({ zh, en }: why its pack.json does not read, or null), blocks (how many), enabled (its
|
|
298
|
+
* switch, gallery.json's components.packs), changed (of what was installed, the blocks changed since, and
|
|
299
|
+
* pack.json where it was), newer (of one of Gallery's own that was changed since, Gallery's version of it
|
|
300
|
+
* when that comes after the one installed, which is not put over it; else null) }]: Gallery's own first,
|
|
301
|
+
* then those installed, then the workspace's own, each by id; and before them all the default pack (local/,
|
|
302
|
+
* OWN_SCOPE: kind "default", named and described by DEFAULT_PACK, its switch as any pack's), whether or
|
|
303
|
+
* not it holds a block yet: where an Agent's block goes when it names no pack.
|
|
304
|
+
*/
|
|
305
|
+
export function workspacePacks(root, { settings = null, shippedIds = shippedPackIds(), directory = packsDirectory } = {}) {
|
|
306
|
+
const { components } = layoutOf(root);
|
|
307
|
+
const record = recordOf(root);
|
|
308
|
+
const installed = isTable(record.packs) ? record.packs : {};
|
|
309
|
+
const blocks = packageFolders(root);
|
|
310
|
+
const scopes = new Set([OWN_SCOPE, ...blocks.map(({ id }) => id.split("/")[0])]);
|
|
311
|
+
try {
|
|
312
|
+
for (const name of fs.readdirSync(components)) if (PACK_ID.test(name) && fs.existsSync(path.join(components, name, PACK_FILE))) scopes.add(name);
|
|
313
|
+
} catch {}
|
|
314
|
+
const switches = (settings ?? componentSettings(root)).packs ?? {};
|
|
315
|
+
const listed = [...scopes].map((id) => {
|
|
316
|
+
const folder = path.join(components, id);
|
|
317
|
+
let manifest = null;
|
|
318
|
+
let problem = null;
|
|
319
|
+
if (fs.existsSync(path.join(folder, PACK_FILE))) {
|
|
320
|
+
try {
|
|
321
|
+
manifest = readPackManifest(fs.readFileSync(path.join(folder, PACK_FILE), "utf8"));
|
|
322
|
+
if (manifest.id !== id) {
|
|
323
|
+
problem = said("pack.json 的 id 是 {0},它的文件夹却是 components/{1}", manifest.id, id);
|
|
324
|
+
manifest = null;
|
|
325
|
+
}
|
|
326
|
+
} catch (error) {
|
|
327
|
+
problem = error;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const was = isTable(installed[id]) ? installed[id] : null;
|
|
331
|
+
const ids = blocks.filter((block) => block.id.startsWith(`${id}/`));
|
|
332
|
+
const changed = was ? ids.filter((block) => isTable(record[block.id]) && fingerprintOf(block.folder) !== record[block.id].fingerprint).map((block) => block.id) : [];
|
|
333
|
+
if (was && ownFingerprint(folder) !== was.fingerprint) changed.push(`${id}/${PACK_FILE}`);
|
|
334
|
+
const official = shippedIds.includes(id);
|
|
335
|
+
// One of Gallery's own: what Gallery's pack.json says of it, where the workspace's has none (its blocks
|
|
336
|
+
// put there one by one, gallery block add's, before a start installed the pack).
|
|
337
|
+
let shipped = null;
|
|
338
|
+
if (official) {
|
|
339
|
+
try {
|
|
340
|
+
shipped = readPackManifest(fs.readFileSync(path.join(directory, id, PACK_FILE), "utf8"));
|
|
341
|
+
} catch {}
|
|
342
|
+
}
|
|
343
|
+
// Gallery's newer version, not put over a change: a changed block of it whose version Gallery's comes after, or a changed pack.json.
|
|
344
|
+
const versionAt = (block) => {
|
|
345
|
+
try {
|
|
346
|
+
return JSON.parse(fs.readFileSync(path.join(components, ...block.split("/"), PACKAGE_MANIFEST), "utf8")).version ?? null;
|
|
347
|
+
} catch {
|
|
348
|
+
return null;
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
const ownBlocks = official ? shippedBlocks(directory) : [];
|
|
352
|
+
const behind = official && shipped && changed.some((block) => (block.endsWith(`/${PACK_FILE}`) ? versionAfter(shipped.version, manifest?.version ?? null) : (ownBlocks.some((one) => one.id === block) && versionAfter(ownBlocks.find((one) => one.id === block).version, versionAt(block)))));
|
|
353
|
+
const newer = behind ? shipped.version : null;
|
|
354
|
+
const told = id === OWN_SCOPE ? DEFAULT_PACK : manifest ?? (problem ? null : shipped);
|
|
355
|
+
return {
|
|
356
|
+
id,
|
|
357
|
+
name: told?.name ?? { zh: id, en: id },
|
|
358
|
+
description: told?.description ?? null,
|
|
359
|
+
version: manifest?.version ?? null,
|
|
360
|
+
author: told?.author ?? null,
|
|
361
|
+
homepage: told?.homepage ?? null,
|
|
362
|
+
icon: told?.icon ?? null,
|
|
363
|
+
kind: id === OWN_SCOPE ? "default" : official ? "official" : was ? "installed" : "own",
|
|
364
|
+
problem: problem ? both(problem) : null,
|
|
365
|
+
blocks: ids.length,
|
|
366
|
+
enabled: switches[id] !== false,
|
|
367
|
+
changed,
|
|
368
|
+
newer,
|
|
369
|
+
};
|
|
370
|
+
});
|
|
371
|
+
const rank = ({ id, kind }) => (kind === "default" ? -1 : kind === "official" ? shippedIds.indexOf(id) : kind === "installed" ? 1000 : 2000);
|
|
372
|
+
return listed.sort((a, b) => rank(a) - rank(b) || (a.id < b.id ? -1 : 1));
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// What installOfficialPacks tells the log of one pack, a line each.
|
|
376
|
+
function installedLines(root, made, first) {
|
|
377
|
+
const lines = [];
|
|
378
|
+
const where = path.resolve(root);
|
|
379
|
+
if (first) lines.push(`Gallery's pack ${made.id} ${made.version} installed in ${where} (${made.added.length + made.same.length + made.updated.length} blocks)${OFF_AT_FIRST.includes(made.id) ? ", switched off: 设置 › 组件列表 turns it on" : ""}`);
|
|
380
|
+
else {
|
|
381
|
+
if (made.added.length) lines.push(`Gallery's pack ${made.id} in ${where} has new blocks: ${made.added.join(", ")}`);
|
|
382
|
+
if (made.updated.length) lines.push(`Gallery's pack ${made.id} in ${where}, its blocks as they were installed, updated to this Gallery's: ${made.updated.join(", ")}`);
|
|
383
|
+
if (made.removed.length) lines.push(`Gallery's pack ${made.id} in ${where}: ${made.removed.join(", ")} no longer in it, taken out`);
|
|
384
|
+
}
|
|
385
|
+
return lines;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Gallery's own packs (in `directory`, the package's) installed into the workspace at `root`, as
|
|
390
|
+
* installPack installs any, whenever its server starts and by gallery init: one not installed yet is
|
|
391
|
+
* (one of OFF_AT_FIRST switched off first in gallery.json, where it says nothing of it: a gallery.json that
|
|
392
|
+
* cannot be written leaves that pack for the next start), one installed is brought up to Gallery's.
|
|
393
|
+
* `env`: whose NO_PACKS is read; `log`: told what was done, a line each. Never rejects: { did: "off"
|
|
394
|
+
* (NO_PACKS), "unread" (gallery.json does not read as Gallery's) or "done", packs: [installPack's answer
|
|
395
|
+
* with `first`, or { id, failed }] }.
|
|
396
|
+
*/
|
|
397
|
+
export async function installOfficialPacks(root, { directory = packsDirectory, env = process.env, log = () => {} } = {}) {
|
|
398
|
+
if (packsSkipped(env)) return { did: "off", packs: [] };
|
|
399
|
+
let marker = { ours: false };
|
|
400
|
+
try {
|
|
401
|
+
marker = markerOf(fs.readFileSync(layoutOf(root).marker, "utf8"));
|
|
402
|
+
} catch {}
|
|
403
|
+
if (!marker.ours) return { did: "unread", packs: [] };
|
|
404
|
+
const ids = shippedPackIds(directory);
|
|
405
|
+
const packs = [];
|
|
406
|
+
for (const id of ids) {
|
|
407
|
+
try {
|
|
408
|
+
const first = !isTable(recordOf(root).packs?.[id]);
|
|
409
|
+
if (first && OFF_AT_FIRST.includes(id) && componentSettings(root).packs[id] === undefined) await writeComponentSettings(root, { pack: id, enabled: false });
|
|
410
|
+
const made = installPack(root, folderFiles(path.join(directory, id)), { official: true, shippedIds: ids });
|
|
411
|
+
packs.push({ ...made, first });
|
|
412
|
+
for (const line of installedLines(root, made, first)) log(line);
|
|
413
|
+
} catch (error) {
|
|
414
|
+
log(`Gallery's pack ${id} could not be installed in ${path.resolve(root)}: ${error?.message ?? error}`);
|
|
415
|
+
packs.push({ id, failed: error?.message ?? String(error) });
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
return { did: "done", packs };
|
|
419
|
+
}
|