@alloy-js/core 0.24.0-dev.2 → 0.24.0-dev.7
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/CHANGELOG.md +8 -0
- package/dist/dev/src/components/AccessExpression.test.js +30 -38
- package/dist/dev/src/components/AccessExpression.test.js.map +1 -1
- package/dist/dev/src/components/Output.js +3 -2
- package/dist/dev/src/components/Output.js.map +1 -1
- package/dist/dev/src/components/SourceFile.js.map +1 -1
- package/dist/dev/src/content-slot.test.js +16 -18
- package/dist/dev/src/content-slot.test.js.map +1 -1
- package/dist/dev/src/context.js +30 -3
- package/dist/dev/src/context.js.map +1 -1
- package/dist/dev/src/debug/diagnostics.test.js +1 -1
- package/dist/dev/src/debug/diagnostics.test.js.map +1 -1
- package/dist/dev/src/debug/effects.test.js +1 -1
- package/dist/dev/src/debug/effects.test.js.map +1 -1
- package/dist/dev/src/debug/file-streaming.js +103 -0
- package/dist/dev/src/debug/file-streaming.js.map +1 -0
- package/dist/dev/src/debug/files.test.js +4 -5
- package/dist/dev/src/debug/files.test.js.map +1 -1
- package/dist/dev/src/debug/index.js +4 -6
- package/dist/dev/src/debug/index.js.map +1 -1
- package/dist/dev/src/debug/message-format.test.js +50 -52
- package/dist/dev/src/debug/message-format.test.js.map +1 -1
- package/dist/dev/src/debug/render-tree-orphans.test.js +13 -23
- package/dist/dev/src/debug/render-tree-orphans.test.js.map +1 -1
- package/dist/dev/src/debug/render.js +529 -352
- package/dist/dev/src/debug/render.js.map +1 -1
- package/dist/dev/src/debug/render.test.js +171 -92
- package/dist/dev/src/debug/render.test.js.map +1 -1
- package/dist/dev/src/debug/trace-writer.js +127 -15
- package/dist/dev/src/debug/trace-writer.js.map +1 -1
- package/dist/dev/src/debug/trace.js +0 -36
- package/dist/dev/src/debug/trace.js.map +1 -1
- package/dist/dev/src/devtools/devtools-server.js +55 -32
- package/dist/dev/src/devtools/devtools-server.js.map +1 -1
- package/dist/dev/src/devtools-entry.browser.js.map +1 -1
- package/dist/dev/src/devtools-entry.js.map +1 -1
- package/dist/dev/src/diagnostics.js +19 -1
- package/dist/dev/src/diagnostics.js.map +1 -1
- package/dist/dev/src/index.js +5 -2
- package/dist/dev/src/index.js.map +1 -1
- package/dist/dev/src/jsx-runtime.js +14 -8
- package/dist/dev/src/jsx-runtime.js.map +1 -1
- package/dist/dev/src/output-types.js +2 -0
- package/dist/dev/src/output-types.js.map +1 -0
- package/dist/dev/src/reactivity.js +155 -13
- package/dist/dev/src/reactivity.js.map +1 -1
- package/dist/dev/src/render/get-string-width.js +61 -0
- package/dist/dev/src/render/get-string-width.js.map +1 -0
- package/dist/dev/src/render/index.js +2 -0
- package/dist/dev/src/render/index.js.map +1 -0
- package/dist/dev/src/render/node-context.js +7 -0
- package/dist/dev/src/render/node-context.js.map +1 -0
- package/dist/dev/src/render/node.js +386 -0
- package/dist/dev/src/render/node.js.map +1 -0
- package/dist/dev/src/render/printer-support.js +180 -0
- package/dist/dev/src/render/printer-support.js.map +1 -0
- package/dist/dev/src/render/printer.js +797 -0
- package/dist/dev/src/render/printer.js.map +1 -0
- package/dist/dev/src/render-error.js +79 -0
- package/dist/dev/src/render-error.js.map +1 -0
- package/dist/dev/src/render-output.js +209 -0
- package/dist/dev/src/render-output.js.map +1 -0
- package/dist/dev/src/runtime/create-intrinsic.js +53 -0
- package/dist/dev/src/runtime/create-intrinsic.js.map +1 -0
- package/dist/dev/src/runtime/fragment.js +21 -0
- package/dist/dev/src/runtime/fragment.js.map +1 -0
- package/dist/dev/src/runtime/index.js +13 -0
- package/dist/dev/src/runtime/index.js.map +1 -0
- package/dist/dev/src/runtime/insert.js +453 -0
- package/dist/dev/src/runtime/insert.js.map +1 -0
- package/dist/dev/src/runtime/intrinsic.js +1 -11
- package/dist/dev/src/runtime/intrinsic.js.map +1 -1
- package/dist/dev/src/scheduler.js +38 -14
- package/dist/dev/src/scheduler.js.map +1 -1
- package/dist/dev/src/stc.js +2 -0
- package/dist/dev/src/stc.js.map +1 -1
- package/dist/dev/src/sti.js +1 -1
- package/dist/dev/src/sti.js.map +1 -1
- package/dist/dev/src/symbols/symbol-slot.test.js +5 -5
- package/dist/dev/src/symbols/symbol-slot.test.js.map +1 -1
- package/dist/dev/src/test-render.js +78 -0
- package/dist/dev/src/test-render.js.map +1 -0
- package/dist/dev/src/utils.js +47 -35
- package/dist/dev/src/utils.js.map +1 -1
- package/dist/dev/test/babel-e2e.test.js +218 -0
- package/dist/dev/test/babel-e2e.test.js.map +1 -0
- package/dist/dev/test/children.test.js +9 -11
- package/dist/dev/test/children.test.js.map +1 -1
- package/dist/dev/test/components/append-file.test.js +26 -27
- package/dist/dev/test/components/append-file.test.js.map +1 -1
- package/dist/dev/test/components/block.test.js +9 -11
- package/dist/dev/test/components/block.test.js.map +1 -1
- package/dist/dev/test/components/copy-file.test.js +1 -2
- package/dist/dev/test/components/copy-file.test.js.map +1 -1
- package/dist/dev/test/components/declaration.test.js +2 -2
- package/dist/dev/test/components/declaration.test.js.map +1 -1
- package/dist/dev/test/components/list.test.js +41 -43
- package/dist/dev/test/components/list.test.js.map +1 -1
- package/dist/dev/test/components/prose.test.js +4 -5
- package/dist/dev/test/components/prose.test.js.map +1 -1
- package/dist/dev/test/components/reference-or-content.test.js +32 -33
- package/dist/dev/test/components/reference-or-content.test.js.map +1 -1
- package/dist/dev/test/components/source-file.test.js +8 -7
- package/dist/dev/test/components/source-file.test.js.map +1 -1
- package/dist/dev/test/components/template-file.test.js +16 -17
- package/dist/dev/test/components/template-file.test.js.map +1 -1
- package/dist/dev/test/components/update-file.test.js +11 -12
- package/dist/dev/test/components/update-file.test.js.map +1 -1
- package/dist/dev/test/components/wrap.test.js +6 -8
- package/dist/dev/test/components/wrap.test.js.map +1 -1
- package/dist/dev/test/control-flow/for.test.js +58 -42
- package/dist/dev/test/control-flow/for.test.js.map +1 -1
- package/dist/dev/test/control-flow/match.test.js +15 -17
- package/dist/dev/test/control-flow/match.test.js.map +1 -1
- package/dist/dev/test/control-flow/show.test.js +5 -8
- package/dist/dev/test/control-flow/show.test.js.map +1 -1
- package/dist/dev/test/lazy-isempty.test.js +29 -31
- package/dist/dev/test/lazy-isempty.test.js.map +1 -1
- package/dist/dev/test/name-policy.test.js +2 -3
- package/dist/dev/test/name-policy.test.js.map +1 -1
- package/dist/dev/test/node.test.js +80 -0
- package/dist/dev/test/node.test.js.map +1 -0
- package/dist/dev/test/output-e2e.test.js +194 -0
- package/dist/dev/test/output-e2e.test.js.map +1 -0
- package/dist/dev/test/reactivity/circular-reactives.test.js +9 -9
- package/dist/dev/test/reactivity/circular-reactives.test.js.map +1 -1
- package/dist/dev/test/reactivity/cleanup.test.js +5 -6
- package/dist/dev/test/reactivity/cleanup.test.js.map +1 -1
- package/dist/dev/test/reactivity/ref-rendering.test.js +15 -15
- package/dist/dev/test/reactivity/ref-rendering.test.js.map +1 -1
- package/dist/dev/test/reactivity/test.test.js +18 -18
- package/dist/dev/test/reactivity/test.test.js.map +1 -1
- package/dist/dev/test/rendering/basic.test.js +18 -19
- package/dist/dev/test/rendering/basic.test.js.map +1 -1
- package/dist/dev/test/rendering/code.test.js +2 -3
- package/dist/dev/test/rendering/code.test.js.map +1 -1
- package/dist/dev/test/rendering/formatting.test.js +115 -121
- package/dist/dev/test/rendering/formatting.test.js.map +1 -1
- package/dist/dev/test/rendering/indent.test.js +23 -24
- package/dist/dev/test/rendering/indent.test.js.map +1 -1
- package/dist/dev/test/rendering/memoization.test.js +9 -5
- package/dist/dev/test/rendering/memoization.test.js.map +1 -1
- package/dist/dev/test/rendering/print-render-stack.test.js +20 -21
- package/dist/dev/test/rendering/print-render-stack.test.js.map +1 -1
- package/dist/dev/test/rendering/refkeys.test.js +1 -2
- package/dist/dev/test/rendering/refkeys.test.js.map +1 -1
- package/dist/dev/test/rendering/render-output-diagnostics.test.js +102 -0
- package/dist/dev/test/rendering/render-output-diagnostics.test.js.map +1 -0
- package/dist/dev/test/runtime.test.js +385 -0
- package/dist/dev/test/runtime.test.js.map +1 -0
- package/dist/dev/test/stc.test.js +0 -1
- package/dist/dev/test/stc.test.js.map +1 -1
- package/dist/dev/test/tree-test-utils.js +16 -0
- package/dist/dev/test/tree-test-utils.js.map +1 -0
- package/dist/dev/test/utils.test.js +34 -33
- package/dist/dev/test/utils.test.js.map +1 -1
- package/dist/dev/test/vitest.setup.js +2 -0
- package/dist/dev/test/vitest.setup.js.map +1 -0
- package/dist/dev/testing/devtools-utils.js +1 -1
- package/dist/dev/testing/devtools-utils.js.map +1 -1
- package/dist/dev/testing/extend-expect.js +30 -34
- package/dist/dev/testing/extend-expect.js.map +1 -1
- package/dist/dev/testing/render.js +7 -17
- package/dist/dev/testing/render.js.map +1 -1
- package/dist/devtools/index.html +17 -17
- package/dist/src/components/AccessExpression.test.d.ts +1 -1
- package/dist/src/components/AccessExpression.test.d.ts.map +1 -1
- package/dist/src/components/AccessExpression.test.js +5 -13
- package/dist/src/components/AccessExpression.test.js.map +1 -1
- package/dist/src/components/Output.d.ts +1 -1
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +2 -1
- package/dist/src/components/Output.js.map +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts +1 -1
- package/dist/src/components/ReferenceOrContent.d.ts.map +1 -1
- package/dist/src/components/SourceFile.d.ts +1 -1
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/content-slot.test.d.ts +1 -1
- package/dist/src/content-slot.test.d.ts.map +1 -1
- package/dist/src/content-slot.test.js +8 -10
- package/dist/src/content-slot.test.js.map +1 -1
- package/dist/src/context/format-options.d.ts +1 -1
- package/dist/src/context/format-options.d.ts.map +1 -1
- package/dist/src/context.d.ts +9 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +30 -3
- package/dist/src/context.js.map +1 -1
- package/dist/src/debug/diagnostics.test.js +1 -1
- package/dist/src/debug/diagnostics.test.js.map +1 -1
- package/dist/src/debug/effects.test.js +1 -1
- package/dist/src/debug/effects.test.js.map +1 -1
- package/dist/src/debug/file-streaming.d.ts +22 -0
- package/dist/src/debug/file-streaming.d.ts.map +1 -0
- package/dist/src/debug/file-streaming.js +103 -0
- package/dist/src/debug/file-streaming.js.map +1 -0
- package/dist/src/debug/files.test.js +4 -5
- package/dist/src/debug/files.test.js.map +1 -1
- package/dist/src/debug/index.d.ts +5 -7
- package/dist/src/debug/index.d.ts.map +1 -1
- package/dist/src/debug/index.js +4 -6
- package/dist/src/debug/index.js.map +1 -1
- package/dist/src/debug/message-format.test.js +16 -18
- package/dist/src/debug/message-format.test.js.map +1 -1
- package/dist/src/debug/render-tree-orphans.test.js +8 -18
- package/dist/src/debug/render-tree-orphans.test.js.map +1 -1
- package/dist/src/debug/render.d.ts +71 -21
- package/dist/src/debug/render.d.ts.map +1 -1
- package/dist/src/debug/render.js +529 -352
- package/dist/src/debug/render.js.map +1 -1
- package/dist/src/debug/render.test.js +137 -74
- package/dist/src/debug/render.test.js.map +1 -1
- package/dist/src/debug/trace-writer.d.ts +6 -1
- package/dist/src/debug/trace-writer.d.ts.map +1 -1
- package/dist/src/debug/trace-writer.js +127 -15
- package/dist/src/debug/trace-writer.js.map +1 -1
- package/dist/src/debug/trace.d.ts +0 -36
- package/dist/src/debug/trace.d.ts.map +1 -1
- package/dist/src/debug/trace.js +0 -36
- package/dist/src/debug/trace.js.map +1 -1
- package/dist/src/devtools/devtools-protocol.d.ts +34 -1
- package/dist/src/devtools/devtools-protocol.d.ts.map +1 -1
- package/dist/src/devtools/devtools-server.d.ts.map +1 -1
- package/dist/src/devtools/devtools-server.js +55 -32
- package/dist/src/devtools/devtools-server.js.map +1 -1
- package/dist/src/devtools-entry.browser.d.ts +1 -1
- package/dist/src/devtools-entry.browser.d.ts.map +1 -1
- package/dist/src/devtools-entry.browser.js.map +1 -1
- package/dist/src/devtools-entry.d.ts +1 -1
- package/dist/src/devtools-entry.d.ts.map +1 -1
- package/dist/src/devtools-entry.js.map +1 -1
- package/dist/src/diagnostics.d.ts +4 -0
- package/dist/src/diagnostics.d.ts.map +1 -1
- package/dist/src/diagnostics.js +19 -1
- package/dist/src/diagnostics.js.map +1 -1
- package/dist/src/index.d.ts +5 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsx-runtime.d.ts +13 -4
- package/dist/src/jsx-runtime.d.ts.map +1 -1
- package/dist/src/jsx-runtime.js +14 -8
- package/dist/src/jsx-runtime.js.map +1 -1
- package/dist/src/output-types.d.ts +40 -0
- package/dist/src/output-types.d.ts.map +1 -0
- package/dist/src/output-types.js +2 -0
- package/dist/src/output-types.js.map +1 -0
- package/dist/src/reactivity.d.ts +49 -18
- package/dist/src/reactivity.d.ts.map +1 -1
- package/dist/src/reactivity.js +155 -13
- package/dist/src/reactivity.js.map +1 -1
- package/dist/src/render/get-string-width.d.ts +19 -0
- package/dist/src/render/get-string-width.d.ts.map +1 -0
- package/dist/src/render/get-string-width.js +61 -0
- package/dist/src/render/get-string-width.js.map +1 -0
- package/dist/src/render/index.d.ts +2 -0
- package/dist/src/render/index.d.ts.map +1 -0
- package/dist/src/render/index.js +2 -0
- package/dist/src/render/index.js.map +1 -0
- package/dist/src/render/node-context.d.ts +5 -0
- package/dist/src/render/node-context.d.ts.map +1 -0
- package/dist/src/render/node-context.js +7 -0
- package/dist/src/render/node-context.js.map +1 -0
- package/dist/src/render/node.d.ts +146 -0
- package/dist/src/render/node.d.ts.map +1 -0
- package/dist/src/render/node.js +386 -0
- package/dist/src/render/node.js.map +1 -0
- package/dist/src/render/printer-support.d.ts +50 -0
- package/dist/src/render/printer-support.d.ts.map +1 -0
- package/dist/src/render/printer-support.js +180 -0
- package/dist/src/render/printer-support.js.map +1 -0
- package/dist/src/render/printer.d.ts +35 -0
- package/dist/src/render/printer.d.ts.map +1 -0
- package/dist/src/render/printer.js +797 -0
- package/dist/src/render/printer.js.map +1 -0
- package/dist/src/render-error.d.ts +4 -0
- package/dist/src/render-error.d.ts.map +1 -0
- package/dist/src/render-error.js +79 -0
- package/dist/src/render-error.js.map +1 -0
- package/dist/src/render-output.d.ts +42 -0
- package/dist/src/render-output.d.ts.map +1 -0
- package/dist/src/render-output.js +209 -0
- package/dist/src/render-output.js.map +1 -0
- package/dist/src/runtime/component.d.ts +2 -2
- package/dist/src/runtime/component.d.ts.map +1 -1
- package/dist/src/runtime/create-intrinsic.d.ts +28 -0
- package/dist/src/runtime/create-intrinsic.d.ts.map +1 -0
- package/dist/src/runtime/create-intrinsic.js +53 -0
- package/dist/src/runtime/create-intrinsic.js.map +1 -0
- package/dist/src/runtime/fragment.d.ts +16 -0
- package/dist/src/runtime/fragment.d.ts.map +1 -0
- package/dist/src/runtime/fragment.js +21 -0
- package/dist/src/runtime/fragment.js.map +1 -0
- package/dist/src/runtime/index.d.ts +12 -0
- package/dist/src/runtime/index.d.ts.map +1 -0
- package/dist/src/runtime/index.js +13 -0
- package/dist/src/runtime/index.js.map +1 -0
- package/dist/src/runtime/insert.d.ts +29 -0
- package/dist/src/runtime/insert.d.ts.map +1 -0
- package/dist/src/runtime/insert.js +453 -0
- package/dist/src/runtime/insert.js.map +1 -0
- package/dist/src/runtime/intrinsic.d.ts +12 -29
- package/dist/src/runtime/intrinsic.d.ts.map +1 -1
- package/dist/src/runtime/intrinsic.js +1 -11
- package/dist/src/runtime/intrinsic.js.map +1 -1
- package/dist/src/scheduler.d.ts.map +1 -1
- package/dist/src/scheduler.js +38 -14
- package/dist/src/scheduler.js.map +1 -1
- package/dist/src/stc.d.ts.map +1 -1
- package/dist/src/stc.js +2 -0
- package/dist/src/stc.js.map +1 -1
- package/dist/src/sti.d.ts +7 -6
- package/dist/src/sti.d.ts.map +1 -1
- package/dist/src/sti.js +1 -1
- package/dist/src/sti.js.map +1 -1
- package/dist/src/symbols/symbol-slot.test.js +5 -5
- package/dist/src/symbols/symbol-slot.test.js.map +1 -1
- package/dist/src/test-render.d.ts +31 -0
- package/dist/src/test-render.d.ts.map +1 -0
- package/dist/src/test-render.js +78 -0
- package/dist/src/test-render.js.map +1 -0
- package/dist/src/utils.d.ts +1 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +40 -28
- package/dist/src/utils.js.map +1 -1
- package/dist/src/write-output.d.ts +1 -1
- package/dist/src/write-output.d.ts.map +1 -1
- package/dist/test/babel-e2e.test.d.ts +13 -0
- package/dist/test/babel-e2e.test.d.ts.map +1 -0
- package/dist/test/babel-e2e.test.js +218 -0
- package/dist/test/babel-e2e.test.js.map +1 -0
- package/dist/test/children.test.js +5 -7
- package/dist/test/children.test.js.map +1 -1
- package/dist/test/components/append-file.test.d.ts +1 -1
- package/dist/test/components/append-file.test.d.ts.map +1 -1
- package/dist/test/components/append-file.test.js +0 -1
- package/dist/test/components/append-file.test.js.map +1 -1
- package/dist/test/components/block.test.d.ts +1 -1
- package/dist/test/components/block.test.d.ts.map +1 -1
- package/dist/test/components/block.test.js +4 -6
- package/dist/test/components/block.test.js.map +1 -1
- package/dist/test/components/copy-file.test.d.ts +1 -1
- package/dist/test/components/copy-file.test.d.ts.map +1 -1
- package/dist/test/components/copy-file.test.js +1 -2
- package/dist/test/components/copy-file.test.js.map +1 -1
- package/dist/test/components/declaration.test.js +2 -2
- package/dist/test/components/declaration.test.js.map +1 -1
- package/dist/test/components/list.test.d.ts +1 -1
- package/dist/test/components/list.test.d.ts.map +1 -1
- package/dist/test/components/list.test.js +20 -22
- package/dist/test/components/list.test.js.map +1 -1
- package/dist/test/components/prose.test.d.ts +1 -1
- package/dist/test/components/prose.test.d.ts.map +1 -1
- package/dist/test/components/prose.test.js +0 -1
- package/dist/test/components/prose.test.js.map +1 -1
- package/dist/test/components/reference-or-content.test.js +8 -9
- package/dist/test/components/reference-or-content.test.js.map +1 -1
- package/dist/test/components/source-file.test.d.ts +1 -1
- package/dist/test/components/source-file.test.d.ts.map +1 -1
- package/dist/test/components/source-file.test.js +5 -4
- package/dist/test/components/source-file.test.js.map +1 -1
- package/dist/test/components/template-file.test.d.ts +1 -1
- package/dist/test/components/template-file.test.d.ts.map +1 -1
- package/dist/test/components/template-file.test.js +0 -1
- package/dist/test/components/template-file.test.js.map +1 -1
- package/dist/test/components/update-file.test.d.ts +1 -1
- package/dist/test/components/update-file.test.d.ts.map +1 -1
- package/dist/test/components/update-file.test.js +1 -2
- package/dist/test/components/update-file.test.js.map +1 -1
- package/dist/test/components/wrap.test.d.ts +1 -1
- package/dist/test/components/wrap.test.d.ts.map +1 -1
- package/dist/test/components/wrap.test.js +3 -5
- package/dist/test/components/wrap.test.js.map +1 -1
- package/dist/test/control-flow/for.test.d.ts +1 -1
- package/dist/test/control-flow/for.test.d.ts.map +1 -1
- package/dist/test/control-flow/for.test.js +40 -24
- package/dist/test/control-flow/for.test.js.map +1 -1
- package/dist/test/control-flow/match.test.d.ts +1 -1
- package/dist/test/control-flow/match.test.d.ts.map +1 -1
- package/dist/test/control-flow/match.test.js +4 -6
- package/dist/test/control-flow/match.test.js.map +1 -1
- package/dist/test/control-flow/show.test.d.ts +1 -1
- package/dist/test/control-flow/show.test.d.ts.map +1 -1
- package/dist/test/control-flow/show.test.js +3 -6
- package/dist/test/control-flow/show.test.js.map +1 -1
- package/dist/test/lazy-isempty.test.d.ts +1 -1
- package/dist/test/lazy-isempty.test.d.ts.map +1 -1
- package/dist/test/lazy-isempty.test.js +16 -18
- package/dist/test/lazy-isempty.test.js.map +1 -1
- package/dist/test/name-policy.test.d.ts +1 -1
- package/dist/test/name-policy.test.d.ts.map +1 -1
- package/dist/test/name-policy.test.js +0 -1
- package/dist/test/name-policy.test.js.map +1 -1
- package/dist/test/node.test.d.ts +2 -0
- package/dist/test/node.test.d.ts.map +1 -0
- package/dist/test/node.test.js +80 -0
- package/dist/test/node.test.js.map +1 -0
- package/dist/test/output-e2e.test.d.ts +13 -0
- package/dist/test/output-e2e.test.d.ts.map +1 -0
- package/dist/test/output-e2e.test.js +194 -0
- package/dist/test/output-e2e.test.js.map +1 -0
- package/dist/test/reactivity/circular-reactives.test.js +6 -6
- package/dist/test/reactivity/circular-reactives.test.js.map +1 -1
- package/dist/test/reactivity/cleanup.test.js +2 -3
- package/dist/test/reactivity/cleanup.test.js.map +1 -1
- package/dist/test/reactivity/ref-rendering.test.js +15 -15
- package/dist/test/reactivity/ref-rendering.test.js.map +1 -1
- package/dist/test/reactivity/test.test.js +15 -15
- package/dist/test/reactivity/test.test.js.map +1 -1
- package/dist/test/rendering/basic.test.d.ts +1 -1
- package/dist/test/rendering/basic.test.d.ts.map +1 -1
- package/dist/test/rendering/basic.test.js +0 -1
- package/dist/test/rendering/basic.test.js.map +1 -1
- package/dist/test/rendering/code.test.d.ts +1 -1
- package/dist/test/rendering/code.test.d.ts.map +1 -1
- package/dist/test/rendering/code.test.js +0 -1
- package/dist/test/rendering/code.test.js.map +1 -1
- package/dist/test/rendering/formatting.test.d.ts +1 -1
- package/dist/test/rendering/formatting.test.d.ts.map +1 -1
- package/dist/test/rendering/formatting.test.js +17 -23
- package/dist/test/rendering/formatting.test.js.map +1 -1
- package/dist/test/rendering/indent.test.d.ts +1 -1
- package/dist/test/rendering/indent.test.d.ts.map +1 -1
- package/dist/test/rendering/indent.test.js +0 -1
- package/dist/test/rendering/indent.test.js.map +1 -1
- package/dist/test/rendering/memoization.test.js +7 -3
- package/dist/test/rendering/memoization.test.js.map +1 -1
- package/dist/test/rendering/print-render-stack.test.d.ts +1 -1
- package/dist/test/rendering/print-render-stack.test.d.ts.map +1 -1
- package/dist/test/rendering/print-render-stack.test.js +0 -1
- package/dist/test/rendering/print-render-stack.test.js.map +1 -1
- package/dist/test/rendering/refkeys.test.d.ts +1 -1
- package/dist/test/rendering/refkeys.test.d.ts.map +1 -1
- package/dist/test/rendering/refkeys.test.js +0 -1
- package/dist/test/rendering/refkeys.test.js.map +1 -1
- package/dist/test/rendering/render-output-diagnostics.test.d.ts +2 -0
- package/dist/test/rendering/render-output-diagnostics.test.d.ts.map +1 -0
- package/dist/test/rendering/render-output-diagnostics.test.js +82 -0
- package/dist/test/rendering/render-output-diagnostics.test.js.map +1 -0
- package/dist/test/runtime.test.d.ts +11 -0
- package/dist/test/runtime.test.d.ts.map +1 -0
- package/dist/test/runtime.test.js +385 -0
- package/dist/test/runtime.test.js.map +1 -0
- package/dist/test/stc.test.d.ts +1 -1
- package/dist/test/stc.test.d.ts.map +1 -1
- package/dist/test/stc.test.js +0 -1
- package/dist/test/stc.test.js.map +1 -1
- package/dist/test/tree-test-utils.d.ts +3 -0
- package/dist/test/tree-test-utils.d.ts.map +1 -0
- package/dist/test/tree-test-utils.js +16 -0
- package/dist/test/tree-test-utils.js.map +1 -0
- package/dist/test/utils.test.d.ts +1 -1
- package/dist/test/utils.test.d.ts.map +1 -1
- package/dist/test/utils.test.js +12 -11
- package/dist/test/utils.test.js.map +1 -1
- package/dist/test/vitest.setup.d.ts +2 -0
- package/dist/test/vitest.setup.d.ts.map +1 -0
- package/dist/test/vitest.setup.js +2 -0
- package/dist/test/vitest.setup.js.map +1 -0
- package/dist/testing/devtools-utils.d.ts.map +1 -1
- package/dist/testing/devtools-utils.js +1 -1
- package/dist/testing/devtools-utils.js.map +1 -1
- package/dist/testing/extend-expect.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +30 -34
- package/dist/testing/extend-expect.js.map +1 -1
- package/dist/testing/render.d.ts +7 -9
- package/dist/testing/render.d.ts.map +1 -1
- package/dist/testing/render.js +7 -17
- package/dist/testing/render.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/api/components/Output.md +0 -3
- package/docs/api/components/SourceFile.md +0 -3
- package/docs/api/functions/createComment.md +18 -0
- package/docs/api/functions/createElement.md +19 -0
- package/docs/api/functions/createFragment.md +17 -0
- package/docs/api/functions/createTextNode.md +18 -0
- package/docs/api/functions/emitDiagnosticForTree.md +19 -0
- package/docs/api/functions/ensureIsEmpty.md +1 -1
- package/docs/api/functions/getContextForNode.md +18 -0
- package/docs/api/functions/getContextForRenderNode.md +4 -4
- package/docs/api/functions/getDiagnosticsForTree.md +7 -5
- package/docs/api/functions/getRegisteredDiagnosticsForTree.md +18 -0
- package/docs/api/functions/index.md +17 -12
- package/docs/api/functions/isCustomContext.md +4 -4
- package/docs/api/functions/notifyContentState.md +6 -0
- package/docs/api/functions/printTree.md +6 -16
- package/docs/api/functions/registerDiagnosticsForTree.md +19 -0
- package/docs/api/functions/render.md +1 -2
- package/docs/api/functions/renderAsync.md +1 -2
- package/docs/api/functions/renderTree.md +8 -5
- package/docs/api/functions/reportDiagnosticsForTree.md +18 -0
- package/docs/api/functions/runInContext.md +28 -0
- package/docs/api/functions/sourceFilesForTree.md +6 -16
- package/docs/api/index.md +3 -3
- package/docs/api/testing/functions/index.md +1 -1
- package/docs/api/testing/functions/renderToString.md +1 -1
- package/docs/api/types/AlloyNode.md +22 -0
- package/docs/api/types/Child.md +1 -1
- package/docs/api/types/CommentNode.md +15 -0
- package/docs/api/types/Context.md +13 -15
- package/docs/api/types/ElementNode.md +18 -0
- package/docs/api/types/FragmentNode.md +12 -0
- package/docs/api/types/Insertable.md +7 -0
- package/docs/api/types/NodeType.md +5 -0
- package/docs/api/types/OutputDirectory.md +0 -50
- package/docs/api/types/PrintTreeOptions.md +0 -1
- package/docs/api/types/RenderTreeOptions.md +7 -0
- package/docs/api/types/StiComponentCreator.md +4 -4
- package/docs/api/types/StiSignature.md +1 -1
- package/docs/api/types/TextNode.md +16 -0
- package/docs/api/types/index.md +10 -28
- package/docs/api/variables/COMMENT_NODE.md +5 -0
- package/docs/api/variables/ELEMENT_NODE.md +11 -0
- package/docs/api/variables/FRAGMENT_NODE.md +5 -0
- package/docs/api/variables/TEXT_NODE.md +5 -0
- package/docs/api/variables/index.md +4 -2
- package/docs/formatting.md +1 -1
- package/docs/rendering.md +4 -4
- package/package.json +6 -6
- package/src/components/AccessExpression.test.tsx +5 -13
- package/src/components/Output.tsx +2 -1
- package/src/components/SourceFile.tsx +1 -1
- package/src/content-slot.test.tsx +8 -10
- package/src/context/format-options.ts +1 -1
- package/src/context.ts +37 -4
- package/src/debug/diagnostics.test.tsx +1 -1
- package/src/debug/effects.test.tsx +1 -1
- package/src/debug/file-streaming.ts +115 -0
- package/src/debug/files.test.tsx +15 -11
- package/src/debug/index.ts +11 -11
- package/src/debug/message-format.test.tsx +32 -19
- package/src/debug/render-tree-orphans.test.tsx +10 -19
- package/src/debug/render.test.tsx +206 -78
- package/src/debug/render.ts +642 -495
- package/src/debug/trace-writer.ts +168 -14
- package/src/debug/trace.ts +0 -20
- package/src/devtools/devtools-protocol.ts +43 -0
- package/src/devtools/devtools-server.ts +57 -32
- package/src/devtools-entry.browser.ts +5 -0
- package/src/devtools-entry.ts +5 -0
- package/src/diagnostics.ts +31 -0
- package/src/index.ts +66 -2
- package/src/jsx-runtime.ts +16 -14
- package/src/output-types.ts +47 -0
- package/src/reactivity.ts +186 -40
- package/src/render/get-string-width.ts +201 -0
- package/src/render/index.ts +1 -0
- package/src/render/node-context.ts +14 -0
- package/src/render/node.ts +442 -0
- package/src/render/printer-support.ts +209 -0
- package/src/render/printer.ts +817 -0
- package/src/render-error.ts +98 -0
- package/src/render-output.ts +243 -0
- package/src/runtime/component.ts +2 -2
- package/src/runtime/create-intrinsic.ts +56 -0
- package/src/runtime/fragment.ts +22 -0
- package/src/runtime/index.ts +12 -0
- package/src/runtime/insert.ts +569 -0
- package/src/runtime/intrinsic.ts +14 -70
- package/src/scheduler.ts +40 -25
- package/src/stc.ts +3 -0
- package/src/sti.ts +17 -20
- package/src/symbols/symbol-slot.test.tsx +5 -5
- package/src/test-render.ts +103 -0
- package/src/utils.tsx +55 -37
- package/src/write-output.ts +1 -1
- package/temp/api-testing.json +390 -14
- package/temp/api.json +4320 -4144
- package/test/babel-e2e.test.ts +224 -0
- package/test/children.test.tsx +4 -7
- package/test/components/append-file.test.tsx +0 -1
- package/test/components/block.test.tsx +4 -6
- package/test/components/copy-file.test.tsx +2 -2
- package/test/components/declaration.test.tsx +2 -2
- package/test/components/list.test.tsx +20 -29
- package/test/components/prose.test.tsx +0 -1
- package/test/components/reference-or-content.test.tsx +8 -9
- package/test/components/source-file.test.tsx +4 -4
- package/test/components/template-file.test.tsx +0 -1
- package/test/components/update-file.test.tsx +1 -2
- package/test/components/wrap.test.tsx +3 -5
- package/test/control-flow/for.test.tsx +39 -31
- package/test/control-flow/match.test.tsx +4 -6
- package/test/control-flow/show.test.tsx +3 -6
- package/test/lazy-isempty.test.tsx +17 -19
- package/test/name-policy.test.tsx +0 -1
- package/test/node.test.ts +90 -0
- package/test/output-e2e.test.ts +198 -0
- package/test/reactivity/circular-reactives.test.tsx +6 -6
- package/test/reactivity/cleanup.test.tsx +2 -3
- package/test/reactivity/ref-rendering.test.tsx +15 -15
- package/test/reactivity/test.test.tsx +14 -14
- package/test/rendering/basic.test.tsx +0 -1
- package/test/rendering/code.test.tsx +0 -1
- package/test/rendering/formatting.test.tsx +21 -29
- package/test/rendering/indent.test.tsx +0 -1
- package/test/rendering/memoization.test.tsx +7 -3
- package/test/rendering/print-render-stack.test.tsx +0 -1
- package/test/rendering/refkeys.test.tsx +0 -1
- package/test/rendering/render-output-diagnostics.test.tsx +120 -0
- package/test/runtime.test.ts +448 -0
- package/test/stc.test.tsx +0 -1
- package/test/tree-test-utils.ts +23 -0
- package/test/utils.test.tsx +10 -9
- package/test/vitest.setup.ts +1 -0
- package/testing/devtools-utils.ts +2 -0
- package/testing/extend-expect.ts +32 -47
- package/testing/render.ts +17 -21
- package/vitest.config.ts +3 -0
- package/dist/dev/src/print-hook.js +0 -10
- package/dist/dev/src/print-hook.js.map +0 -1
- package/dist/dev/src/render.js +0 -872
- package/dist/dev/src/render.js.map +0 -1
- package/dist/src/print-hook.d.ts +0 -14
- package/dist/src/print-hook.d.ts.map +0 -1
- package/dist/src/print-hook.js +0 -10
- package/dist/src/print-hook.js.map +0 -1
- package/dist/src/render.d.ts +0 -155
- package/dist/src/render.d.ts.map +0 -1
- package/dist/src/render.js +0 -872
- package/dist/src/render.js.map +0 -1
- package/docs/api/functions/createIntrinsic.md +0 -19
- package/docs/api/functions/createRenderTreeHook.md +0 -19
- package/docs/api/functions/getElementCache.md +0 -17
- package/docs/api/functions/isIntrinsicElement.md +0 -18
- package/docs/api/functions/isPrintHook.md +0 -18
- package/docs/api/types/AlignIntrinsicElement.md +0 -5
- package/docs/api/types/BrIntrinsicElement.md +0 -5
- package/docs/api/types/BreakParentIntrinsicElement.md +0 -5
- package/docs/api/types/DedentIntrinsicElement.md +0 -5
- package/docs/api/types/DedentToRootIntrinsicElement.md +0 -5
- package/docs/api/types/ElementCache.md +0 -5
- package/docs/api/types/ElementCacheKey.md +0 -5
- package/docs/api/types/FillIntrinsicElement.md +0 -5
- package/docs/api/types/GroupIntrinsicElement.md +0 -5
- package/docs/api/types/HardlineIntrinsicElement.md +0 -5
- package/docs/api/types/HbrIntrinsicElement.md +0 -5
- package/docs/api/types/IfBreakIntrinsicElement.md +0 -5
- package/docs/api/types/IndentIfBreakIntrinsicElement.md +0 -5
- package/docs/api/types/IndentIntrinsicElement.md +0 -5
- package/docs/api/types/IntrinsicElement.md +0 -5
- package/docs/api/types/IntrinsicElementBase.md +0 -9
- package/docs/api/types/LbrIntrinsicElement.md +0 -5
- package/docs/api/types/LineIntrinsicElement.md +0 -5
- package/docs/api/types/LineSuffixBoundaryIntrinsicElement.md +0 -5
- package/docs/api/types/LineSuffixIntrinsicElement.md +0 -5
- package/docs/api/types/LiterallineIntrinsicElement.md +0 -5
- package/docs/api/types/MarkAsRootIntrinsicElement.md +0 -5
- package/docs/api/types/PrintHook.md +0 -10
- package/docs/api/types/RenderedTextTree.md +0 -5
- package/docs/api/types/SbrIntrinsicElement.md +0 -5
- package/docs/api/types/SoftlineIntrinsicElement.md +0 -5
- package/docs/api/variables/intrinsicElementKey.md +0 -5
- package/docs/api/variables/printHookTag.md +0 -7
- package/src/print-hook.ts +0 -22
- package/src/render.ts +0 -1154
package/src/render.ts
DELETED
|
@@ -1,1154 +0,0 @@
|
|
|
1
|
-
import { isRef } from "@vue/reactivity";
|
|
2
|
-
import { Doc, doc } from "prettier";
|
|
3
|
-
import prettier from "prettier/doc.js";
|
|
4
|
-
import { useContext } from "./context.js";
|
|
5
|
-
import { SourceFileContext } from "./context/source-file.js";
|
|
6
|
-
import {
|
|
7
|
-
debug,
|
|
8
|
-
getRenderNodeId,
|
|
9
|
-
isDevtoolsConnected,
|
|
10
|
-
isDevtoolsEnabled,
|
|
11
|
-
type RenderTreeNodeInfo,
|
|
12
|
-
} from "./debug/index.js";
|
|
13
|
-
import {
|
|
14
|
-
beginTransaction,
|
|
15
|
-
closeTrace,
|
|
16
|
-
commitTransaction,
|
|
17
|
-
notifyDiagnosticsReport,
|
|
18
|
-
} from "./debug/trace-writer.js";
|
|
19
|
-
import { isTraceEnabled } from "./debug/trace.js";
|
|
20
|
-
import {
|
|
21
|
-
attachDiagnosticsCollector,
|
|
22
|
-
DiagnosticsCollector,
|
|
23
|
-
emitDiagnostic,
|
|
24
|
-
reportDiagnostics,
|
|
25
|
-
} from "./diagnostics.js";
|
|
26
|
-
import {
|
|
27
|
-
isPrintHook,
|
|
28
|
-
printHookTag,
|
|
29
|
-
type PrintHook,
|
|
30
|
-
type RenderedTextTree,
|
|
31
|
-
} from "./print-hook.js";
|
|
32
|
-
import {
|
|
33
|
-
Context,
|
|
34
|
-
CustomContext,
|
|
35
|
-
effect,
|
|
36
|
-
getContext,
|
|
37
|
-
getElementCache,
|
|
38
|
-
isCustomContext,
|
|
39
|
-
onCleanup,
|
|
40
|
-
ref,
|
|
41
|
-
root,
|
|
42
|
-
untrack,
|
|
43
|
-
} from "./reactivity.js";
|
|
44
|
-
import { isRefkeyable, toRefkey } from "./refkey.js";
|
|
45
|
-
import {
|
|
46
|
-
getRenderStackSnapshot,
|
|
47
|
-
popStack,
|
|
48
|
-
printRenderStack,
|
|
49
|
-
pushStack,
|
|
50
|
-
} from "./render-stack.js";
|
|
51
|
-
import {
|
|
52
|
-
Child,
|
|
53
|
-
Children,
|
|
54
|
-
isComponentCreator,
|
|
55
|
-
isRenderableObject,
|
|
56
|
-
RENDERABLE,
|
|
57
|
-
} from "./runtime/component.js";
|
|
58
|
-
import { IntrinsicElement, isIntrinsicElement } from "./runtime/intrinsic.js";
|
|
59
|
-
import { flushJobs, flushJobsAsync, waitForSignal } from "./scheduler.js";
|
|
60
|
-
|
|
61
|
-
const notifiedErrors = new WeakSet<object>();
|
|
62
|
-
|
|
63
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
64
|
-
// Deferred file printing: mark files dirty during render, print once at end
|
|
65
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
66
|
-
interface DirtyFileEntry {
|
|
67
|
-
renderNode: RenderedTextTree;
|
|
68
|
-
printOptions: {
|
|
69
|
-
printWidth?: number;
|
|
70
|
-
tabWidth?: number;
|
|
71
|
-
useTabs?: boolean;
|
|
72
|
-
insertFinalNewLine?: boolean;
|
|
73
|
-
};
|
|
74
|
-
path: string;
|
|
75
|
-
filetype: string;
|
|
76
|
-
}
|
|
77
|
-
const dirtyFiles = new Map<string, DirtyFileEntry>();
|
|
78
|
-
const lastFlushTimeByFile = new Map<string, number>();
|
|
79
|
-
const DEVTOOLS_FLUSH_INTERVAL_MS = 1000;
|
|
80
|
-
|
|
81
|
-
function flushDirtyFile(path: string): void {
|
|
82
|
-
const entry = dirtyFiles.get(path);
|
|
83
|
-
if (!entry) return;
|
|
84
|
-
dirtyFiles.delete(path);
|
|
85
|
-
const contents = printTree(entry.renderNode, {
|
|
86
|
-
...entry.printOptions,
|
|
87
|
-
insertFinalNewLine: entry.printOptions.insertFinalNewLine ?? true,
|
|
88
|
-
noFlush: true,
|
|
89
|
-
});
|
|
90
|
-
debug.files.updated({ path: entry.path, filetype: entry.filetype, contents });
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function flushDirtyFiles(): void {
|
|
94
|
-
for (const path of [...dirtyFiles.keys()]) {
|
|
95
|
-
flushDirtyFile(path);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let lastRenderError: {
|
|
100
|
-
error: { name: string; message: string; stack?: string };
|
|
101
|
-
componentStack: Array<{
|
|
102
|
-
name: string;
|
|
103
|
-
props?: Record<string, unknown> | undefined;
|
|
104
|
-
propsSerialized?: string;
|
|
105
|
-
renderNodeId?: number;
|
|
106
|
-
source?: RenderTreeNodeInfo["source"];
|
|
107
|
-
}>;
|
|
108
|
-
} | null = null;
|
|
109
|
-
|
|
110
|
-
function normalizeRenderError(error: unknown): {
|
|
111
|
-
name: string;
|
|
112
|
-
message: string;
|
|
113
|
-
stack?: string;
|
|
114
|
-
} {
|
|
115
|
-
if (error instanceof Error) {
|
|
116
|
-
return {
|
|
117
|
-
name: error.name || error.constructor?.name || "Error",
|
|
118
|
-
message: error.message || "",
|
|
119
|
-
stack: error.stack,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
if (error && typeof error === "object") {
|
|
123
|
-
const anyError = error as {
|
|
124
|
-
name?: string;
|
|
125
|
-
message?: string;
|
|
126
|
-
stack?: string;
|
|
127
|
-
};
|
|
128
|
-
return {
|
|
129
|
-
name: anyError.name || "Error",
|
|
130
|
-
message: anyError.message || String(error),
|
|
131
|
-
stack: anyError.stack,
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return {
|
|
135
|
-
name: "Error",
|
|
136
|
-
message: String(error),
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
function notifyRenderError(error: unknown) {
|
|
141
|
-
if (error && typeof error === "object") {
|
|
142
|
-
if (notifiedErrors.has(error)) return;
|
|
143
|
-
notifiedErrors.add(error);
|
|
144
|
-
}
|
|
145
|
-
if (lastRenderError) return;
|
|
146
|
-
|
|
147
|
-
const { name, message, stack } = normalizeRenderError(error);
|
|
148
|
-
const componentStack = getRenderStackSnapshot().map((entry) => {
|
|
149
|
-
const renderNode = entry.context?.meta?.renderNode as
|
|
150
|
-
| RenderedTextTree
|
|
151
|
-
| undefined;
|
|
152
|
-
const renderNodeId = renderNode ? getRenderNodeId(renderNode) : undefined;
|
|
153
|
-
return {
|
|
154
|
-
name: entry.displayName,
|
|
155
|
-
props: entry.props as Record<string, unknown> | undefined,
|
|
156
|
-
renderNodeId,
|
|
157
|
-
source: entry.source,
|
|
158
|
-
};
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Output to console
|
|
162
|
-
printRenderStack(error);
|
|
163
|
-
|
|
164
|
-
// Send to devtools if enabled
|
|
165
|
-
debug.render.error({ name, message, stack }, componentStack);
|
|
166
|
-
|
|
167
|
-
// Store for diagnostics
|
|
168
|
-
lastRenderError = { error: { name, message, stack }, componentStack };
|
|
169
|
-
const lastEntry = componentStack.at(-1);
|
|
170
|
-
emitDiagnostic({
|
|
171
|
-
severity: "error",
|
|
172
|
-
message: `${name}: ${message}`,
|
|
173
|
-
source: lastEntry?.source,
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
function reportLastRenderError() {
|
|
178
|
-
// Error already reported in notifyRenderError via debug.renderError
|
|
179
|
-
lastRenderError = null;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
const {
|
|
183
|
-
builders: {
|
|
184
|
-
align,
|
|
185
|
-
breakParent,
|
|
186
|
-
dedent,
|
|
187
|
-
dedentToRoot,
|
|
188
|
-
fill,
|
|
189
|
-
group,
|
|
190
|
-
hardline,
|
|
191
|
-
indent,
|
|
192
|
-
indentIfBreak,
|
|
193
|
-
line,
|
|
194
|
-
lineSuffix,
|
|
195
|
-
lineSuffixBoundary,
|
|
196
|
-
literalline,
|
|
197
|
-
markAsRoot,
|
|
198
|
-
softline,
|
|
199
|
-
ifBreak,
|
|
200
|
-
},
|
|
201
|
-
} = prettier;
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Turning components into source text involves three different trees produced
|
|
205
|
-
* sequentially:
|
|
206
|
-
*
|
|
207
|
-
* 1. Component tree, built by the nesting of components
|
|
208
|
-
* 2. Rendered text tree, produced by *rendering* the component tree
|
|
209
|
-
* 3. Document tree, produced by *printing* the rendered text tree
|
|
210
|
-
*
|
|
211
|
-
* Finally, the document tree is converted to text via `prettier`. Let's look at
|
|
212
|
-
* each of these trees and the conversions in detail.
|
|
213
|
-
*
|
|
214
|
-
* # Component tree
|
|
215
|
-
*
|
|
216
|
-
* The component tree is built by JSX or STC templates. The nodes in this tree
|
|
217
|
-
* are defined by the type `Child` and are one of the following
|
|
218
|
-
*
|
|
219
|
-
* ## Primitive values
|
|
220
|
-
*
|
|
221
|
-
* Strings in the tree are placed into the rendered text tree as-is. Numbers are
|
|
222
|
-
* converted to strings. Falsy primitive values and booleans are converted to
|
|
223
|
-
* empty strings (and may cause a line break to be ignored, see below).
|
|
224
|
-
*
|
|
225
|
-
* ## Nullary functions
|
|
226
|
-
*
|
|
227
|
-
* Nullary functions represent computed or reactive values in the component
|
|
228
|
-
* tree, such as expressions placed into a JSX template with curly brackets.
|
|
229
|
-
* Nullary functions return `Children` which are then recursively rendered.
|
|
230
|
-
* Nullary functions are invoked in an effect which will update the rendered
|
|
231
|
-
* text tree when any reactive dependencies change.
|
|
232
|
-
*
|
|
233
|
-
* ## Component creators
|
|
234
|
-
*
|
|
235
|
-
* Component creators are a special kind of nullary function which instantiate
|
|
236
|
-
* components in order to get their children which are then recursively
|
|
237
|
-
* rendered. Component creators have some special rendering behavior, such as
|
|
238
|
-
* tracking the stack of rendered components. Like other nullary functions,
|
|
239
|
-
* component creators are invoked in an effect which will update the rendered
|
|
240
|
-
* text tree when any reactive dependencies change.
|
|
241
|
-
*
|
|
242
|
-
* ## Refs
|
|
243
|
-
*
|
|
244
|
-
* Refs are wrapped in a nullary function and rendered in an effect which will
|
|
245
|
-
* update the rendered text tree when the ref's value changes. This is
|
|
246
|
-
* essentially a syntactic convenience, allowing JSX templates to contain
|
|
247
|
-
* `\{ someRef \}` instead of `\{ someRef.value \}`.
|
|
248
|
-
*
|
|
249
|
-
* ## Refkey
|
|
250
|
-
*
|
|
251
|
-
* Refkeys are replaced with a component creator for the Reference component
|
|
252
|
-
* associated with the current source file. This allows creating references by
|
|
253
|
-
* placing them directly in the component tree e.g. `{ someRefkey }`.
|
|
254
|
-
*
|
|
255
|
-
* ## CustomContext
|
|
256
|
-
*
|
|
257
|
-
* CustomContext is a special kind of component which allows rendering children
|
|
258
|
-
* within a custom reactive context. This enables components to manually manage
|
|
259
|
-
* the lifetime of their reactive contexts.
|
|
260
|
-
*
|
|
261
|
-
* ## IntrinsicElement
|
|
262
|
-
*
|
|
263
|
-
* Various intrinsic elements exist to control formatting. These elements
|
|
264
|
-
* provide Print Hooks that are called during Printing.
|
|
265
|
-
*
|
|
266
|
-
* # Rendered Text Tree
|
|
267
|
-
*
|
|
268
|
-
* This tree is a nested array structure containing the rendered output of all
|
|
269
|
-
* the components in the component tree. This structure is updated reactively
|
|
270
|
-
* when reactive dependencies change. The nodes in this tree are predominantly
|
|
271
|
-
* strings, but can also be Print Hooks.
|
|
272
|
-
*
|
|
273
|
-
* This tree is built by the `renderTree` function.
|
|
274
|
-
*
|
|
275
|
-
* # Document Tree
|
|
276
|
-
*
|
|
277
|
-
* This tree is constructed by calling `printTree` on the rendered text tree.
|
|
278
|
-
* The rendered text tree is walked and the appropriate Prettier builders are
|
|
279
|
-
* called to produce a document tree. The result is then passed to Prettier's
|
|
280
|
-
* `printDocToString` function to produce the final source text.
|
|
281
|
-
*/
|
|
282
|
-
|
|
283
|
-
export interface OutputDirectory {
|
|
284
|
-
kind: "directory";
|
|
285
|
-
/** Full path from the output root, e.g. `"generated-client/src"`. Do not prepend parent directory paths when walking the tree. */
|
|
286
|
-
path: string;
|
|
287
|
-
contents: (OutputDirectory | OutputFile)[];
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export interface OutputFileBase {
|
|
291
|
-
kind: "file";
|
|
292
|
-
/** Full path from the output root, e.g. `"generated-client/src/models.ext"`. Do not prepend parent directory paths when walking the tree. */
|
|
293
|
-
path: string;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
export interface CopyOutputFile extends OutputFileBase {
|
|
297
|
-
sourcePath: string;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export interface ContentOutputFile extends OutputFileBase {
|
|
301
|
-
contents: string;
|
|
302
|
-
filetype: string;
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
export type OutputFile = ContentOutputFile | CopyOutputFile;
|
|
306
|
-
|
|
307
|
-
const nodesToContext = new WeakMap<RenderedTextTree, Context>();
|
|
308
|
-
const diagnosticsByTree = new WeakMap<RenderedTextTree, DiagnosticsCollector>();
|
|
309
|
-
|
|
310
|
-
export function getContextForRenderNode(node: RenderedTextTree) {
|
|
311
|
-
return nodesToContext.get(node);
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export function getDiagnosticsForTree(tree: RenderedTextTree) {
|
|
315
|
-
return diagnosticsByTree.get(tree)?.getDiagnostics() ?? [];
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function reportDiagnosticsForTree(tree: RenderedTextTree) {
|
|
319
|
-
const diagnostics = diagnosticsByTree.get(tree);
|
|
320
|
-
if (!diagnostics) return;
|
|
321
|
-
const entries = diagnostics.getDiagnostics();
|
|
322
|
-
if (entries.length === 0) return;
|
|
323
|
-
reportDiagnostics(diagnostics);
|
|
324
|
-
notifyDiagnosticsReport(entries);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
// Re-export from print-hook.ts to maintain backwards compatibility
|
|
328
|
-
export {
|
|
329
|
-
isPrintHook,
|
|
330
|
-
printHookTag,
|
|
331
|
-
type PrintHook,
|
|
332
|
-
type RenderedTextTree,
|
|
333
|
-
} from "./print-hook.js";
|
|
334
|
-
|
|
335
|
-
export function createRenderTreeHook(
|
|
336
|
-
subtree: RenderedTextTree,
|
|
337
|
-
hooks: Omit<PrintHook, typeof printHookTag | "subtree">,
|
|
338
|
-
): PrintHook {
|
|
339
|
-
return {
|
|
340
|
-
[printHookTag]: true,
|
|
341
|
-
subtree,
|
|
342
|
-
...hooks,
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Render a component tree to source directories and files. Will ensure that
|
|
348
|
-
* all non-async scheduled jobs are completed before returning. If async jobs
|
|
349
|
-
* are found, an error will be thrown. Use `renderAsync` when asynchronous
|
|
350
|
-
* jobs are expected.
|
|
351
|
-
*/
|
|
352
|
-
export function render(
|
|
353
|
-
children: Children,
|
|
354
|
-
options?: PrintTreeOptions,
|
|
355
|
-
): OutputDirectory {
|
|
356
|
-
const tree = renderTree(children);
|
|
357
|
-
flushJobs();
|
|
358
|
-
const output = sourceFilesForTree(tree, options);
|
|
359
|
-
flushDirtyFiles();
|
|
360
|
-
reportDiagnosticsForTree(tree);
|
|
361
|
-
reportLastRenderError();
|
|
362
|
-
debug.render.complete();
|
|
363
|
-
// Only close the trace DB when devtools is NOT running. When devtools is
|
|
364
|
-
// active the DB must remain open for post-render reactive updates.
|
|
365
|
-
if (isTraceEnabled() && !isDevtoolsEnabled()) closeTrace();
|
|
366
|
-
if (isDevtoolsEnabled()) {
|
|
367
|
-
void waitForSignal();
|
|
368
|
-
}
|
|
369
|
-
return output;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Render a component tree to source directories and files. Will ensure that all
|
|
374
|
-
* scheduled jobs are completed before returning.
|
|
375
|
-
*/
|
|
376
|
-
export async function renderAsync(
|
|
377
|
-
children: Children,
|
|
378
|
-
options?: PrintTreeOptions,
|
|
379
|
-
): Promise<OutputDirectory> {
|
|
380
|
-
await debug.prepare();
|
|
381
|
-
const tree = renderTree(children);
|
|
382
|
-
// Ensure all reactive updates are flushed before printing.
|
|
383
|
-
await flushJobsAsync();
|
|
384
|
-
const output = sourceFilesForTree(tree, options);
|
|
385
|
-
flushDirtyFiles();
|
|
386
|
-
reportDiagnosticsForTree(tree);
|
|
387
|
-
reportLastRenderError();
|
|
388
|
-
debug.render.complete();
|
|
389
|
-
// Only close the trace DB when devtools is NOT running. When devtools is
|
|
390
|
-
// active the DB must remain open for post-render reactive updates.
|
|
391
|
-
if (isTraceEnabled() && !isDevtoolsEnabled()) closeTrace();
|
|
392
|
-
|
|
393
|
-
return output;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Convert a rendered text tree to source directories and files. Will ensure
|
|
398
|
-
* that all scheduled jobs are completed before returning.
|
|
399
|
-
*/
|
|
400
|
-
export function sourceFilesForTree(
|
|
401
|
-
tree: RenderedTextTree,
|
|
402
|
-
options?: PrintTreeOptions,
|
|
403
|
-
): OutputDirectory {
|
|
404
|
-
let rootDirectory: OutputDirectory | undefined = undefined;
|
|
405
|
-
|
|
406
|
-
collectSourceFiles(undefined, tree);
|
|
407
|
-
|
|
408
|
-
if (!rootDirectory) {
|
|
409
|
-
emitDiagnostic({
|
|
410
|
-
severity: "error",
|
|
411
|
-
message:
|
|
412
|
-
"No root directory found. Make sure you are using the output component.",
|
|
413
|
-
});
|
|
414
|
-
return { kind: "directory", path: "", contents: [] };
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
return rootDirectory;
|
|
418
|
-
|
|
419
|
-
function collectSourceFiles(
|
|
420
|
-
currentDirectory: OutputDirectory | undefined,
|
|
421
|
-
root: RenderedTextTree,
|
|
422
|
-
) {
|
|
423
|
-
if (!Array.isArray(root)) {
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
const context = getContextForRenderNode(root);
|
|
427
|
-
|
|
428
|
-
if (!context) {
|
|
429
|
-
return recurse(currentDirectory);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
if (context.meta?.directory) {
|
|
433
|
-
const directory: OutputDirectory = {
|
|
434
|
-
kind: "directory",
|
|
435
|
-
path: context.meta?.directory.path,
|
|
436
|
-
contents: [],
|
|
437
|
-
};
|
|
438
|
-
|
|
439
|
-
if (currentDirectory) {
|
|
440
|
-
currentDirectory.contents.push(directory);
|
|
441
|
-
} else {
|
|
442
|
-
rootDirectory = directory;
|
|
443
|
-
}
|
|
444
|
-
recurse(directory);
|
|
445
|
-
} else if (context.meta?.sourceFile) {
|
|
446
|
-
if (!currentDirectory) {
|
|
447
|
-
// This shouldn't happen if you're using the Output component.
|
|
448
|
-
throw new Error(
|
|
449
|
-
"Source file doesn't have parent directory. Make sure you have used the Output component.",
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
const sourceFile: ContentOutputFile = {
|
|
454
|
-
kind: "file",
|
|
455
|
-
path: context.meta?.sourceFile.path,
|
|
456
|
-
filetype: context.meta?.sourceFile.filetype,
|
|
457
|
-
contents: printTree(root, {
|
|
458
|
-
printWidth:
|
|
459
|
-
options?.printWidth ?? context.meta?.printOptions?.printWidth,
|
|
460
|
-
tabWidth: options?.tabWidth ?? context.meta?.printOptions?.tabWidth,
|
|
461
|
-
useTabs: options?.useTabs ?? context.meta?.printOptions?.useTabs,
|
|
462
|
-
insertFinalNewLine:
|
|
463
|
-
options?.insertFinalNewLine ??
|
|
464
|
-
context.meta?.printOptions?.insertFinalNewLine ??
|
|
465
|
-
true,
|
|
466
|
-
}),
|
|
467
|
-
};
|
|
468
|
-
|
|
469
|
-
currentDirectory.contents.push(sourceFile);
|
|
470
|
-
} else if (context.meta?.copyFile) {
|
|
471
|
-
if (!currentDirectory) {
|
|
472
|
-
// This shouldn't happen if you're using the Output component.
|
|
473
|
-
throw new Error(
|
|
474
|
-
"Copy file doesn't have parent directory. Make sure you have used the Output component.",
|
|
475
|
-
);
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const sourceFile: CopyOutputFile = {
|
|
479
|
-
kind: "file",
|
|
480
|
-
path: context.meta?.copyFile.path,
|
|
481
|
-
sourcePath: context.meta?.copyFile.sourcePath,
|
|
482
|
-
};
|
|
483
|
-
|
|
484
|
-
currentDirectory.contents.push(sourceFile);
|
|
485
|
-
} else {
|
|
486
|
-
recurse(currentDirectory);
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
function recurse(cwd: OutputDirectory | undefined) {
|
|
490
|
-
for (const child of root) {
|
|
491
|
-
collectSourceFiles(cwd, child as RenderedTextTree);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
export function renderTree(children: Children) {
|
|
497
|
-
const rootElem: RenderedTextTree = [];
|
|
498
|
-
const diagnostics = new DiagnosticsCollector();
|
|
499
|
-
lastRenderError = null;
|
|
500
|
-
debug.effect.reset();
|
|
501
|
-
debug.symbols.reset();
|
|
502
|
-
debug.files.reset();
|
|
503
|
-
dirtyFiles.clear();
|
|
504
|
-
lastFlushTimeByFile.clear();
|
|
505
|
-
debug.render.initialize(rootElem);
|
|
506
|
-
if (isTraceEnabled()) beginTransaction();
|
|
507
|
-
try {
|
|
508
|
-
root(() => {
|
|
509
|
-
attachDiagnosticsCollector(diagnostics);
|
|
510
|
-
renderWorker(rootElem, children);
|
|
511
|
-
});
|
|
512
|
-
} catch (e) {
|
|
513
|
-
if (isTraceEnabled()) commitTransaction();
|
|
514
|
-
flushDirtyFiles();
|
|
515
|
-
notifyRenderError(e);
|
|
516
|
-
reportLastRenderError();
|
|
517
|
-
throw e;
|
|
518
|
-
}
|
|
519
|
-
if (isTraceEnabled()) commitTransaction();
|
|
520
|
-
|
|
521
|
-
diagnosticsByTree.set(rootElem, diagnostics);
|
|
522
|
-
|
|
523
|
-
return rootElem;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
function renderWorker(node: RenderedTextTree, children: Children) {
|
|
527
|
-
if (lastRenderError) return;
|
|
528
|
-
if (!getContext()) {
|
|
529
|
-
throw new Error(
|
|
530
|
-
"Cannot render without a context. Make sure you are using the Output component.",
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
if (Array.isArray(node)) {
|
|
535
|
-
nodesToContext.set(node, getContext()!);
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
if (Array.isArray(children)) {
|
|
539
|
-
for (const child of (children as any).flat(Infinity)) {
|
|
540
|
-
appendChild(node, child);
|
|
541
|
-
if (lastRenderError) break;
|
|
542
|
-
}
|
|
543
|
-
} else {
|
|
544
|
-
appendChild(node, children);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
function contentAdded() {
|
|
549
|
-
const context: Context = getContext()!;
|
|
550
|
-
context.childrenWithContent++;
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
export function notifyContentState() {
|
|
554
|
-
untrack(() => {
|
|
555
|
-
const startContext = getContext()!;
|
|
556
|
-
|
|
557
|
-
if (startContext.childrenWithContent === 0) {
|
|
558
|
-
if (startContext._lastEmpty) {
|
|
559
|
-
// it was already empty, no work to do.
|
|
560
|
-
return;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
startContext._lastEmpty = true;
|
|
564
|
-
if (startContext.isEmpty) {
|
|
565
|
-
startContext.isEmpty.value = true;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// otherwise we need to decrement the content counts up the tree.
|
|
569
|
-
let current = startContext.owner;
|
|
570
|
-
while (current) {
|
|
571
|
-
if (current.childrenWithContent === 0) {
|
|
572
|
-
break;
|
|
573
|
-
}
|
|
574
|
-
current.childrenWithContent--;
|
|
575
|
-
if (current.childrenWithContent > 0) {
|
|
576
|
-
// This isn't the last content so we have no work to do
|
|
577
|
-
break;
|
|
578
|
-
}
|
|
579
|
-
current._lastEmpty = true;
|
|
580
|
-
if (current.isEmpty) {
|
|
581
|
-
current.isEmpty.value = true;
|
|
582
|
-
}
|
|
583
|
-
current = current.owner;
|
|
584
|
-
}
|
|
585
|
-
} else {
|
|
586
|
-
if (!startContext._lastEmpty) {
|
|
587
|
-
// it was already non-empty, no work to do.
|
|
588
|
-
return;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
startContext._lastEmpty = false;
|
|
592
|
-
if (startContext.isEmpty) {
|
|
593
|
-
startContext.isEmpty.value = false;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// otherwise we need to increment the content counts up the tree.
|
|
597
|
-
let current = startContext.owner;
|
|
598
|
-
while (current) {
|
|
599
|
-
current.childrenWithContent++;
|
|
600
|
-
if (current.childrenWithContent > 1) {
|
|
601
|
-
// This isn't the first content so we have no work to do
|
|
602
|
-
break;
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
current._lastEmpty = false;
|
|
606
|
-
if (current.isEmpty) {
|
|
607
|
-
current.isEmpty.value = false;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
current = current.owner;
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
function appendChild(node: RenderedTextTree, rawChild: Child) {
|
|
617
|
-
if (lastRenderError) return;
|
|
618
|
-
const child = normalizeChild(rawChild);
|
|
619
|
-
|
|
620
|
-
if (typeof child === "string") {
|
|
621
|
-
if (child !== "") {
|
|
622
|
-
contentAdded();
|
|
623
|
-
debug.render.appendTextNode(node, node.length, child);
|
|
624
|
-
}
|
|
625
|
-
node.push(child);
|
|
626
|
-
} else {
|
|
627
|
-
const cache = getElementCache();
|
|
628
|
-
if (cache.has(child as any)) {
|
|
629
|
-
const cachedNode = cache.get(child as any)!;
|
|
630
|
-
// recordSubtreeAdded detects cached nodes automatically and re-adds their children
|
|
631
|
-
if (isCustomContext(child)) {
|
|
632
|
-
debug.render.appendCustomContext(node, cachedNode);
|
|
633
|
-
} else {
|
|
634
|
-
debug.render.appendFragmentChild(node, cachedNode);
|
|
635
|
-
}
|
|
636
|
-
node.push(cachedNode);
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
if (isCustomContext(child)) {
|
|
640
|
-
const newNode: RenderedTextTree = [];
|
|
641
|
-
debug.render.appendCustomContext(node, newNode);
|
|
642
|
-
child.useCustomContext((children) => {
|
|
643
|
-
renderWorker(newNode, children);
|
|
644
|
-
node.push(newNode);
|
|
645
|
-
cache.set(child, newNode);
|
|
646
|
-
notifyContentState();
|
|
647
|
-
notifyFileUpdateForNode(node);
|
|
648
|
-
});
|
|
649
|
-
} else if (isIntrinsicElement(child)) {
|
|
650
|
-
// don't need a new context here because intrinsics are never reactive
|
|
651
|
-
const intrinsic = child as IntrinsicElement;
|
|
652
|
-
const newNode: RenderedTextTree = [];
|
|
653
|
-
|
|
654
|
-
function formatHookWithChildren(command: (doc: Doc) => Doc) {
|
|
655
|
-
const hook = createRenderTreeHook(newNode, {
|
|
656
|
-
print(tree, print) {
|
|
657
|
-
return command(print(tree));
|
|
658
|
-
},
|
|
659
|
-
});
|
|
660
|
-
debug.render.appendPrintHook(
|
|
661
|
-
node,
|
|
662
|
-
node.length,
|
|
663
|
-
hook,
|
|
664
|
-
intrinsic.name,
|
|
665
|
-
newNode,
|
|
666
|
-
);
|
|
667
|
-
node.push(hook);
|
|
668
|
-
renderWorker(newNode, (child as any).props.children);
|
|
669
|
-
notifyFileUpdateForNode(node);
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
function formatHook(command: Doc) {
|
|
673
|
-
const hook = createRenderTreeHook(newNode, {
|
|
674
|
-
print() {
|
|
675
|
-
return command;
|
|
676
|
-
},
|
|
677
|
-
});
|
|
678
|
-
debug.render.appendPrintHook(node, node.length, hook, intrinsic.name);
|
|
679
|
-
node.push(hook);
|
|
680
|
-
return hook;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
switch (child.name) {
|
|
684
|
-
case "indent":
|
|
685
|
-
return formatHookWithChildren(indent);
|
|
686
|
-
case "indentIfBreak":
|
|
687
|
-
{
|
|
688
|
-
const hook = createRenderTreeHook(newNode, {
|
|
689
|
-
print(tree, print) {
|
|
690
|
-
return indentIfBreak(print(tree), {
|
|
691
|
-
groupId: child.props.groupId,
|
|
692
|
-
negate: child.props.negate,
|
|
693
|
-
});
|
|
694
|
-
},
|
|
695
|
-
});
|
|
696
|
-
debug.render.appendPrintHook(
|
|
697
|
-
node,
|
|
698
|
-
node.length,
|
|
699
|
-
hook,
|
|
700
|
-
intrinsic.name,
|
|
701
|
-
newNode,
|
|
702
|
-
);
|
|
703
|
-
node.push(hook);
|
|
704
|
-
}
|
|
705
|
-
renderWorker(newNode, child.props.children);
|
|
706
|
-
notifyFileUpdateForNode(node);
|
|
707
|
-
return;
|
|
708
|
-
case "fill":
|
|
709
|
-
return formatHookWithChildren(fill as any);
|
|
710
|
-
case "group":
|
|
711
|
-
{
|
|
712
|
-
const hook = createRenderTreeHook(newNode, {
|
|
713
|
-
print(tree, print) {
|
|
714
|
-
return group(print(tree), {
|
|
715
|
-
id: child.props.id,
|
|
716
|
-
shouldBreak: child.props.shouldBreak,
|
|
717
|
-
});
|
|
718
|
-
},
|
|
719
|
-
});
|
|
720
|
-
debug.render.appendPrintHook(
|
|
721
|
-
node,
|
|
722
|
-
node.length,
|
|
723
|
-
hook,
|
|
724
|
-
intrinsic.name,
|
|
725
|
-
newNode,
|
|
726
|
-
);
|
|
727
|
-
node.push(hook);
|
|
728
|
-
}
|
|
729
|
-
renderWorker(newNode, child.props.children);
|
|
730
|
-
notifyFileUpdateForNode(node);
|
|
731
|
-
return;
|
|
732
|
-
case "line":
|
|
733
|
-
case "br":
|
|
734
|
-
return formatHook(line);
|
|
735
|
-
case "hbr":
|
|
736
|
-
case "hardline":
|
|
737
|
-
return formatHook(hardline);
|
|
738
|
-
case "sbr":
|
|
739
|
-
case "softline":
|
|
740
|
-
return formatHook(softline);
|
|
741
|
-
case "literalline":
|
|
742
|
-
case "lbr":
|
|
743
|
-
return formatHook(literalline);
|
|
744
|
-
case "align":
|
|
745
|
-
{
|
|
746
|
-
const hook = createRenderTreeHook(newNode, {
|
|
747
|
-
print(tree, print) {
|
|
748
|
-
return align(
|
|
749
|
-
(child.props as any).width ?? (child.props as any).string!,
|
|
750
|
-
print(tree),
|
|
751
|
-
);
|
|
752
|
-
},
|
|
753
|
-
});
|
|
754
|
-
debug.render.appendPrintHook(
|
|
755
|
-
node,
|
|
756
|
-
node.length,
|
|
757
|
-
hook,
|
|
758
|
-
intrinsic.name,
|
|
759
|
-
newNode,
|
|
760
|
-
);
|
|
761
|
-
node.push(hook);
|
|
762
|
-
}
|
|
763
|
-
renderWorker(newNode, (child as any).props.children);
|
|
764
|
-
notifyFileUpdateForNode(node);
|
|
765
|
-
return;
|
|
766
|
-
case "lineSuffix":
|
|
767
|
-
return formatHookWithChildren(lineSuffix);
|
|
768
|
-
case "lineSuffixBoundary":
|
|
769
|
-
return formatHook(lineSuffixBoundary);
|
|
770
|
-
case "breakParent":
|
|
771
|
-
return formatHook(breakParent);
|
|
772
|
-
case "dedent":
|
|
773
|
-
return formatHookWithChildren(dedent);
|
|
774
|
-
case "dedentToRoot":
|
|
775
|
-
return formatHookWithChildren(dedentToRoot);
|
|
776
|
-
case "markAsRoot":
|
|
777
|
-
return formatHookWithChildren(markAsRoot);
|
|
778
|
-
case "ifBreak":
|
|
779
|
-
{
|
|
780
|
-
const hook = createRenderTreeHook(newNode, {
|
|
781
|
-
print(tree, print) {
|
|
782
|
-
return ifBreak(
|
|
783
|
-
print((tree as RenderedTextTree[])[0]),
|
|
784
|
-
print((tree as RenderedTextTree[])[1]),
|
|
785
|
-
);
|
|
786
|
-
},
|
|
787
|
-
});
|
|
788
|
-
debug.render.appendPrintHook(
|
|
789
|
-
node,
|
|
790
|
-
node.length,
|
|
791
|
-
hook,
|
|
792
|
-
intrinsic.name,
|
|
793
|
-
newNode,
|
|
794
|
-
);
|
|
795
|
-
node.push(hook);
|
|
796
|
-
}
|
|
797
|
-
newNode.push([], []);
|
|
798
|
-
debug.render.appendFragmentChild(
|
|
799
|
-
newNode,
|
|
800
|
-
newNode[0] as RenderedTextTree,
|
|
801
|
-
);
|
|
802
|
-
debug.render.appendFragmentChild(
|
|
803
|
-
newNode,
|
|
804
|
-
newNode[1] as RenderedTextTree,
|
|
805
|
-
);
|
|
806
|
-
renderWorker(
|
|
807
|
-
newNode[0] as RenderedTextTree[],
|
|
808
|
-
(child as any).props.children,
|
|
809
|
-
);
|
|
810
|
-
renderWorker(
|
|
811
|
-
newNode[1] as RenderedTextTree[],
|
|
812
|
-
(child as any).props.flatContents,
|
|
813
|
-
);
|
|
814
|
-
notifyFileUpdateForNode(node);
|
|
815
|
-
return;
|
|
816
|
-
default:
|
|
817
|
-
throw new Error("Unknown intrinsic element");
|
|
818
|
-
}
|
|
819
|
-
} else if (isComponentCreator(child)) {
|
|
820
|
-
const index = node.length;
|
|
821
|
-
const rerenderToken =
|
|
822
|
-
isDevtoolsEnabled() ? ref(0, { isInfrastructure: true }) : undefined;
|
|
823
|
-
const breakNext =
|
|
824
|
-
isDevtoolsEnabled() ?
|
|
825
|
-
ref(false, { isInfrastructure: true })
|
|
826
|
-
: undefined;
|
|
827
|
-
// todo: remove this effect (only needed for context, not needed for anything else)
|
|
828
|
-
effect(
|
|
829
|
-
() => {
|
|
830
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
831
|
-
rerenderToken?.value;
|
|
832
|
-
const context = getContext();
|
|
833
|
-
context!.childrenWithContent = 0;
|
|
834
|
-
|
|
835
|
-
if (context) context.componentOwner = child;
|
|
836
|
-
const existing = node[index];
|
|
837
|
-
const componentRoot: RenderedTextTree =
|
|
838
|
-
Array.isArray(existing) ? existing : [];
|
|
839
|
-
context!.meta ??= {};
|
|
840
|
-
context!.meta.renderNode = componentRoot;
|
|
841
|
-
const propsSource = (child.props ?? undefined) as
|
|
842
|
-
| Record<string, unknown>
|
|
843
|
-
| undefined;
|
|
844
|
-
const debugSession = debug.render.beginComponent({
|
|
845
|
-
parent: node,
|
|
846
|
-
index,
|
|
847
|
-
node: componentRoot,
|
|
848
|
-
component: child,
|
|
849
|
-
propsSource,
|
|
850
|
-
source: child.source,
|
|
851
|
-
isExisting: Array.isArray(existing),
|
|
852
|
-
actions: {
|
|
853
|
-
rerender:
|
|
854
|
-
rerenderToken ?
|
|
855
|
-
() => {
|
|
856
|
-
lastRenderError = null;
|
|
857
|
-
rerenderToken.value++;
|
|
858
|
-
}
|
|
859
|
-
: () => {},
|
|
860
|
-
rerenderAndBreak:
|
|
861
|
-
breakNext && rerenderToken ?
|
|
862
|
-
() => {
|
|
863
|
-
lastRenderError = null;
|
|
864
|
-
breakNext.value = true;
|
|
865
|
-
rerenderToken.value++;
|
|
866
|
-
}
|
|
867
|
-
: () => {},
|
|
868
|
-
},
|
|
869
|
-
});
|
|
870
|
-
if (Array.isArray(existing)) {
|
|
871
|
-
componentRoot.length = 0;
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
pushStack(child.component, child.props, child.source);
|
|
875
|
-
let renderFailed = false;
|
|
876
|
-
let childResult: Children | undefined;
|
|
877
|
-
try {
|
|
878
|
-
childResult = untrack(() => {
|
|
879
|
-
const shouldBreak = breakNext?.value ?? false;
|
|
880
|
-
if (shouldBreak) {
|
|
881
|
-
breakNext!.value = false;
|
|
882
|
-
// eslint-disable-next-line no-debugger
|
|
883
|
-
debugger;
|
|
884
|
-
}
|
|
885
|
-
return child();
|
|
886
|
-
});
|
|
887
|
-
} catch (error) {
|
|
888
|
-
notifyRenderError(error);
|
|
889
|
-
renderFailed = true;
|
|
890
|
-
throw error;
|
|
891
|
-
}
|
|
892
|
-
try {
|
|
893
|
-
if (context?.meta?.directory) {
|
|
894
|
-
debugSession.recordDirectory(context.meta.directory.path);
|
|
895
|
-
}
|
|
896
|
-
if (context?.meta?.sourceFile) {
|
|
897
|
-
context.meta.renderNode = componentRoot;
|
|
898
|
-
debugSession.recordFile(
|
|
899
|
-
context.meta.sourceFile.path,
|
|
900
|
-
context.meta.sourceFile.filetype,
|
|
901
|
-
);
|
|
902
|
-
context.meta.sourceFileReady = false;
|
|
903
|
-
}
|
|
904
|
-
if (!renderFailed) {
|
|
905
|
-
renderWorker(componentRoot, childResult);
|
|
906
|
-
}
|
|
907
|
-
} finally {
|
|
908
|
-
popStack();
|
|
909
|
-
}
|
|
910
|
-
if (renderFailed) {
|
|
911
|
-
node[index] = componentRoot;
|
|
912
|
-
cache.set(child, componentRoot);
|
|
913
|
-
notifyFileUpdateForNode(node);
|
|
914
|
-
notifyContentState();
|
|
915
|
-
onCleanup(() => debugSession.dispose());
|
|
916
|
-
return;
|
|
917
|
-
}
|
|
918
|
-
if (context?.meta?.sourceFile) {
|
|
919
|
-
context.meta.sourceFileReady = true;
|
|
920
|
-
notifyFileUpdateForNode(componentRoot);
|
|
921
|
-
}
|
|
922
|
-
node[index] = componentRoot;
|
|
923
|
-
cache.set(child, componentRoot);
|
|
924
|
-
notifyContentState();
|
|
925
|
-
onCleanup(() => debugSession.dispose());
|
|
926
|
-
},
|
|
927
|
-
undefined,
|
|
928
|
-
{
|
|
929
|
-
debug: {
|
|
930
|
-
name: `render:${child.component.name || "Anonymous"}`,
|
|
931
|
-
type: "render",
|
|
932
|
-
},
|
|
933
|
-
},
|
|
934
|
-
);
|
|
935
|
-
} else if (typeof child === "function") {
|
|
936
|
-
const index = node.length;
|
|
937
|
-
effect(
|
|
938
|
-
() => {
|
|
939
|
-
let res: Child | Children | undefined;
|
|
940
|
-
let renderFailed = false;
|
|
941
|
-
try {
|
|
942
|
-
res = child();
|
|
943
|
-
while (typeof res === "function" && !isComponentCreator(res)) {
|
|
944
|
-
res = res();
|
|
945
|
-
}
|
|
946
|
-
} catch (error) {
|
|
947
|
-
notifyRenderError(error);
|
|
948
|
-
renderFailed = true;
|
|
949
|
-
throw error;
|
|
950
|
-
}
|
|
951
|
-
const context = getContext();
|
|
952
|
-
context!.childrenWithContent = 0;
|
|
953
|
-
|
|
954
|
-
const existing = node[index];
|
|
955
|
-
const memoNode: RenderedTextTree =
|
|
956
|
-
Array.isArray(existing) ? existing : [];
|
|
957
|
-
|
|
958
|
-
debug.render.prepareMemoNode(node, memoNode, Array.isArray(existing));
|
|
959
|
-
if (Array.isArray(existing)) {
|
|
960
|
-
memoNode.length = 0;
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
if (!renderFailed) {
|
|
964
|
-
renderWorker(memoNode, res);
|
|
965
|
-
}
|
|
966
|
-
node[index] = memoNode;
|
|
967
|
-
cache.set(child, memoNode);
|
|
968
|
-
notifyFileUpdateForNode(node);
|
|
969
|
-
notifyContentState();
|
|
970
|
-
return memoNode;
|
|
971
|
-
},
|
|
972
|
-
undefined,
|
|
973
|
-
{
|
|
974
|
-
debug: {
|
|
975
|
-
name: `render:memo:${child.name || "anonymous"}`,
|
|
976
|
-
type: "render",
|
|
977
|
-
},
|
|
978
|
-
},
|
|
979
|
-
);
|
|
980
|
-
} else {
|
|
981
|
-
throw new Error("Unexpected child type");
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
}
|
|
985
|
-
|
|
986
|
-
function findSourceFileContext(node: RenderedTextTree) {
|
|
987
|
-
let context: Context | null | undefined =
|
|
988
|
-
getContextForRenderNode(node) ?? null;
|
|
989
|
-
while (context) {
|
|
990
|
-
if (context.meta?.sourceFile) return context;
|
|
991
|
-
context = context.owner;
|
|
992
|
-
}
|
|
993
|
-
return undefined;
|
|
994
|
-
}
|
|
995
|
-
|
|
996
|
-
function notifyFileUpdateForNode(node: RenderedTextTree) {
|
|
997
|
-
// Only track when devtools or trace are actually enabled
|
|
998
|
-
if (!isDevtoolsEnabled() && !isTraceEnabled()) return;
|
|
999
|
-
const context = findSourceFileContext(node);
|
|
1000
|
-
if (!context?.meta?.sourceFile) return;
|
|
1001
|
-
if (context.meta.sourceFileReady === false) return;
|
|
1002
|
-
const sourceFile = context.meta.sourceFile;
|
|
1003
|
-
const renderNode: RenderedTextTree =
|
|
1004
|
-
(context.meta.renderNode as RenderedTextTree | undefined) ?? node;
|
|
1005
|
-
|
|
1006
|
-
// Mark this file as dirty — defer the expensive printTree to end of render
|
|
1007
|
-
dirtyFiles.set(sourceFile.path, {
|
|
1008
|
-
renderNode,
|
|
1009
|
-
printOptions: {
|
|
1010
|
-
printWidth: context.meta?.printOptions?.printWidth,
|
|
1011
|
-
tabWidth: context.meta?.printOptions?.tabWidth,
|
|
1012
|
-
useTabs: context.meta?.printOptions?.useTabs,
|
|
1013
|
-
insertFinalNewLine: context.meta?.printOptions?.insertFinalNewLine,
|
|
1014
|
-
},
|
|
1015
|
-
path: sourceFile.path,
|
|
1016
|
-
filetype: sourceFile.filetype,
|
|
1017
|
-
});
|
|
1018
|
-
|
|
1019
|
-
// When a devtools client is connected, throttle file flushing to ~1s per file
|
|
1020
|
-
// so the user can watch content build up during rendering.
|
|
1021
|
-
if (isDevtoolsConnected()) {
|
|
1022
|
-
const now = Date.now();
|
|
1023
|
-
const lastFlush = lastFlushTimeByFile.get(sourceFile.path) ?? 0;
|
|
1024
|
-
if (now - lastFlush >= DEVTOOLS_FLUSH_INTERVAL_MS) {
|
|
1025
|
-
lastFlushTimeByFile.set(sourceFile.path, now);
|
|
1026
|
-
flushDirtyFile(sourceFile.path);
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
type NormalizedChildren = NormalizedChild | NormalizedChildren[];
|
|
1032
|
-
type NormalizedChild =
|
|
1033
|
-
| string
|
|
1034
|
-
| (() => Child | Children)
|
|
1035
|
-
| CustomContext
|
|
1036
|
-
| IntrinsicElement;
|
|
1037
|
-
|
|
1038
|
-
function normalizeChild(child: Child): NormalizedChildren {
|
|
1039
|
-
if (Array.isArray(child)) {
|
|
1040
|
-
return child.map(normalizeChild);
|
|
1041
|
-
} else if (typeof child === "string" || typeof child === "function") {
|
|
1042
|
-
return child as NormalizedChild;
|
|
1043
|
-
} else if (
|
|
1044
|
-
typeof child === "undefined" ||
|
|
1045
|
-
child === null ||
|
|
1046
|
-
typeof child === "boolean"
|
|
1047
|
-
) {
|
|
1048
|
-
return "";
|
|
1049
|
-
} else if (isRef(child)) {
|
|
1050
|
-
return () => child.value as () => Child;
|
|
1051
|
-
} else if (isRefkeyable(child)) {
|
|
1052
|
-
const refkey = toRefkey(child);
|
|
1053
|
-
return () => {
|
|
1054
|
-
const sfContext = useContext(SourceFileContext);
|
|
1055
|
-
if (!sfContext || !sfContext.reference) {
|
|
1056
|
-
throw new Error("Can only emit references inside of source files");
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
return sfContext.reference({ refkey });
|
|
1060
|
-
};
|
|
1061
|
-
} else if (isRenderableObject(child)) {
|
|
1062
|
-
// For custom renderable objects, we will just normalize them to a bound function.
|
|
1063
|
-
return child[RENDERABLE].bind(child);
|
|
1064
|
-
} else if (isCustomContext(child)) {
|
|
1065
|
-
return child;
|
|
1066
|
-
} else if (isIntrinsicElement(child)) {
|
|
1067
|
-
return child;
|
|
1068
|
-
} else {
|
|
1069
|
-
return String(child);
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
export interface PrintTreeOptions {
|
|
1074
|
-
/**
|
|
1075
|
-
* The number of characters the printer will wrap on. Defaults to 100
|
|
1076
|
-
* characters.
|
|
1077
|
-
*/
|
|
1078
|
-
printWidth?: number;
|
|
1079
|
-
|
|
1080
|
-
/**
|
|
1081
|
-
* Whether to use tabs instead of spaces for indentation. Defaults to false.
|
|
1082
|
-
*/
|
|
1083
|
-
useTabs?: boolean;
|
|
1084
|
-
|
|
1085
|
-
/**
|
|
1086
|
-
* The number of spaces to use for indentation. Defaults to 2 spaces.
|
|
1087
|
-
*/
|
|
1088
|
-
tabWidth?: number;
|
|
1089
|
-
|
|
1090
|
-
/**
|
|
1091
|
-
* If files should end with a final new line.
|
|
1092
|
-
* @default true
|
|
1093
|
-
*/
|
|
1094
|
-
insertFinalNewLine?: boolean;
|
|
1095
|
-
|
|
1096
|
-
/**
|
|
1097
|
-
* Skip flushing scheduled jobs before printing.
|
|
1098
|
-
* @default false
|
|
1099
|
-
*/
|
|
1100
|
-
noFlush?: boolean;
|
|
1101
|
-
}
|
|
1102
|
-
|
|
1103
|
-
const defaultPrintTreeOptions: PrintTreeOptions = {
|
|
1104
|
-
printWidth: 80,
|
|
1105
|
-
tabWidth: 2,
|
|
1106
|
-
};
|
|
1107
|
-
|
|
1108
|
-
/**
|
|
1109
|
-
* Convert a rendered text tree to a string. Will ensure that the scheduler is
|
|
1110
|
-
* empty before printing.
|
|
1111
|
-
*/
|
|
1112
|
-
export function printTree(tree: RenderedTextTree, options?: PrintTreeOptions) {
|
|
1113
|
-
options = {
|
|
1114
|
-
...defaultPrintTreeOptions,
|
|
1115
|
-
...Object.fromEntries(
|
|
1116
|
-
Object.entries(options ?? {}).filter(([_, v]) => v !== undefined),
|
|
1117
|
-
),
|
|
1118
|
-
};
|
|
1119
|
-
|
|
1120
|
-
if (!options.noFlush) {
|
|
1121
|
-
// make sure queue is empty
|
|
1122
|
-
flushJobs();
|
|
1123
|
-
}
|
|
1124
|
-
|
|
1125
|
-
const d = printTreeWorker(tree);
|
|
1126
|
-
const result = doc.printer.printDocToString(
|
|
1127
|
-
d,
|
|
1128
|
-
options as doc.printer.Options,
|
|
1129
|
-
).formatted;
|
|
1130
|
-
|
|
1131
|
-
return options.insertFinalNewLine && !result.endsWith("\n") ?
|
|
1132
|
-
`${result}\n`
|
|
1133
|
-
: result;
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
function printTreeWorker(tree: RenderedTextTree): Doc {
|
|
1137
|
-
const doc: Doc = [];
|
|
1138
|
-
for (const node of tree) {
|
|
1139
|
-
if (typeof node === "string") {
|
|
1140
|
-
const normalizedNode = node
|
|
1141
|
-
.split(/\r?\n/)
|
|
1142
|
-
.flatMap((line, index, array) =>
|
|
1143
|
-
index < array.length - 1 ? [line, hardline] : [line],
|
|
1144
|
-
);
|
|
1145
|
-
doc.push(normalizedNode);
|
|
1146
|
-
} else if (isPrintHook(node)) {
|
|
1147
|
-
doc.push(node.print!(node.subtree, printTreeWorker));
|
|
1148
|
-
} else {
|
|
1149
|
-
doc.push(printTreeWorker(node));
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
return doc;
|
|
1154
|
-
}
|