@react-x11/components 0.1.0 → 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/README.md +979 -21
- package/dist/ansi/cast.d.ts +48 -0
- package/dist/ansi/cast.d.ts.map +1 -0
- package/dist/ansi/cast.js +135 -0
- package/dist/ansi/cast.js.map +1 -0
- package/dist/ansi/index.d.ts +10 -0
- package/dist/ansi/index.d.ts.map +1 -0
- package/dist/ansi/index.js +27 -0
- package/dist/ansi/index.js.map +1 -0
- package/dist/ansi/palette.d.ts +79 -0
- package/dist/ansi/palette.d.ts.map +1 -0
- package/dist/ansi/palette.js +155 -0
- package/dist/ansi/palette.js.map +1 -0
- package/dist/ansi/parse.d.ts +114 -0
- package/dist/ansi/parse.d.ts.map +1 -0
- package/dist/ansi/parse.js +687 -0
- package/dist/ansi/parse.js.map +1 -0
- package/dist/ansi/sgr.d.ts +87 -0
- package/dist/ansi/sgr.d.ts.map +1 -0
- package/dist/ansi/sgr.js +302 -0
- package/dist/ansi/sgr.js.map +1 -0
- package/dist/ansi/utf8.d.ts +15 -0
- package/dist/ansi/utf8.d.ts.map +1 -0
- package/dist/ansi/utf8.js +82 -0
- package/dist/ansi/utf8.js.map +1 -0
- package/dist/calendar/Calendar.d.ts +136 -0
- package/dist/calendar/Calendar.d.ts.map +1 -0
- package/dist/calendar/Calendar.js +460 -0
- package/dist/calendar/Calendar.js.map +1 -0
- package/dist/calendar/DatePicker.d.ts +52 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/DatePicker.js +257 -0
- package/dist/calendar/DatePicker.js.map +1 -0
- package/dist/calendar/dates.d.ts +90 -0
- package/dist/calendar/dates.d.ts.map +1 -0
- package/dist/calendar/dates.js +236 -0
- package/dist/calendar/dates.js.map +1 -0
- package/dist/calendar/index.d.ts +8 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +15 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/charts/components.d.ts +141 -0
- package/dist/charts/components.d.ts.map +1 -0
- package/dist/charts/components.js +580 -0
- package/dist/charts/components.js.map +1 -0
- package/dist/charts/data.d.ts +198 -0
- package/dist/charts/data.d.ts.map +1 -0
- package/dist/charts/data.js +616 -0
- package/dist/charts/data.js.map +1 -0
- package/dist/charts/hx.d.ts +21 -0
- package/dist/charts/hx.d.ts.map +1 -0
- package/dist/charts/hx.js +15 -0
- package/dist/charts/hx.js.map +1 -0
- package/dist/charts/index.d.ts +27 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +38 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/node.d.ts +96 -0
- package/dist/charts/node.d.ts.map +1 -0
- package/dist/charts/node.js +720 -0
- package/dist/charts/node.js.map +1 -0
- package/dist/charts/render.d.ts +153 -0
- package/dist/charts/render.d.ts.map +1 -0
- package/dist/charts/render.js +762 -0
- package/dist/charts/render.js.map +1 -0
- package/dist/charts/scale.d.ts +42 -0
- package/dist/charts/scale.d.ts.map +1 -0
- package/dist/charts/scale.js +173 -0
- package/dist/charts/scale.js.map +1 -0
- package/dist/charts/spec.d.ts +91 -0
- package/dist/charts/spec.d.ts.map +1 -0
- package/dist/charts/spec.js +33 -0
- package/dist/charts/spec.js.map +1 -0
- package/dist/charts/timers.d.ts +6 -0
- package/dist/charts/timers.d.ts.map +1 -0
- package/dist/charts/timers.js +14 -0
- package/dist/charts/timers.js.map +1 -0
- package/dist/code/hx.d.ts +24 -0
- package/dist/code/hx.d.ts.map +1 -0
- package/dist/code/hx.js +25 -0
- package/dist/code/hx.js.map +1 -0
- package/dist/code/index.d.ts +45 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +93 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code-editor/completion.d.ts +26 -0
- package/dist/code-editor/completion.d.ts.map +1 -0
- package/dist/code-editor/completion.js +129 -0
- package/dist/code-editor/completion.js.map +1 -0
- package/dist/code-editor/doc.d.ts +35 -0
- package/dist/code-editor/doc.d.ts.map +1 -0
- package/dist/code-editor/doc.js +162 -0
- package/dist/code-editor/doc.js.map +1 -0
- package/dist/code-editor/hx.d.ts +13 -0
- package/dist/code-editor/hx.d.ts.map +1 -0
- package/dist/code-editor/hx.js +10 -0
- package/dist/code-editor/hx.js.map +1 -0
- package/dist/code-editor/index.d.ts +88 -0
- package/dist/code-editor/index.d.ts.map +1 -0
- package/dist/code-editor/index.js +401 -0
- package/dist/code-editor/index.js.map +1 -0
- package/dist/code-editor/node.d.ts +343 -0
- package/dist/code-editor/node.d.ts.map +1 -0
- package/dist/code-editor/node.js +1521 -0
- package/dist/code-editor/node.js.map +1 -0
- package/dist/code-language/hljs.d.ts +47 -0
- package/dist/code-language/hljs.d.ts.map +1 -0
- package/dist/code-language/hljs.js +211 -0
- package/dist/code-language/hljs.js.map +1 -0
- package/dist/code-language/index.d.ts +22 -0
- package/dist/code-language/index.d.ts.map +1 -0
- package/dist/code-language/index.js +20 -0
- package/dist/code-language/index.js.map +1 -0
- package/dist/code-language/languages/glsl.d.ts +4 -0
- package/dist/code-language/languages/glsl.d.ts.map +1 -0
- package/dist/code-language/languages/glsl.js +99 -0
- package/dist/code-language/languages/glsl.js.map +1 -0
- package/dist/code-language/languages/javascript.d.ts +10 -0
- package/dist/code-language/languages/javascript.d.ts.map +1 -0
- package/dist/code-language/languages/javascript.js +360 -0
- package/dist/code-language/languages/javascript.js.map +1 -0
- package/dist/code-language/languages/json.d.ts +4 -0
- package/dist/code-language/languages/json.d.ts.map +1 -0
- package/dist/code-language/languages/json.js +68 -0
- package/dist/code-language/languages/json.js.map +1 -0
- package/dist/code-language/languages/shell.d.ts +4 -0
- package/dist/code-language/languages/shell.d.ts.map +1 -0
- package/dist/code-language/languages/shell.js +189 -0
- package/dist/code-language/languages/shell.js.map +1 -0
- package/dist/code-language/languages/sql.d.ts +11 -0
- package/dist/code-language/languages/sql.d.ts.map +1 -0
- package/dist/code-language/languages/sql.js +133 -0
- package/dist/code-language/languages/sql.js.map +1 -0
- package/dist/code-language/lezer.d.ts +24 -0
- package/dist/code-language/lezer.d.ts.map +1 -0
- package/dist/code-language/lezer.js +148 -0
- package/dist/code-language/lezer.js.map +1 -0
- package/dist/code-language/registry.d.ts +19 -0
- package/dist/code-language/registry.d.ts.map +1 -0
- package/dist/code-language/registry.js +56 -0
- package/dist/code-language/registry.js.map +1 -0
- package/dist/code-language/runs.d.ts +35 -0
- package/dist/code-language/runs.d.ts.map +1 -0
- package/dist/code-language/runs.js +88 -0
- package/dist/code-language/runs.js.map +1 -0
- package/dist/code-language/stream.d.ts +70 -0
- package/dist/code-language/stream.d.ts.map +1 -0
- package/dist/code-language/stream.js +243 -0
- package/dist/code-language/stream.js.map +1 -0
- package/dist/code-language/textmate.d.ts +27 -0
- package/dist/code-language/textmate.d.ts.map +1 -0
- package/dist/code-language/textmate.js +86 -0
- package/dist/code-language/textmate.js.map +1 -0
- package/dist/code-language/theme.d.ts +26 -0
- package/dist/code-language/theme.d.ts.map +1 -0
- package/dist/code-language/theme.js +108 -0
- package/dist/code-language/theme.js.map +1 -0
- package/dist/code-language/timers.d.ts +7 -0
- package/dist/code-language/timers.d.ts.map +1 -0
- package/dist/code-language/timers.js +22 -0
- package/dist/code-language/timers.js.map +1 -0
- package/dist/code-language/types.d.ts +173 -0
- package/dist/code-language/types.d.ts.map +1 -0
- package/dist/code-language/types.js +41 -0
- package/dist/code-language/types.js.map +1 -0
- package/dist/codeblock/index.d.ts +69 -0
- package/dist/codeblock/index.d.ts.map +1 -0
- package/dist/codeblock/index.js +85 -0
- package/dist/codeblock/index.js.map +1 -0
- package/dist/color-picker/ColorField.d.ts +39 -0
- package/dist/color-picker/ColorField.d.ts.map +1 -0
- package/dist/color-picker/ColorField.js +239 -0
- package/dist/color-picker/ColorField.js.map +1 -0
- package/dist/color-picker/ColorPicker.d.ts +109 -0
- package/dist/color-picker/ColorPicker.d.ts.map +1 -0
- package/dist/color-picker/ColorPicker.js +757 -0
- package/dist/color-picker/ColorPicker.js.map +1 -0
- package/dist/color-picker/color.d.ts +105 -0
- package/dist/color-picker/color.d.ts.map +1 -0
- package/dist/color-picker/color.js +313 -0
- package/dist/color-picker/color.js.map +1 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +19 -0
- package/dist/color-picker/index.js.map +1 -0
- package/dist/desktop-calendar/eds.d.ts +102 -0
- package/dist/desktop-calendar/eds.d.ts.map +1 -0
- package/dist/desktop-calendar/eds.js +356 -0
- package/dist/desktop-calendar/eds.js.map +1 -0
- package/dist/desktop-calendar/ical.d.ts +63 -0
- package/dist/desktop-calendar/ical.d.ts.map +1 -0
- package/dist/desktop-calendar/ical.js +57 -0
- package/dist/desktop-calendar/ical.js.map +1 -0
- package/dist/desktop-calendar/index.d.ts +72 -0
- package/dist/desktop-calendar/index.d.ts.map +1 -0
- package/dist/desktop-calendar/index.js +213 -0
- package/dist/desktop-calendar/index.js.map +1 -0
- package/dist/embed/client.d.ts +121 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +203 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +96 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +266 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +13 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/timers.d.ts +6 -0
- package/dist/embed/timers.d.ts.map +1 -0
- package/dist/embed/timers.js +16 -0
- package/dist/embed/timers.js.map +1 -0
- package/dist/flow/draw.d.ts +45 -0
- package/dist/flow/draw.d.ts.map +1 -0
- package/dist/flow/draw.js +295 -0
- package/dist/flow/draw.js.map +1 -0
- package/dist/flow/index.d.ts +64 -0
- package/dist/flow/index.d.ts.map +1 -0
- package/dist/flow/index.js +306 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/flow/model.d.ts +158 -0
- package/dist/flow/model.d.ts.map +1 -0
- package/dist/flow/model.js +566 -0
- package/dist/flow/model.js.map +1 -0
- package/dist/flow/node.d.ts +429 -0
- package/dist/flow/node.d.ts.map +1 -0
- package/dist/flow/node.js +3025 -0
- package/dist/flow/node.js.map +1 -0
- package/dist/flow/paths.d.ts +43 -0
- package/dist/flow/paths.d.ts.map +1 -0
- package/dist/flow/paths.js +327 -0
- package/dist/flow/paths.js.map +1 -0
- package/dist/flow/types.d.ts +561 -0
- package/dist/flow/types.d.ts.map +1 -0
- package/dist/flow/types.js +2 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/formula/hx.d.ts +24 -0
- package/dist/formula/hx.d.ts.map +1 -0
- package/dist/formula/hx.js +25 -0
- package/dist/formula/hx.js.map +1 -0
- package/dist/formula/index.d.ts +74 -0
- package/dist/formula/index.d.ts.map +1 -0
- package/dist/formula/index.js +155 -0
- package/dist/formula/index.js.map +1 -0
- package/dist/formula/katex.d.ts +78 -0
- package/dist/formula/katex.d.ts.map +1 -0
- package/dist/formula/katex.js +130 -0
- package/dist/formula/katex.js.map +1 -0
- package/dist/formula/layout.d.ts +103 -0
- package/dist/formula/layout.d.ts.map +1 -0
- package/dist/formula/layout.js +716 -0
- package/dist/formula/layout.js.map +1 -0
- package/dist/formula/node.d.ts +50 -0
- package/dist/formula/node.d.ts.map +1 -0
- package/dist/formula/node.js +351 -0
- package/dist/formula/node.js.map +1 -0
- package/dist/html/controls.d.ts +48 -0
- package/dist/html/controls.d.ts.map +1 -0
- package/dist/html/controls.js +195 -0
- package/dist/html/controls.js.map +1 -0
- package/dist/html/css/cascade.d.ts +51 -0
- package/dist/html/css/cascade.d.ts.map +1 -0
- package/dist/html/css/cascade.js +552 -0
- package/dist/html/css/cascade.js.map +1 -0
- package/dist/html/css/parse.d.ts +74 -0
- package/dist/html/css/parse.d.ts.map +1 -0
- package/dist/html/css/parse.js +464 -0
- package/dist/html/css/parse.js.map +1 -0
- package/dist/html/css/style.d.ts +142 -0
- package/dist/html/css/style.d.ts.map +1 -0
- package/dist/html/css/style.js +1145 -0
- package/dist/html/css/style.js.map +1 -0
- package/dist/html/css/ua.d.ts +5 -0
- package/dist/html/css/ua.d.ts.map +1 -0
- package/dist/html/css/ua.js +171 -0
- package/dist/html/css/ua.js.map +1 -0
- package/dist/html/css/values.d.ts +78 -0
- package/dist/html/css/values.d.ts.map +1 -0
- package/dist/html/css/values.js +330 -0
- package/dist/html/css/values.js.map +1 -0
- package/dist/html/dom.d.ts +112 -0
- package/dist/html/dom.d.ts.map +1 -0
- package/dist/html/dom.js +374 -0
- package/dist/html/dom.js.map +1 -0
- package/dist/html/hx.d.ts +24 -0
- package/dist/html/hx.d.ts.map +1 -0
- package/dist/html/hx.js +29 -0
- package/dist/html/hx.js.map +1 -0
- package/dist/html/index.d.ts +137 -0
- package/dist/html/index.d.ts.map +1 -0
- package/dist/html/index.js +339 -0
- package/dist/html/index.js.map +1 -0
- package/dist/html/layout/block.d.ts +58 -0
- package/dist/html/layout/block.d.ts.map +1 -0
- package/dist/html/layout/block.js +724 -0
- package/dist/html/layout/block.js.map +1 -0
- package/dist/html/layout/boxes.d.ts +261 -0
- package/dist/html/layout/boxes.d.ts.map +1 -0
- package/dist/html/layout/boxes.js +725 -0
- package/dist/html/layout/boxes.js.map +1 -0
- package/dist/html/layout/flex.d.ts +16 -0
- package/dist/html/layout/flex.d.ts.map +1 -0
- package/dist/html/layout/flex.js +242 -0
- package/dist/html/layout/flex.js.map +1 -0
- package/dist/html/layout/floats.d.ts +50 -0
- package/dist/html/layout/floats.d.ts.map +1 -0
- package/dist/html/layout/floats.js +110 -0
- package/dist/html/layout/floats.js.map +1 -0
- package/dist/html/layout/inline.d.ts +44 -0
- package/dist/html/layout/inline.d.ts.map +1 -0
- package/dist/html/layout/inline.js +700 -0
- package/dist/html/layout/inline.js.map +1 -0
- package/dist/html/layout/table.d.ts +5 -0
- package/dist/html/layout/table.d.ts.map +1 -0
- package/dist/html/layout/table.js +340 -0
- package/dist/html/layout/table.js.map +1 -0
- package/dist/html/node.d.ts +149 -0
- package/dist/html/node.d.ts.map +1 -0
- package/dist/html/node.js +861 -0
- package/dist/html/node.js.map +1 -0
- package/dist/html/paint.d.ts +48 -0
- package/dist/html/paint.d.ts.map +1 -0
- package/dist/html/paint.js +495 -0
- package/dist/html/paint.js.map +1 -0
- package/dist/html/resources.d.ts +48 -0
- package/dist/html/resources.d.ts.map +1 -0
- package/dist/html/resources.js +156 -0
- package/dist/html/resources.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/heights.d.ts +81 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +193 -0
- package/dist/internal/heights.js.map +1 -0
- package/dist/internal/hx.d.ts +24 -0
- package/dist/internal/hx.d.ts.map +1 -0
- package/dist/internal/hx.js +27 -0
- package/dist/internal/hx.js.map +1 -0
- package/dist/internal/text.d.ts +6 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +44 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/timers.d.ts +8 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/timers.js +22 -0
- package/dist/internal/timers.js.map +1 -0
- package/dist/internal/widget.d.ts +40 -0
- package/dist/internal/widget.d.ts.map +1 -0
- package/dist/internal/widget.js +44 -0
- package/dist/internal/widget.js.map +1 -0
- package/dist/markdown/ast.d.ts +126 -0
- package/dist/markdown/ast.d.ts.map +1 -0
- package/dist/markdown/ast.js +8 -0
- package/dist/markdown/ast.js.map +1 -0
- package/dist/markdown/hx.d.ts +24 -0
- package/dist/markdown/hx.d.ts.map +1 -0
- package/dist/markdown/hx.js +25 -0
- package/dist/markdown/hx.js.map +1 -0
- package/dist/markdown/index.d.ts +90 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +413 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +8 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +911 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/spans.d.ts +20 -0
- package/dist/markdown/spans.d.ts.map +1 -0
- package/dist/markdown/spans.js +96 -0
- package/dist/markdown/spans.js.map +1 -0
- package/dist/media-player/backends.d.ts +64 -0
- package/dist/media-player/backends.d.ts.map +1 -0
- package/dist/media-player/backends.js +110 -0
- package/dist/media-player/backends.js.map +1 -0
- package/dist/media-player/control.d.ts +40 -0
- package/dist/media-player/control.d.ts.map +1 -0
- package/dist/media-player/control.js +44 -0
- package/dist/media-player/control.js.map +1 -0
- package/dist/media-player/hx.d.ts +24 -0
- package/dist/media-player/hx.d.ts.map +1 -0
- package/dist/media-player/hx.js +25 -0
- package/dist/media-player/hx.js.map +1 -0
- package/dist/media-player/index.d.ts +107 -0
- package/dist/media-player/index.d.ts.map +1 -0
- package/dist/media-player/index.js +219 -0
- package/dist/media-player/index.js.map +1 -0
- package/dist/media-player/mpv.d.ts +4 -0
- package/dist/media-player/mpv.d.ts.map +1 -0
- package/dist/media-player/mpv.js +120 -0
- package/dist/media-player/mpv.js.map +1 -0
- package/dist/media-player/vlc.d.ts +8 -0
- package/dist/media-player/vlc.d.ts.map +1 -0
- package/dist/media-player/vlc.js +83 -0
- package/dist/media-player/vlc.js.map +1 -0
- package/dist/richtext/index.d.ts +19 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +4 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/links.d.ts +12 -0
- package/dist/richtext/links.d.ts.map +1 -0
- package/dist/richtext/links.js +64 -0
- package/dist/richtext/links.js.map +1 -0
- package/dist/richtext/menu.d.ts +11 -0
- package/dist/richtext/menu.d.ts.map +1 -0
- package/dist/richtext/menu.js +43 -0
- package/dist/richtext/menu.js.map +1 -0
- package/dist/richtext/node.d.ts +151 -0
- package/dist/richtext/node.d.ts.map +1 -0
- package/dist/richtext/node.js +255 -0
- package/dist/richtext/node.js.map +1 -0
- package/dist/richtext/runs.d.ts +92 -0
- package/dist/richtext/runs.d.ts.map +1 -0
- package/dist/richtext/runs.js +158 -0
- package/dist/richtext/runs.js.map +1 -0
- package/dist/table/hx.d.ts +24 -0
- package/dist/table/hx.d.ts.map +1 -0
- package/dist/table/hx.js +25 -0
- package/dist/table/hx.js.map +1 -0
- package/dist/table/index.d.ts +169 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +844 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/rows.d.ts +136 -0
- package/dist/table/rows.d.ts.map +1 -0
- package/dist/table/rows.js +146 -0
- package/dist/table/rows.js.map +1 -0
- package/dist/terminal/backends.d.ts +105 -0
- package/dist/terminal/backends.d.ts.map +1 -0
- package/dist/terminal/backends.js +185 -0
- package/dist/terminal/backends.js.map +1 -0
- package/dist/terminal/hx.d.ts +24 -0
- package/dist/terminal/hx.d.ts.map +1 -0
- package/dist/terminal/hx.js +25 -0
- package/dist/terminal/hx.js.map +1 -0
- package/dist/terminal/index.d.ts +160 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +344 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/title.d.ts +24 -0
- package/dist/terminal/title.d.ts.map +1 -0
- package/dist/terminal/title.js +129 -0
- package/dist/terminal/title.js.map +1 -0
- package/dist/terminal/vt/colors.d.ts +63 -0
- package/dist/terminal/vt/colors.d.ts.map +1 -0
- package/dist/terminal/vt/colors.js +203 -0
- package/dist/terminal/vt/colors.js.map +1 -0
- package/dist/terminal/vt/diff.d.ts +117 -0
- package/dist/terminal/vt/diff.d.ts.map +1 -0
- package/dist/terminal/vt/diff.js +358 -0
- package/dist/terminal/vt/diff.js.map +1 -0
- package/dist/terminal/vt/fonts.d.ts +92 -0
- package/dist/terminal/vt/fonts.d.ts.map +1 -0
- package/dist/terminal/vt/fonts.js +178 -0
- package/dist/terminal/vt/fonts.js.map +1 -0
- package/dist/terminal/vt/index.d.ts +78 -0
- package/dist/terminal/vt/index.d.ts.map +1 -0
- package/dist/terminal/vt/index.js +312 -0
- package/dist/terminal/vt/index.js.map +1 -0
- package/dist/terminal/vt/keys.d.ts +74 -0
- package/dist/terminal/vt/keys.d.ts.map +1 -0
- package/dist/terminal/vt/keys.js +309 -0
- package/dist/terminal/vt/keys.js.map +1 -0
- package/dist/terminal/vt/mouse.d.ts +44 -0
- package/dist/terminal/vt/mouse.d.ts.map +1 -0
- package/dist/terminal/vt/mouse.js +106 -0
- package/dist/terminal/vt/mouse.js.map +1 -0
- package/dist/terminal/vt/node.d.ts +246 -0
- package/dist/terminal/vt/node.d.ts.map +1 -0
- package/dist/terminal/vt/node.js +1068 -0
- package/dist/terminal/vt/node.js.map +1 -0
- package/dist/terminal/vt/pty.d.ts +81 -0
- package/dist/terminal/vt/pty.d.ts.map +1 -0
- package/dist/terminal/vt/pty.js +201 -0
- package/dist/terminal/vt/pty.js.map +1 -0
- package/dist/terminal/vt/renderer.d.ts +179 -0
- package/dist/terminal/vt/renderer.d.ts.map +1 -0
- package/dist/terminal/vt/renderer.js +357 -0
- package/dist/terminal/vt/renderer.js.map +1 -0
- package/dist/terminal/vt/timers.d.ts +6 -0
- package/dist/terminal/vt/timers.d.ts.map +1 -0
- package/dist/terminal/vt/timers.js +16 -0
- package/dist/terminal/vt/timers.js.map +1 -0
- package/dist/terminal/vt/xterm.d.ts +142 -0
- package/dist/terminal/vt/xterm.d.ts.map +1 -0
- package/dist/terminal/vt/xterm.js +32 -0
- package/dist/terminal/vt/xterm.js.map +1 -0
- package/dist/terminal-output/hx.d.ts +24 -0
- package/dist/terminal-output/hx.d.ts.map +1 -0
- package/dist/terminal-output/hx.js +25 -0
- package/dist/terminal-output/hx.js.map +1 -0
- package/dist/terminal-output/index.d.ts +92 -0
- package/dist/terminal-output/index.d.ts.map +1 -0
- package/dist/terminal-output/index.js +179 -0
- package/dist/terminal-output/index.js.map +1 -0
- package/dist/terminal-output/runs.d.ts +27 -0
- package/dist/terminal-output/runs.d.ts.map +1 -0
- package/dist/terminal-output/runs.js +66 -0
- package/dist/terminal-output/runs.js.map +1 -0
- package/dist/three/canvas.d.ts +46 -0
- package/dist/three/canvas.d.ts.map +1 -0
- package/dist/three/canvas.js +305 -0
- package/dist/three/canvas.js.map +1 -0
- package/dist/three/events.d.ts +64 -0
- package/dist/three/events.d.ts.map +1 -0
- package/dist/three/events.js +146 -0
- package/dist/three/events.js.map +1 -0
- package/dist/three/geometries.d.ts +89 -0
- package/dist/three/geometries.d.ts.map +1 -0
- package/dist/three/geometries.js +345 -0
- package/dist/three/geometries.js.map +1 -0
- package/dist/three/globals.d.ts +7 -0
- package/dist/three/globals.d.ts.map +1 -0
- package/dist/three/globals.js +20 -0
- package/dist/three/globals.js.map +1 -0
- package/dist/three/hx.d.ts +9 -0
- package/dist/three/hx.d.ts.map +1 -0
- package/dist/three/hx.js +10 -0
- package/dist/three/hx.js.map +1 -0
- package/dist/three/index.d.ts +22 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +24 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/jsx-dev-runtime.d.ts +19 -0
- package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/three/jsx-dev-runtime.js +2 -0
- package/dist/three/jsx-dev-runtime.js.map +1 -0
- package/dist/three/jsx-runtime.d.ts +19 -0
- package/dist/three/jsx-runtime.d.ts.map +1 -0
- package/dist/three/jsx-runtime.js +2 -0
- package/dist/three/jsx-runtime.js.map +1 -0
- package/dist/three/jsx.d.ts +198 -0
- package/dist/three/jsx.d.ts.map +1 -0
- package/dist/three/jsx.js +2 -0
- package/dist/three/jsx.js.map +1 -0
- package/dist/three/materials.d.ts +125 -0
- package/dist/three/materials.d.ts.map +1 -0
- package/dist/three/materials.js +229 -0
- package/dist/three/materials.js.map +1 -0
- package/dist/three/math.d.ts +146 -0
- package/dist/three/math.d.ts.map +1 -0
- package/dist/three/math.js +464 -0
- package/dist/three/math.js.map +1 -0
- package/dist/three/objects.d.ts +185 -0
- package/dist/three/objects.d.ts.map +1 -0
- package/dist/three/objects.js +309 -0
- package/dist/three/objects.js.map +1 -0
- package/dist/three/passes.d.ts +54 -0
- package/dist/three/passes.d.ts.map +1 -0
- package/dist/three/passes.js +78 -0
- package/dist/three/passes.js.map +1 -0
- package/dist/three/postprocess.d.ts +85 -0
- package/dist/three/postprocess.d.ts.map +1 -0
- package/dist/three/postprocess.js +503 -0
- package/dist/three/postprocess.js.map +1 -0
- package/dist/three/raycast.d.ts +24 -0
- package/dist/three/raycast.d.ts.map +1 -0
- package/dist/three/raycast.js +138 -0
- package/dist/three/raycast.js.map +1 -0
- package/dist/three/reconciler.d.ts +48 -0
- package/dist/three/reconciler.d.ts.map +1 -0
- package/dist/three/reconciler.js +416 -0
- package/dist/three/reconciler.js.map +1 -0
- package/dist/three/renderer-direct.d.ts +102 -0
- package/dist/three/renderer-direct.d.ts.map +1 -0
- package/dist/three/renderer-direct.js +782 -0
- package/dist/three/renderer-direct.js.map +1 -0
- package/dist/three/renderer-indirect.d.ts +68 -0
- package/dist/three/renderer-indirect.d.ts.map +1 -0
- package/dist/three/renderer-indirect.js +438 -0
- package/dist/three/renderer-indirect.js.map +1 -0
- package/dist/three/store.d.ts +81 -0
- package/dist/three/store.d.ts.map +1 -0
- package/dist/three/store.js +110 -0
- package/dist/three/store.js.map +1 -0
- package/dist/timeline/hx.d.ts +18 -0
- package/dist/timeline/hx.d.ts.map +1 -0
- package/dist/timeline/hx.js +10 -0
- package/dist/timeline/hx.js.map +1 -0
- package/dist/timeline/index.d.ts +152 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +383 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/tray-host/hx.d.ts +24 -0
- package/dist/tray-host/hx.d.ts.map +1 -0
- package/dist/tray-host/hx.js +25 -0
- package/dist/tray-host/hx.js.map +1 -0
- package/dist/tray-host/index.d.ts +110 -0
- package/dist/tray-host/index.d.ts.map +1 -0
- package/dist/tray-host/index.js +191 -0
- package/dist/tray-host/index.js.map +1 -0
- package/dist/tray-host/manager.d.ts +137 -0
- package/dist/tray-host/manager.d.ts.map +1 -0
- package/dist/tray-host/manager.js +462 -0
- package/dist/tray-host/manager.js.map +1 -0
- package/dist/tray-host/notify.d.ts +22 -0
- package/dist/tray-host/notify.d.ts.map +1 -0
- package/dist/tray-host/notify.js +74 -0
- package/dist/tray-host/notify.js.map +1 -0
- package/dist/tray-host/protocol.d.ts +106 -0
- package/dist/tray-host/protocol.d.ts.map +1 -0
- package/dist/tray-host/protocol.js +191 -0
- package/dist/tray-host/protocol.js.map +1 -0
- package/dist/tree/hx.d.ts +24 -0
- package/dist/tree/hx.d.ts.map +1 -0
- package/dist/tree/hx.js +25 -0
- package/dist/tree/hx.js.map +1 -0
- package/dist/tree/index.d.ts +221 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +716 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/internal.d.ts +18 -0
- package/dist/tree/internal.d.ts.map +1 -0
- package/dist/tree/internal.js +66 -0
- package/dist/tree/internal.js.map +1 -0
- package/dist/tree/rows.d.ts +177 -0
- package/dist/tree/rows.d.ts.map +1 -0
- package/dist/tree/rows.js +179 -0
- package/dist/tree/rows.js.map +1 -0
- package/package.json +166 -12
- package/src/ansi/cast.ts +159 -0
- package/src/ansi/index.ts +53 -0
- package/src/ansi/palette.ts +226 -0
- package/src/ansi/parse.ts +780 -0
- package/src/ansi/sgr.ts +380 -0
- package/src/ansi/utf8.ts +84 -0
- package/src/calendar/Calendar.ts +744 -0
- package/src/calendar/DatePicker.ts +368 -0
- package/src/calendar/dates.ts +307 -0
- package/src/calendar/index.ts +51 -0
- package/src/charts/components.ts +864 -0
- package/src/charts/data.ts +776 -0
- package/src/charts/hx.ts +39 -0
- package/src/charts/index.ts +99 -0
- package/src/charts/node.ts +932 -0
- package/src/charts/render.ts +982 -0
- package/src/charts/scale.ts +214 -0
- package/src/charts/spec.ts +122 -0
- package/src/charts/timers.ts +24 -0
- package/src/code/hx.ts +51 -0
- package/src/code/index.ts +174 -0
- package/src/code-editor/completion.ts +161 -0
- package/src/code-editor/doc.ts +198 -0
- package/src/code-editor/hx.ts +26 -0
- package/src/code-editor/index.ts +615 -0
- package/src/code-editor/node.ts +1926 -0
- package/src/code-language/hljs.ts +302 -0
- package/src/code-language/index.ts +51 -0
- package/src/code-language/languages/glsl.ts +120 -0
- package/src/code-language/languages/javascript.ts +419 -0
- package/src/code-language/languages/json.ts +72 -0
- package/src/code-language/languages/shell.ts +221 -0
- package/src/code-language/languages/sql.ts +165 -0
- package/src/code-language/lezer.ts +190 -0
- package/src/code-language/registry.ts +66 -0
- package/src/code-language/runs.ts +128 -0
- package/src/code-language/stream.ts +306 -0
- package/src/code-language/textmate.ts +134 -0
- package/src/code-language/theme.ts +124 -0
- package/src/code-language/timers.ts +36 -0
- package/src/code-language/types.ts +252 -0
- package/src/codeblock/index.ts +146 -0
- package/src/color-picker/ColorField.ts +333 -0
- package/src/color-picker/ColorPicker.ts +1069 -0
- package/src/color-picker/color.ts +399 -0
- package/src/color-picker/index.ts +50 -0
- package/src/desktop-calendar/eds.ts +484 -0
- package/src/desktop-calendar/ical.ts +119 -0
- package/src/desktop-calendar/index.ts +287 -0
- package/src/embed/client.ts +311 -0
- package/src/embed/host.ts +432 -0
- package/src/embed/index.ts +33 -0
- package/src/embed/timers.ts +32 -0
- package/src/flow/draw.ts +418 -0
- package/src/flow/index.ts +473 -0
- package/src/flow/model.ts +687 -0
- package/src/flow/node.ts +3694 -0
- package/src/flow/paths.ts +403 -0
- package/src/flow/types.ts +634 -0
- package/src/formula/hx.ts +51 -0
- package/src/formula/index.ts +243 -0
- package/src/formula/katex.ts +209 -0
- package/src/formula/layout.ts +876 -0
- package/src/formula/node.ts +467 -0
- package/src/html/controls.ts +244 -0
- package/src/html/css/cascade.ts +606 -0
- package/src/html/css/parse.ts +500 -0
- package/src/html/css/style.ts +1371 -0
- package/src/html/css/ua.ts +174 -0
- package/src/html/css/values.ts +358 -0
- package/src/html/dom.ts +410 -0
- package/src/html/hx.ts +55 -0
- package/src/html/index.ts +545 -0
- package/src/html/layout/block.ts +876 -0
- package/src/html/layout/boxes.ts +981 -0
- package/src/html/layout/flex.ts +297 -0
- package/src/html/layout/floats.ts +125 -0
- package/src/html/layout/inline.ts +870 -0
- package/src/html/layout/table.ts +380 -0
- package/src/html/node.ts +967 -0
- package/src/html/paint.ts +605 -0
- package/src/html/resources.ts +214 -0
- package/src/index.ts +638 -0
- package/src/internal/heights.ts +211 -0
- package/src/internal/hx.ts +53 -0
- package/src/internal/text.ts +44 -0
- package/src/internal/timers.ts +44 -0
- package/src/internal/widget.ts +92 -0
- package/src/markdown/ast.ts +163 -0
- package/src/markdown/hx.ts +51 -0
- package/src/markdown/index.ts +686 -0
- package/src/markdown/parse.ts +1037 -0
- package/src/markdown/spans.ts +143 -0
- package/src/media-player/backends.ts +155 -0
- package/src/media-player/control.ts +70 -0
- package/src/media-player/hx.ts +51 -0
- package/src/media-player/index.ts +378 -0
- package/src/media-player/mpv.ts +146 -0
- package/src/media-player/vlc.ts +97 -0
- package/src/richtext/index.ts +42 -0
- package/src/richtext/links.ts +78 -0
- package/src/richtext/menu.ts +49 -0
- package/src/richtext/node.ts +406 -0
- package/src/richtext/runs.ts +253 -0
- package/src/table/hx.ts +51 -0
- package/src/table/index.ts +1219 -0
- package/src/table/rows.ts +275 -0
- package/src/terminal/backends.ts +242 -0
- package/src/terminal/hx.ts +51 -0
- package/src/terminal/index.ts +574 -0
- package/src/terminal/title.ts +172 -0
- package/src/terminal/vt/colors.ts +247 -0
- package/src/terminal/vt/diff.ts +467 -0
- package/src/terminal/vt/fonts.ts +233 -0
- package/src/terminal/vt/index.ts +443 -0
- package/src/terminal/vt/keys.ts +369 -0
- package/src/terminal/vt/mouse.ts +144 -0
- package/src/terminal/vt/node.ts +1242 -0
- package/src/terminal/vt/pty.ts +334 -0
- package/src/terminal/vt/renderer.ts +555 -0
- package/src/terminal/vt/timers.ts +31 -0
- package/src/terminal/vt/xterm.ts +193 -0
- package/src/terminal-output/hx.ts +51 -0
- package/src/terminal-output/index.ts +340 -0
- package/src/terminal-output/runs.ts +79 -0
- package/src/three/canvas.ts +451 -0
- package/src/three/events.ts +197 -0
- package/src/three/geometries.ts +429 -0
- package/src/three/globals.ts +34 -0
- package/src/three/hx.ts +22 -0
- package/src/three/index.ts +98 -0
- package/src/three/jsx-dev-runtime.ts +27 -0
- package/src/three/jsx-runtime.ts +38 -0
- package/src/three/jsx.ts +275 -0
- package/src/three/materials.ts +270 -0
- package/src/three/math.ts +585 -0
- package/src/three/objects.ts +397 -0
- package/src/three/passes.ts +90 -0
- package/src/three/postprocess.ts +677 -0
- package/src/three/raycast.ts +189 -0
- package/src/three/react-reconciler.d.ts +50 -0
- package/src/three/reconciler.ts +624 -0
- package/src/three/renderer-direct.ts +1055 -0
- package/src/three/renderer-indirect.ts +570 -0
- package/src/three/store.ts +207 -0
- package/src/timeline/hx.ts +31 -0
- package/src/timeline/index.ts +603 -0
- package/src/tray-host/hx.ts +51 -0
- package/src/tray-host/index.ts +331 -0
- package/src/tray-host/manager.ts +639 -0
- package/src/tray-host/notify.ts +102 -0
- package/src/tray-host/protocol.ts +235 -0
- package/src/tree/hx.ts +51 -0
- package/src/tree/index.ts +1087 -0
- package/src/tree/internal.ts +87 -0
- package/src/tree/rows.ts +334 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -9
- package/src/sparkline/index.d.ts +0 -29
- package/src/sparkline/index.js +0 -50
- package/src/sparkline/node.js +0 -72
|
@@ -0,0 +1,776 @@
|
|
|
1
|
+
// The data layer under `<chartplot>`: column resolution over the three
|
|
2
|
+
// accepted data shapes, the streaming `ChartData` store, and the min/max
|
|
3
|
+
// pyramid that makes paint cost a function of pixels rather than points.
|
|
4
|
+
//
|
|
5
|
+
// Everything here is pure JavaScript over plain values — no react-x11, no
|
|
6
|
+
// ntk — so the whole layer is unit-testable without a display, and the
|
|
7
|
+
// renderers stay the only code that knows what a drawing command is.
|
|
8
|
+
//
|
|
9
|
+
// ## Identity is the cache key, and appends are the one allowed mutation
|
|
10
|
+
//
|
|
11
|
+
// Preparation artifacts (pyramids, x-column indexes) are cached in WeakMaps
|
|
12
|
+
// keyed on a per-column host object, with `{epoch, n}` versioning:
|
|
13
|
+
//
|
|
14
|
+
// - a plain rows array or a columnar object is treated as immutable except
|
|
15
|
+
// for *growing* — same identity with a larger length extends the caches
|
|
16
|
+
// incrementally; a same-length change is invisible, which is the usual
|
|
17
|
+
// immutable-data contract React apps already live by;
|
|
18
|
+
// - `ChartData` is the sanctioned mutable store: it versions itself, its
|
|
19
|
+
// caches ride the per-column state objects (stable across compaction),
|
|
20
|
+
// and its `epoch` bump is what invalidates them after a window shift.
|
|
21
|
+
//
|
|
22
|
+
// Getting this wrong fails as a stale chart, so the rule is stated here
|
|
23
|
+
// once: **mutate history only through `ChartData`**.
|
|
24
|
+
|
|
25
|
+
/** One row, shadcn-style: `{ month: 'Jan', desktop: 186 }`. */
|
|
26
|
+
export type ChartRow = Record<string, unknown>;
|
|
27
|
+
|
|
28
|
+
/** Columnar input — the fast path. Arrays may be typed arrays; a column may
|
|
29
|
+
* hold strings (a category axis). `length` bounds every column. */
|
|
30
|
+
export interface ColumnarData {
|
|
31
|
+
length: number;
|
|
32
|
+
columns: Record<string, ArrayLike<number> | ArrayLike<string>>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The streaming store's contract, written structurally — deliberately not
|
|
37
|
+
* `typeof ChartData`. Structural, so a JSX augmentation carrying it
|
|
38
|
+
* unifies across the src/dist boundary (a class with private state would
|
|
39
|
+
* not), and so an app can bring its own store: anything that answers
|
|
40
|
+
* columns and announces appends is a chart data source.
|
|
41
|
+
*/
|
|
42
|
+
export interface ChartDataLike {
|
|
43
|
+
readonly length: number;
|
|
44
|
+
/** Bumps when history shifts; derived caches rebuild then. */
|
|
45
|
+
readonly epoch: number;
|
|
46
|
+
column(key: string): ResolvedColumn | null;
|
|
47
|
+
subscribe(listener: (change: ChartDataChange) => void): () => void;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** What `data` accepts: rows, columns, or a streaming store. */
|
|
51
|
+
export type ChartSourceData =
|
|
52
|
+
readonly ChartRow[] | ColumnarData | ChartDataLike;
|
|
53
|
+
|
|
54
|
+
export function isChartDataLike(data: ChartSourceData): data is ChartDataLike {
|
|
55
|
+
return (
|
|
56
|
+
!Array.isArray(data) &&
|
|
57
|
+
typeof (data as ChartDataLike).column === 'function' &&
|
|
58
|
+
typeof (data as ChartDataLike).subscribe === 'function'
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** A resolved column: raw storage, the valid length (storage may hold slack
|
|
63
|
+
* capacity), and the identity/version pair the caches key on. */
|
|
64
|
+
export interface ResolvedColumn {
|
|
65
|
+
values: ArrayLike<number> | ArrayLike<string>;
|
|
66
|
+
n: number;
|
|
67
|
+
/** Cache identity — WeakMap key. Stable for the life of the column. */
|
|
68
|
+
host: object;
|
|
69
|
+
/** Bumps when history changed under the same host (a window shift). */
|
|
70
|
+
epoch: number;
|
|
71
|
+
numeric: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** A resolved numeric column, which is what every renderer consumes. */
|
|
75
|
+
export interface NumericColumn extends ResolvedColumn {
|
|
76
|
+
values: ArrayLike<number>;
|
|
77
|
+
numeric: true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const isColumnar = (d: ChartSourceData): d is ColumnarData =>
|
|
81
|
+
typeof (d as ColumnarData).length === 'number' &&
|
|
82
|
+
!!(d as ColumnarData).columns &&
|
|
83
|
+
!Array.isArray(d);
|
|
84
|
+
|
|
85
|
+
// --- rows → columns --------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
interface RowsCacheEntry {
|
|
88
|
+
/** how many rows were extracted; same-identity growth re-extracts the tail */
|
|
89
|
+
n: number;
|
|
90
|
+
values: Float64Array | string[];
|
|
91
|
+
numeric: boolean;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Extracted columns per rows-array identity. WeakMap, so dropping the data
|
|
95
|
+
* drops the extraction. */
|
|
96
|
+
const rowsCache = new WeakMap<object, Map<string, RowsCacheEntry>>();
|
|
97
|
+
|
|
98
|
+
/** Per-host growable Float64 push. Doubling keeps append O(1) amortized. */
|
|
99
|
+
function grow(arr: Float64Array, need: number): Float64Array {
|
|
100
|
+
if (need <= arr.length) return arr;
|
|
101
|
+
const next = new Float64Array(Math.max(need, arr.length * 2, 64));
|
|
102
|
+
next.set(arr);
|
|
103
|
+
return next;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function extractRows(
|
|
107
|
+
rows: readonly ChartRow[],
|
|
108
|
+
key: string,
|
|
109
|
+
): RowsCacheEntry | null {
|
|
110
|
+
let perKey = rowsCache.get(rows);
|
|
111
|
+
if (!perKey) rowsCache.set(rows, (perKey = new Map()));
|
|
112
|
+
let entry = perKey.get(key);
|
|
113
|
+
const n = rows.length;
|
|
114
|
+
if (entry && entry.n === n) return entry;
|
|
115
|
+
if (!entry) {
|
|
116
|
+
// sniff the type from the first present value; a column that never
|
|
117
|
+
// shows the key at all is "not there" rather than all-NaN
|
|
118
|
+
let numeric: boolean | null = null;
|
|
119
|
+
for (let i = 0; i < n; i++) {
|
|
120
|
+
const v = rows[i]?.[key];
|
|
121
|
+
if (v == null) continue;
|
|
122
|
+
numeric = typeof v !== 'string';
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
if (numeric === null) return null;
|
|
126
|
+
entry = {
|
|
127
|
+
n: 0,
|
|
128
|
+
numeric,
|
|
129
|
+
values: numeric ? new Float64Array(Math.max(n, 64)) : [],
|
|
130
|
+
};
|
|
131
|
+
perKey.set(key, entry);
|
|
132
|
+
}
|
|
133
|
+
if (entry.numeric) {
|
|
134
|
+
let values = entry.values as Float64Array;
|
|
135
|
+
values = grow(values, n);
|
|
136
|
+
for (let i = entry.n; i < n; i++) {
|
|
137
|
+
const v = rows[i]?.[key];
|
|
138
|
+
values[i] = typeof v === 'number' ? v : NaN;
|
|
139
|
+
}
|
|
140
|
+
entry.values = values;
|
|
141
|
+
} else {
|
|
142
|
+
const values = entry.values as string[];
|
|
143
|
+
for (let i = entry.n; i < n; i++) {
|
|
144
|
+
const v = rows[i]?.[key];
|
|
145
|
+
values.push(v == null ? '' : String(v));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
entry.n = n;
|
|
149
|
+
return entry;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* The column `key` names in `data`, or null when there is none. Cheap to
|
|
154
|
+
* call every paint: each shape resolves through an identity-keyed cache.
|
|
155
|
+
*/
|
|
156
|
+
export function resolveColumn(
|
|
157
|
+
data: ChartSourceData,
|
|
158
|
+
key: string,
|
|
159
|
+
): ResolvedColumn | null {
|
|
160
|
+
if (isChartDataLike(data)) return data.column(key);
|
|
161
|
+
if (isColumnar(data)) {
|
|
162
|
+
const values = data.columns[key];
|
|
163
|
+
if (!values) return null;
|
|
164
|
+
const n = Math.min(data.length, values.length);
|
|
165
|
+
const numeric = typeof values[0] !== 'string';
|
|
166
|
+
return { values, n, host: values as object, epoch: 0, numeric };
|
|
167
|
+
}
|
|
168
|
+
const rows = data as readonly ChartRow[];
|
|
169
|
+
const entry = extractRows(rows, key);
|
|
170
|
+
if (!entry) return null;
|
|
171
|
+
return {
|
|
172
|
+
values: entry.numeric
|
|
173
|
+
? (entry.values as Float64Array).subarray(0, entry.n)
|
|
174
|
+
: entry.values,
|
|
175
|
+
n: entry.n,
|
|
176
|
+
host: rows as object,
|
|
177
|
+
epoch: 0,
|
|
178
|
+
numeric: entry.numeric,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Narrow to numeric, which is what scales and pyramids need. */
|
|
183
|
+
export function numericColumn(
|
|
184
|
+
col: ResolvedColumn | null,
|
|
185
|
+
): NumericColumn | null {
|
|
186
|
+
return col && col.numeric ? (col as NumericColumn) : null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// --- the streaming store ---------------------------------------------------
|
|
190
|
+
|
|
191
|
+
interface StoreColumn {
|
|
192
|
+
key: string;
|
|
193
|
+
numeric: boolean;
|
|
194
|
+
values: Float64Array | string[];
|
|
195
|
+
/** the cache identity for this column — survives compaction */
|
|
196
|
+
host: object;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface ChartDataOptions {
|
|
200
|
+
/** Keep at most this many points, dropping the oldest. The drop happens
|
|
201
|
+
* in occasional batches (12.5% slack), so appends stay O(1) and the
|
|
202
|
+
* expensive re-preparation is amortized over many frames. */
|
|
203
|
+
maxLength?: number;
|
|
204
|
+
/**
|
|
205
|
+
* Keep only points whose `key` column is within `ms` of the newest one —
|
|
206
|
+
* a **time** window where `maxLength` is a count window. A live feed
|
|
207
|
+
* wants this one: a count window silently turns into "however long that
|
|
208
|
+
* many points took", and an OS that throttles a hidden window's timers
|
|
209
|
+
* (it fires them slowly rather than not at all, so no gap heuristic
|
|
210
|
+
* notices) leaves a minutes-wide, points-thin era in the store — the
|
|
211
|
+
* dense fresh data then renders squeezed beside honest emptiness until
|
|
212
|
+
* enough appends push the sparse era out. Age eviction drops it on the
|
|
213
|
+
* first append instead, hard stalls included. Assumes `key` is appended
|
|
214
|
+
* in non-decreasing order, which a timestamp is; trims in occasional
|
|
215
|
+
* batches like `maxLength`.
|
|
216
|
+
*/
|
|
217
|
+
maxAge?: { key: string; ms: number };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export interface ChartDataChange {
|
|
221
|
+
appended: number;
|
|
222
|
+
/** History moved (a window shift): everything derived must rebuild. */
|
|
223
|
+
epoch: number;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The streaming data store: append-only columns in growable typed arrays.
|
|
228
|
+
*
|
|
229
|
+
* This is the "proper data structures and preparations" half of the
|
|
230
|
+
* performance story. Charts subscribing to a store never rescan history —
|
|
231
|
+
* an append extends the decimation pyramids incrementally and invalidates
|
|
232
|
+
* nothing, so a 10Hz feed into a million-point series stays O(appended)
|
|
233
|
+
* per tick plus one bounded repaint per visible chart.
|
|
234
|
+
*/
|
|
235
|
+
export class ChartData {
|
|
236
|
+
private _cols = new Map<string, StoreColumn>();
|
|
237
|
+
private _n = 0;
|
|
238
|
+
private _epoch = 0;
|
|
239
|
+
private _listeners = new Set<(change: ChartDataChange) => void>();
|
|
240
|
+
private readonly _maxLength: number;
|
|
241
|
+
private readonly _maxAge: { key: string; ms: number } | null;
|
|
242
|
+
|
|
243
|
+
constructor(options: ChartDataOptions = {}) {
|
|
244
|
+
this._maxLength = Math.max(2, options.maxLength ?? Infinity);
|
|
245
|
+
const age = options.maxAge;
|
|
246
|
+
this._maxAge =
|
|
247
|
+
age && age.ms > 0 && age.key ? { key: age.key, ms: age.ms } : null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
get length(): number {
|
|
251
|
+
return this._n;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Bumps when history shifts; caches keyed on it rebuild then. */
|
|
255
|
+
get epoch(): number {
|
|
256
|
+
return this._epoch;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Append one row. Keys never seen before backfill NaN (numeric) or ''
|
|
260
|
+
* so every column always covers every index. */
|
|
261
|
+
append(row: Readonly<Record<string, number | string>>): void {
|
|
262
|
+
this.appendRows([row]);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Drop every row, keeping the columns and their storage. The reset every
|
|
267
|
+
* live dashboard eventually wants: a stream resuming after its process
|
|
268
|
+
* was suspended (a hidden window, a laptop lid) comes back with a time
|
|
269
|
+
* gap as wide as the sleep, and a windowed store then renders fifty
|
|
270
|
+
* seconds of data squeezed beside fourteen minutes of nothing until the
|
|
271
|
+
* gap evicts. Clearing on resume starts the window honestly instead.
|
|
272
|
+
*
|
|
273
|
+
* An epoch bump, so every cache keyed on `{epoch, n}` — pyramids, x
|
|
274
|
+
* indexes, scatter grids — rebuilds, through the same invalidation a
|
|
275
|
+
* window shift already exercises.
|
|
276
|
+
*/
|
|
277
|
+
clear(): void {
|
|
278
|
+
if (this._n === 0) return;
|
|
279
|
+
// numeric storage is reused (reads are capped by n); string columns
|
|
280
|
+
// append with push, so their arrays must actually empty
|
|
281
|
+
for (const col of this._cols.values()) {
|
|
282
|
+
if (!col.numeric) (col.values as string[]).length = 0;
|
|
283
|
+
}
|
|
284
|
+
this._n = 0;
|
|
285
|
+
this._epoch++;
|
|
286
|
+
this._notify(0);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** Append many rows in one notification. */
|
|
290
|
+
appendRows(rows: readonly Readonly<Record<string, number | string>>[]): void {
|
|
291
|
+
if (rows.length === 0) return;
|
|
292
|
+
for (const row of rows) {
|
|
293
|
+
for (const key of Object.keys(row)) this._ensureColumn(key, row[key]);
|
|
294
|
+
const at = this._n;
|
|
295
|
+
for (const col of this._cols.values()) {
|
|
296
|
+
const v = row[col.key];
|
|
297
|
+
if (col.numeric) {
|
|
298
|
+
let values = col.values as Float64Array;
|
|
299
|
+
values = grow(values, at + 1);
|
|
300
|
+
values[at] = typeof v === 'number' ? v : NaN;
|
|
301
|
+
col.values = values;
|
|
302
|
+
} else {
|
|
303
|
+
(col.values as string[]).push(v == null ? '' : String(v));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
this._n = at + 1;
|
|
307
|
+
}
|
|
308
|
+
const shifted = this._enforceWindow();
|
|
309
|
+
this._notify(shifted ? 0 : rows.length);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private _ensureColumn(key: string, sample: unknown): void {
|
|
313
|
+
if (this._cols.has(key)) return;
|
|
314
|
+
const numeric = typeof sample !== 'string';
|
|
315
|
+
const col: StoreColumn = {
|
|
316
|
+
key,
|
|
317
|
+
numeric,
|
|
318
|
+
values: numeric ? new Float64Array(Math.max(this._n + 1, 64)) : [],
|
|
319
|
+
host: { key },
|
|
320
|
+
};
|
|
321
|
+
if (numeric) (col.values as Float64Array).fill(NaN, 0, this._n);
|
|
322
|
+
else for (let i = 0; i < this._n; i++) (col.values as string[]).push('');
|
|
323
|
+
this._cols.set(key, col);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/** Drop the oldest points once a window is exceeded by its slack.
|
|
327
|
+
* Returns true when history moved. */
|
|
328
|
+
private _enforceWindow(): boolean {
|
|
329
|
+
let drop = 0;
|
|
330
|
+
const limit = this._maxLength;
|
|
331
|
+
if (Number.isFinite(limit) && this._n > limit * 1.125) {
|
|
332
|
+
drop = this._n - limit;
|
|
333
|
+
}
|
|
334
|
+
const age = this._maxAge;
|
|
335
|
+
if (age) {
|
|
336
|
+
const col = this._cols.get(age.key);
|
|
337
|
+
if (col?.numeric && this._n > 0) {
|
|
338
|
+
const values = col.values as Float64Array;
|
|
339
|
+
const cutoff = values[this._n - 1] - age.ms;
|
|
340
|
+
// the age key appends in non-decreasing order, so the first row to
|
|
341
|
+
// keep is a binary search away
|
|
342
|
+
const first = lowerBound(values, this._n, cutoff);
|
|
343
|
+
// the same 12.5% slack the count window uses, so a live feed trims
|
|
344
|
+
// in occasional batches instead of every append — except when the
|
|
345
|
+
// stale run dwarfs the window (a resumed feed after a throttled
|
|
346
|
+
// era), where waiting for slack is exactly the squeeze to avoid
|
|
347
|
+
if (
|
|
348
|
+
first > drop &&
|
|
349
|
+
(first - drop >= this._n * 0.125 || values[0] < cutoff - age.ms)
|
|
350
|
+
) {
|
|
351
|
+
drop = first;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (drop <= 0) return false;
|
|
356
|
+
for (const col of this._cols.values()) {
|
|
357
|
+
if (col.numeric) {
|
|
358
|
+
const values = col.values as Float64Array;
|
|
359
|
+
values.copyWithin(0, drop, this._n);
|
|
360
|
+
} else {
|
|
361
|
+
(col.values as string[]).splice(0, drop);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
this._n -= drop;
|
|
365
|
+
this._epoch++;
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
column(key: string): ResolvedColumn | null {
|
|
370
|
+
const col = this._cols.get(key);
|
|
371
|
+
if (!col) return null;
|
|
372
|
+
return {
|
|
373
|
+
values: col.numeric
|
|
374
|
+
? (col.values as Float64Array).subarray(0, this._n)
|
|
375
|
+
: (col.values as string[]),
|
|
376
|
+
n: this._n,
|
|
377
|
+
host: col.host,
|
|
378
|
+
epoch: this._epoch,
|
|
379
|
+
numeric: col.numeric,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/** Hear about appends and window shifts. Returns the unsubscribe. */
|
|
384
|
+
subscribe(listener: (change: ChartDataChange) => void): () => void {
|
|
385
|
+
this._listeners.add(listener);
|
|
386
|
+
return () => {
|
|
387
|
+
this._listeners.delete(listener);
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private _notify(appended: number): void {
|
|
392
|
+
const change = { appended, epoch: this._epoch };
|
|
393
|
+
for (const listener of [...this._listeners]) listener(change);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// --- the min/max pyramid ---------------------------------------------------
|
|
398
|
+
|
|
399
|
+
/** Base block size. 16 keeps total pyramid memory at ~1/4 of the column
|
|
400
|
+
* (2 values per block, halving per level) while capping the raw-scan edges
|
|
401
|
+
* of any query at 15 points a side. */
|
|
402
|
+
const BASE = 16;
|
|
403
|
+
const BASE_SHIFT = 4;
|
|
404
|
+
|
|
405
|
+
interface PyramidLevel {
|
|
406
|
+
/** points per block at this level: BASE << k */
|
|
407
|
+
size: number;
|
|
408
|
+
mins: Float64Array;
|
|
409
|
+
maxs: Float64Array;
|
|
410
|
+
/** blocks currently valid (the last one may cover a partial tail, and is
|
|
411
|
+
* correct *for its coverage* — see extend) */
|
|
412
|
+
blocks: number;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export interface Pyramid {
|
|
416
|
+
builtN: number;
|
|
417
|
+
epoch: number;
|
|
418
|
+
levels: PyramidLevel[];
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const pyramids = new WeakMap<object, Pyramid>();
|
|
422
|
+
|
|
423
|
+
function growLevel(level: PyramidLevel, blocks: number): void {
|
|
424
|
+
if (blocks <= level.mins.length) return;
|
|
425
|
+
const cap = Math.max(blocks, level.mins.length * 2, 8);
|
|
426
|
+
const mins = new Float64Array(cap);
|
|
427
|
+
const maxs = new Float64Array(cap);
|
|
428
|
+
mins.set(level.mins);
|
|
429
|
+
maxs.set(level.maxs);
|
|
430
|
+
level.mins = mins;
|
|
431
|
+
level.maxs = maxs;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Recompute the blocks of every level that the growth from `fromN` to `n`
|
|
436
|
+
* touched. Level 1 reads raw values; every higher level reads the two
|
|
437
|
+
* blocks below it — a partial lower block is correct for its coverage, so
|
|
438
|
+
* the parent combining it is correct for *its* coverage too, which is the
|
|
439
|
+
* invariant that makes incremental extension safe.
|
|
440
|
+
*/
|
|
441
|
+
function extendPyramid(
|
|
442
|
+
pyr: Pyramid,
|
|
443
|
+
values: ArrayLike<number>,
|
|
444
|
+
n: number,
|
|
445
|
+
): void {
|
|
446
|
+
const fromN = pyr.builtN;
|
|
447
|
+
if (n <= fromN) return;
|
|
448
|
+
|
|
449
|
+
// make sure enough levels exist that the top is a single block
|
|
450
|
+
let topSize = pyr.levels.length
|
|
451
|
+
? pyr.levels[pyr.levels.length - 1].size
|
|
452
|
+
: BASE >> 1;
|
|
453
|
+
while (topSize < n) {
|
|
454
|
+
topSize <<= 1;
|
|
455
|
+
pyr.levels.push({
|
|
456
|
+
size: topSize,
|
|
457
|
+
mins: new Float64Array(0),
|
|
458
|
+
maxs: new Float64Array(0),
|
|
459
|
+
blocks: 0,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
for (let k = 0; k < pyr.levels.length; k++) {
|
|
464
|
+
const level = pyr.levels[k];
|
|
465
|
+
const size = level.size;
|
|
466
|
+
const first = Math.floor(fromN / size);
|
|
467
|
+
const last = Math.floor((n - 1) / size);
|
|
468
|
+
growLevel(level, last + 1);
|
|
469
|
+
for (let b = first; b <= last; b++) {
|
|
470
|
+
let min = Infinity;
|
|
471
|
+
let max = -Infinity;
|
|
472
|
+
if (k === 0) {
|
|
473
|
+
const end = Math.min((b + 1) * size, n);
|
|
474
|
+
for (let i = b * size; i < end; i++) {
|
|
475
|
+
const v = values[i];
|
|
476
|
+
// explicit comparisons skip NaN without poisoning the block
|
|
477
|
+
if (v < min) min = v;
|
|
478
|
+
if (v > max) max = v;
|
|
479
|
+
}
|
|
480
|
+
} else {
|
|
481
|
+
const below = pyr.levels[k - 1];
|
|
482
|
+
const b0 = b * 2;
|
|
483
|
+
const b1 = b0 + 1;
|
|
484
|
+
if (b0 < below.blocks) {
|
|
485
|
+
if (below.mins[b0] < min) min = below.mins[b0];
|
|
486
|
+
if (below.maxs[b0] > max) max = below.maxs[b0];
|
|
487
|
+
}
|
|
488
|
+
if (b1 < below.blocks) {
|
|
489
|
+
if (below.mins[b1] < min) min = below.mins[b1];
|
|
490
|
+
if (below.maxs[b1] > max) max = below.maxs[b1];
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
level.mins[b] = min;
|
|
494
|
+
level.maxs[b] = max;
|
|
495
|
+
}
|
|
496
|
+
level.blocks = last + 1;
|
|
497
|
+
}
|
|
498
|
+
pyr.builtN = n;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* The pyramid for a numeric column, built on first use and extended in
|
|
503
|
+
* place as the column grows. An epoch change rebuilds from scratch —
|
|
504
|
+
* history moved, and no incremental repair is worth the bug surface.
|
|
505
|
+
*/
|
|
506
|
+
export function pyramidFor(col: NumericColumn): Pyramid {
|
|
507
|
+
let pyr = pyramids.get(col.host);
|
|
508
|
+
if (!pyr || pyr.epoch !== col.epoch) {
|
|
509
|
+
pyr = { builtN: 0, epoch: col.epoch, levels: [] };
|
|
510
|
+
pyramids.set(col.host, pyr);
|
|
511
|
+
}
|
|
512
|
+
extendPyramid(pyr, col.values, col.n);
|
|
513
|
+
return pyr;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/** Reusable min/max result — renderers call this per pixel column, and a
|
|
517
|
+
* fresh object per call would be a million allocations a second. */
|
|
518
|
+
export interface MinMax {
|
|
519
|
+
min: number;
|
|
520
|
+
max: number;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Exact min/max over `[i0, i1)`, in O(log) block reads plus ≤15 raw points
|
|
525
|
+
* at each edge: greedy decomposition over the aligned blocks that fit, the
|
|
526
|
+
* way a sparse segment tree answers range queries. `out.min > out.max`
|
|
527
|
+
* means the range held no finite value (a gap).
|
|
528
|
+
*/
|
|
529
|
+
export function minMaxRange(
|
|
530
|
+
pyr: Pyramid,
|
|
531
|
+
values: ArrayLike<number>,
|
|
532
|
+
i0: number,
|
|
533
|
+
i1: number,
|
|
534
|
+
out: MinMax,
|
|
535
|
+
): void {
|
|
536
|
+
let min = Infinity;
|
|
537
|
+
let max = -Infinity;
|
|
538
|
+
let i = i0;
|
|
539
|
+
// raw leading edge up to base-block alignment
|
|
540
|
+
const firstAligned = Math.min(i1, (i + BASE - 1) & ~(BASE - 1));
|
|
541
|
+
for (; i < firstAligned; i++) {
|
|
542
|
+
const v = values[i];
|
|
543
|
+
if (v < min) min = v;
|
|
544
|
+
if (v > max) max = v;
|
|
545
|
+
}
|
|
546
|
+
// aligned middle: the biggest block that starts here and fits
|
|
547
|
+
while (i + BASE <= i1) {
|
|
548
|
+
let k = 0;
|
|
549
|
+
let size = BASE;
|
|
550
|
+
while (
|
|
551
|
+
k + 1 < pyr.levels.length &&
|
|
552
|
+
i % (size << 1) === 0 &&
|
|
553
|
+
i + (size << 1) <= i1
|
|
554
|
+
) {
|
|
555
|
+
k++;
|
|
556
|
+
size <<= 1;
|
|
557
|
+
}
|
|
558
|
+
const level = pyr.levels[k];
|
|
559
|
+
const b = i >> (BASE_SHIFT + k);
|
|
560
|
+
if (level.mins[b] < min) min = level.mins[b];
|
|
561
|
+
if (level.maxs[b] > max) max = level.maxs[b];
|
|
562
|
+
i += size;
|
|
563
|
+
}
|
|
564
|
+
// raw trailing edge
|
|
565
|
+
for (; i < i1; i++) {
|
|
566
|
+
const v = values[i];
|
|
567
|
+
if (v < min) min = v;
|
|
568
|
+
if (v > max) max = v;
|
|
569
|
+
}
|
|
570
|
+
out.min = min;
|
|
571
|
+
out.max = max;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// --- the x-column index ----------------------------------------------------
|
|
575
|
+
|
|
576
|
+
export interface XIndex {
|
|
577
|
+
builtN: number;
|
|
578
|
+
epoch: number;
|
|
579
|
+
/** non-decreasing so far — what makes binary search legal */
|
|
580
|
+
sorted: boolean;
|
|
581
|
+
/** evenly spaced so far — what makes column→index arithmetic */
|
|
582
|
+
uniform: boolean;
|
|
583
|
+
x0: number;
|
|
584
|
+
dx: number;
|
|
585
|
+
min: number;
|
|
586
|
+
max: number;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
const xIndexes = new WeakMap<object, XIndex>();
|
|
590
|
+
|
|
591
|
+
/** |observed − predicted| tolerated before "uniform" is given up, relative
|
|
592
|
+
* to the step. Covers float noise in generated timestamps without letting a
|
|
593
|
+
* genuinely ragged series pretend. */
|
|
594
|
+
const UNIFORM_TOL = 1e-6;
|
|
595
|
+
|
|
596
|
+
function extendXIndex(idx: XIndex, values: ArrayLike<number>, n: number): void {
|
|
597
|
+
let i = idx.builtN;
|
|
598
|
+
if (n <= i) return;
|
|
599
|
+
if (i === 0) {
|
|
600
|
+
idx.x0 = values[0];
|
|
601
|
+
idx.dx = NaN;
|
|
602
|
+
idx.min = Infinity;
|
|
603
|
+
idx.max = -Infinity;
|
|
604
|
+
i = 0;
|
|
605
|
+
}
|
|
606
|
+
let prev = i > 0 ? values[i - 1] : -Infinity;
|
|
607
|
+
for (; i < n; i++) {
|
|
608
|
+
const v = values[i];
|
|
609
|
+
if (Number.isNaN(v)) {
|
|
610
|
+
// a hole in x breaks both properties at once; there is no honest
|
|
611
|
+
// position for the points after it
|
|
612
|
+
idx.sorted = false;
|
|
613
|
+
idx.uniform = false;
|
|
614
|
+
} else {
|
|
615
|
+
if (v < prev) idx.sorted = false;
|
|
616
|
+
if (idx.uniform && i > 0) {
|
|
617
|
+
if (Number.isNaN(idx.dx)) idx.dx = v - idx.x0;
|
|
618
|
+
const predicted = idx.x0 + idx.dx * i;
|
|
619
|
+
const tol = Math.abs(idx.dx) * UNIFORM_TOL + 1e-12;
|
|
620
|
+
if (Math.abs(v - predicted) > tol) idx.uniform = false;
|
|
621
|
+
}
|
|
622
|
+
if (v < idx.min) idx.min = v;
|
|
623
|
+
if (v > idx.max) idx.max = v;
|
|
624
|
+
prev = v;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
// one point, or every step so far identical-to-zero: still "uniform",
|
|
628
|
+
// with a degenerate dx the callers guard against
|
|
629
|
+
idx.builtN = n;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** The sortedness/uniformity/extent record for an x column, incremental
|
|
633
|
+
* like the pyramid. */
|
|
634
|
+
export function xIndexFor(col: NumericColumn): XIndex {
|
|
635
|
+
let idx = xIndexes.get(col.host);
|
|
636
|
+
if (!idx || idx.epoch !== col.epoch) {
|
|
637
|
+
idx = {
|
|
638
|
+
builtN: 0,
|
|
639
|
+
epoch: col.epoch,
|
|
640
|
+
sorted: true,
|
|
641
|
+
uniform: true,
|
|
642
|
+
x0: 0,
|
|
643
|
+
dx: NaN,
|
|
644
|
+
min: Infinity,
|
|
645
|
+
max: -Infinity,
|
|
646
|
+
};
|
|
647
|
+
xIndexes.set(col.host, idx);
|
|
648
|
+
}
|
|
649
|
+
extendXIndex(idx, col.values, col.n);
|
|
650
|
+
return idx;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/** First index whose value is >= x, over a sorted column. */
|
|
654
|
+
export function lowerBound(
|
|
655
|
+
values: ArrayLike<number>,
|
|
656
|
+
n: number,
|
|
657
|
+
x: number,
|
|
658
|
+
): number {
|
|
659
|
+
let lo = 0;
|
|
660
|
+
let hi = n;
|
|
661
|
+
while (lo < hi) {
|
|
662
|
+
const mid = (lo + hi) >> 1;
|
|
663
|
+
if (values[mid] < x) lo = mid + 1;
|
|
664
|
+
else hi = mid;
|
|
665
|
+
}
|
|
666
|
+
return lo;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/** First index whose value is > x, over a sorted column. */
|
|
670
|
+
export function upperBound(
|
|
671
|
+
values: ArrayLike<number>,
|
|
672
|
+
n: number,
|
|
673
|
+
x: number,
|
|
674
|
+
): number {
|
|
675
|
+
let lo = 0;
|
|
676
|
+
let hi = n;
|
|
677
|
+
while (lo < hi) {
|
|
678
|
+
const mid = (lo + hi) >> 1;
|
|
679
|
+
if (values[mid] <= x) lo = mid + 1;
|
|
680
|
+
else hi = mid;
|
|
681
|
+
}
|
|
682
|
+
return lo;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* The index range `[i0, i1)` of points whose x falls in `[xMin, xMax]`,
|
|
687
|
+
* widened by one point each side so a line entering the viewport draws its
|
|
688
|
+
* crossing segment. Arithmetic for a uniform column, O(log n) for a sorted
|
|
689
|
+
* one, everything for the rest.
|
|
690
|
+
*/
|
|
691
|
+
export function visibleIndexRange(
|
|
692
|
+
idx: XIndex,
|
|
693
|
+
values: ArrayLike<number>,
|
|
694
|
+
n: number,
|
|
695
|
+
xMin: number,
|
|
696
|
+
xMax: number,
|
|
697
|
+
): [number, number] {
|
|
698
|
+
if (n === 0) return [0, 0];
|
|
699
|
+
let i0: number;
|
|
700
|
+
let i1: number;
|
|
701
|
+
if (idx.uniform && idx.dx > 0) {
|
|
702
|
+
i0 = Math.floor((xMin - idx.x0) / idx.dx);
|
|
703
|
+
i1 = Math.ceil((xMax - idx.x0) / idx.dx) + 1;
|
|
704
|
+
} else if (idx.sorted) {
|
|
705
|
+
i0 = lowerBound(values, n, xMin);
|
|
706
|
+
i1 = upperBound(values, n, xMax);
|
|
707
|
+
} else {
|
|
708
|
+
return [0, n];
|
|
709
|
+
}
|
|
710
|
+
i0 = Math.max(0, i0 - 1);
|
|
711
|
+
i1 = Math.min(n, i1 + 1);
|
|
712
|
+
if (i1 < i0) i1 = i0;
|
|
713
|
+
return [i0, i1];
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* The nearest index to x, for tooltip snapping. Sorted columns answer in
|
|
718
|
+
* O(log n); unsorted in O(n) — scatter tooltips over huge unsorted data can
|
|
719
|
+
* live with the miss being approximate instead.
|
|
720
|
+
*/
|
|
721
|
+
export function nearestIndex(
|
|
722
|
+
idx: XIndex,
|
|
723
|
+
values: ArrayLike<number>,
|
|
724
|
+
n: number,
|
|
725
|
+
x: number,
|
|
726
|
+
): number {
|
|
727
|
+
if (n === 0) return -1;
|
|
728
|
+
if (idx.uniform && idx.dx !== 0 && !Number.isNaN(idx.dx)) {
|
|
729
|
+
const i = Math.round((x - idx.x0) / idx.dx);
|
|
730
|
+
return Math.max(0, Math.min(n - 1, i));
|
|
731
|
+
}
|
|
732
|
+
if (idx.sorted) {
|
|
733
|
+
const at = lowerBound(values, n, x);
|
|
734
|
+
if (at <= 0) return 0;
|
|
735
|
+
if (at >= n) return n - 1;
|
|
736
|
+
return x - values[at - 1] <= values[at] - x ? at - 1 : at;
|
|
737
|
+
}
|
|
738
|
+
let best = 0;
|
|
739
|
+
let bestD = Infinity;
|
|
740
|
+
for (let i = 0; i < n; i++) {
|
|
741
|
+
const d = Math.abs(values[i] - x);
|
|
742
|
+
if (d < bestD) {
|
|
743
|
+
bestD = d;
|
|
744
|
+
best = i;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return best;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// --- stacks ----------------------------------------------------------------
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Cumulative tops for a stack: `tops[j][i]` is the sum of layers `0..j` at
|
|
754
|
+
* index `i`, NaN treated as 0 so one series' gap does not knock a hole in
|
|
755
|
+
* the layers above it. The arrays are fresh per build; the caller caches by
|
|
756
|
+
* its own version key and hands each layer's array back through
|
|
757
|
+
* `pyramidFor`-compatible columns (a fresh array is its own host).
|
|
758
|
+
*/
|
|
759
|
+
export function buildStackTops(
|
|
760
|
+
layers: readonly ArrayLike<number>[],
|
|
761
|
+
n: number,
|
|
762
|
+
): Float64Array[] {
|
|
763
|
+
const tops: Float64Array[] = [];
|
|
764
|
+
let prev: Float64Array | null = null;
|
|
765
|
+
for (const layer of layers) {
|
|
766
|
+
const top = new Float64Array(n);
|
|
767
|
+
for (let i = 0; i < n; i++) {
|
|
768
|
+
const v = layer[i];
|
|
769
|
+
const below: number = prev ? prev[i] : 0;
|
|
770
|
+
top[i] = below + (typeof v === 'number' && !Number.isNaN(v) ? v : 0);
|
|
771
|
+
}
|
|
772
|
+
tops.push(top);
|
|
773
|
+
prev = top;
|
|
774
|
+
}
|
|
775
|
+
return tops;
|
|
776
|
+
}
|