@elaraai/e3-ui 1.0.86 → 1.0.88
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/dist/src/bind/data-indexed.d.ts +159 -0
- package/dist/src/bind/data-indexed.d.ts.map +1 -0
- package/dist/src/bind/data-indexed.js +105 -0
- package/dist/src/bind/data-indexed.js.map +1 -0
- package/dist/src/bind/data.d.ts +5 -3
- package/dist/src/bind/data.d.ts.map +1 -1
- package/dist/src/bind/data.js +6 -0
- package/dist/src/bind/data.js.map +1 -1
- package/dist/src/bind/record.d.ts +34 -23
- package/dist/src/bind/record.d.ts.map +1 -1
- package/dist/src/bind/record.js +46 -19
- package/dist/src/bind/record.js.map +1 -1
- package/dist/src/calendar/index.d.ts +2923 -0
- package/dist/src/calendar/index.d.ts.map +1 -0
- package/dist/src/calendar/index.js +135 -0
- package/dist/src/calendar/index.js.map +1 -0
- package/dist/src/decision/queue.d.ts +3 -3
- package/dist/src/decision/queue.d.ts.map +1 -1
- package/dist/src/decision/queue.js +2 -2
- package/dist/src/decision/queue.js.map +1 -1
- package/dist/src/decision/types.d.ts +4 -0
- package/dist/src/decision/types.d.ts.map +1 -1
- package/dist/src/decision/types.js +4 -0
- package/dist/src/decision/types.js.map +1 -1
- package/dist/src/flowchart/canvas.d.ts +114 -0
- package/dist/src/flowchart/canvas.d.ts.map +1 -0
- package/dist/src/flowchart/canvas.js +84 -0
- package/dist/src/flowchart/canvas.js.map +1 -0
- package/dist/src/flowchart/flowchart.d.ts +79 -0
- package/dist/src/flowchart/flowchart.d.ts.map +1 -0
- package/dist/src/flowchart/flowchart.js +9 -0
- package/dist/src/flowchart/flowchart.js.map +1 -0
- package/dist/src/flowchart/index.d.ts +305 -0
- package/dist/src/flowchart/index.d.ts.map +1 -0
- package/dist/src/flowchart/index.js +267 -0
- package/dist/src/flowchart/index.js.map +1 -0
- package/dist/src/flowchart/library.d.ts +720 -0
- package/dist/src/flowchart/library.d.ts.map +1 -0
- package/dist/src/flowchart/library.js +611 -0
- package/dist/src/flowchart/library.js.map +1 -0
- package/dist/src/flowchart/over.d.ts +234 -0
- package/dist/src/flowchart/over.d.ts.map +1 -0
- package/dist/src/flowchart/over.js +220 -0
- package/dist/src/flowchart/over.js.map +1 -0
- package/dist/src/flowchart/patch.d.ts +64 -0
- package/dist/src/flowchart/patch.d.ts.map +1 -0
- package/dist/src/flowchart/patch.js +67 -0
- package/dist/src/flowchart/patch.js.map +1 -0
- package/dist/src/flowchart/payload.d.ts +8220 -0
- package/dist/src/flowchart/payload.d.ts.map +1 -0
- package/dist/src/flowchart/payload.js +521 -0
- package/dist/src/flowchart/payload.js.map +1 -0
- package/dist/src/flowchart/types.d.ts +393 -0
- package/dist/src/flowchart/types.d.ts.map +1 -0
- package/dist/src/flowchart/types.js +216 -0
- package/dist/src/flowchart/types.js.map +1 -0
- package/dist/src/flowchart/values.d.ts +267 -0
- package/dist/src/flowchart/values.d.ts.map +1 -0
- package/dist/src/flowchart/values.js +216 -0
- package/dist/src/flowchart/values.js.map +1 -0
- package/dist/src/flowchart/window.d.ts +521 -0
- package/dist/src/flowchart/window.d.ts.map +1 -0
- package/dist/src/flowchart/window.js +69 -0
- package/dist/src/flowchart/window.js.map +1 -0
- package/dist/src/index.d.ts +25 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +48 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/internal.d.ts +35 -3
- package/dist/src/internal.d.ts.map +1 -1
- package/dist/src/internal.js +72 -3
- package/dist/src/internal.js.map +1 -1
- package/dist/src/plan/assemble.d.ts +2224 -0
- package/dist/src/plan/assemble.d.ts.map +1 -0
- package/dist/src/plan/assemble.js +210 -0
- package/dist/src/plan/assemble.js.map +1 -0
- package/dist/src/plan/builders.d.ts +790 -0
- package/dist/src/plan/builders.d.ts.map +1 -0
- package/dist/src/plan/builders.js +749 -0
- package/dist/src/plan/builders.js.map +1 -0
- package/dist/src/plan/event-rows.d.ts +2565 -0
- package/dist/src/plan/event-rows.d.ts.map +1 -0
- package/dist/src/plan/event-rows.js +689 -0
- package/dist/src/plan/event-rows.js.map +1 -0
- package/dist/src/plan/factories.d.ts +458 -0
- package/dist/src/plan/factories.d.ts.map +1 -0
- package/dist/src/plan/factories.js +484 -0
- package/dist/src/plan/factories.js.map +1 -0
- package/dist/src/plan/index.d.ts +672 -0
- package/dist/src/plan/index.d.ts.map +1 -0
- package/dist/src/plan/index.js +532 -0
- package/dist/src/plan/index.js.map +1 -0
- package/dist/src/plan/ir.d.ts +2594 -0
- package/dist/src/plan/ir.d.ts.map +1 -0
- package/dist/src/plan/ir.js +78 -0
- package/dist/src/plan/ir.js.map +1 -0
- package/dist/src/plan/library.d.ts +772 -0
- package/dist/src/plan/library.d.ts.map +1 -0
- package/dist/src/plan/library.js +424 -0
- package/dist/src/plan/library.js.map +1 -0
- package/dist/src/plan/ordered-source.d.ts +27 -0
- package/dist/src/plan/ordered-source.d.ts.map +1 -0
- package/dist/src/plan/ordered-source.js +48 -0
- package/dist/src/plan/ordered-source.js.map +1 -0
- package/dist/src/plan/over.d.ts +247 -0
- package/dist/src/plan/over.d.ts.map +1 -0
- package/dist/src/plan/over.js +266 -0
- package/dist/src/plan/over.js.map +1 -0
- package/dist/src/plan/pick.d.ts +78 -0
- package/dist/src/plan/pick.d.ts.map +1 -0
- package/dist/src/plan/pick.js +146 -0
- package/dist/src/plan/pick.js.map +1 -0
- package/dist/src/plan/plan.d.ts +11611 -0
- package/dist/src/plan/plan.d.ts.map +1 -0
- package/dist/src/plan/plan.js +428 -0
- package/dist/src/plan/plan.js.map +1 -0
- package/dist/src/plan/refs.d.ts +218 -0
- package/dist/src/plan/refs.d.ts.map +1 -0
- package/dist/src/plan/refs.js +226 -0
- package/dist/src/plan/refs.js.map +1 -0
- package/dist/src/plan/root.d.ts +290 -0
- package/dist/src/plan/root.d.ts.map +1 -0
- package/dist/src/plan/root.js +463 -0
- package/dist/src/plan/root.js.map +1 -0
- package/dist/src/plan/series.d.ts +13554 -0
- package/dist/src/plan/series.d.ts.map +1 -0
- package/dist/src/plan/series.js +1921 -0
- package/dist/src/plan/series.js.map +1 -0
- package/dist/src/plan/types.d.ts +12400 -0
- package/dist/src/plan/types.d.ts.map +1 -0
- package/dist/src/plan/types.js +1335 -0
- package/dist/src/plan/types.js.map +1 -0
- package/dist/src/roster/coverage.d.ts +240 -0
- package/dist/src/roster/coverage.d.ts.map +1 -0
- package/dist/src/roster/coverage.js +109 -0
- package/dist/src/roster/coverage.js.map +1 -0
- package/dist/src/roster/index.d.ts +4028 -0
- package/dist/src/roster/index.d.ts.map +1 -0
- package/dist/src/roster/index.js +115 -0
- package/dist/src/roster/index.js.map +1 -0
- package/dist/src/roster/library.d.ts +106 -0
- package/dist/src/roster/library.d.ts.map +1 -0
- package/dist/src/roster/library.js +78 -0
- package/dist/src/roster/library.js.map +1 -0
- package/dist/src/roster/people.d.ts +50 -0
- package/dist/src/roster/people.d.ts.map +1 -0
- package/dist/src/roster/people.js +32 -0
- package/dist/src/roster/people.js.map +1 -0
- package/dist/src/roster/rules.d.ts +275 -0
- package/dist/src/roster/rules.d.ts.map +1 -0
- package/dist/src/roster/rules.js +162 -0
- package/dist/src/roster/rules.js.map +1 -0
- package/dist/src/roster/types.d.ts +672 -0
- package/dist/src/roster/types.d.ts.map +1 -0
- package/dist/src/roster/types.js +248 -0
- package/dist/src/roster/types.js.map +1 -0
- package/dist/src/roster/visibility.d.ts +66 -0
- package/dist/src/roster/visibility.d.ts.map +1 -0
- package/dist/src/roster/visibility.js +25 -0
- package/dist/src/roster/visibility.js.map +1 -0
- package/dist/src/schedule/days.d.ts +54 -0
- package/dist/src/schedule/days.d.ts.map +1 -0
- package/dist/src/schedule/days.js +68 -0
- package/dist/src/schedule/days.js.map +1 -0
- package/dist/src/schedule/events.d.ts +433 -0
- package/dist/src/schedule/events.d.ts.map +1 -0
- package/dist/src/schedule/events.js +851 -0
- package/dist/src/schedule/events.js.map +1 -0
- package/dist/src/schedule/index.d.ts +150 -0
- package/dist/src/schedule/index.d.ts.map +1 -0
- package/dist/src/schedule/index.js +132 -0
- package/dist/src/schedule/index.js.map +1 -0
- package/dist/src/schedule/library.d.ts +70 -0
- package/dist/src/schedule/library.d.ts.map +1 -0
- package/dist/src/schedule/library.js +102 -0
- package/dist/src/schedule/library.js.map +1 -0
- package/dist/src/schedule/patch.d.ts +74 -0
- package/dist/src/schedule/patch.d.ts.map +1 -0
- package/dist/src/schedule/patch.js +68 -0
- package/dist/src/schedule/patch.js.map +1 -0
- package/dist/src/schedule/record-window.d.ts +189 -0
- package/dist/src/schedule/record-window.d.ts.map +1 -0
- package/dist/src/schedule/record-window.js +95 -0
- package/dist/src/schedule/record-window.js.map +1 -0
- package/dist/src/schedule/resources.d.ts +165 -0
- package/dist/src/schedule/resources.d.ts.map +1 -0
- package/dist/src/schedule/resources.js +234 -0
- package/dist/src/schedule/resources.js.map +1 -0
- package/dist/src/schedule/templates.d.ts +47 -0
- package/dist/src/schedule/templates.d.ts.map +1 -0
- package/dist/src/schedule/templates.js +61 -0
- package/dist/src/schedule/templates.js.map +1 -0
- package/dist/src/schedule/types.d.ts +1677 -0
- package/dist/src/schedule/types.d.ts.map +1 -0
- package/dist/src/schedule/types.js +374 -0
- package/dist/src/schedule/types.js.map +1 -0
- package/dist/src/schedule/window.d.ts +154 -0
- package/dist/src/schedule/window.d.ts.map +1 -0
- package/dist/src/schedule/window.js +363 -0
- package/dist/src/schedule/window.js.map +1 -0
- package/dist/src/sheet/bridge.d.ts +385 -0
- package/dist/src/sheet/bridge.d.ts.map +1 -0
- package/dist/src/sheet/bridge.js +809 -0
- package/dist/src/sheet/bridge.js.map +1 -0
- package/dist/src/sheet/columns.d.ts +410 -0
- package/dist/src/sheet/columns.d.ts.map +1 -0
- package/dist/src/sheet/columns.js +99 -0
- package/dist/src/sheet/columns.js.map +1 -0
- package/dist/src/sheet/context-bridge.d.ts +48 -0
- package/dist/src/sheet/context-bridge.d.ts.map +1 -0
- package/dist/src/sheet/context-bridge.js +216 -0
- package/dist/src/sheet/context-bridge.js.map +1 -0
- package/dist/src/sheet/draft-bridge.d.ts +37 -0
- package/dist/src/sheet/draft-bridge.d.ts.map +1 -0
- package/dist/src/sheet/draft-bridge.js +153 -0
- package/dist/src/sheet/draft-bridge.js.map +1 -0
- package/dist/src/sheet/drafts.d.ts +14 -0
- package/dist/src/sheet/drafts.d.ts.map +1 -0
- package/dist/src/sheet/drafts.js +14 -0
- package/dist/src/sheet/drafts.js.map +1 -0
- package/dist/src/sheet/editing-bridge.d.ts +40 -0
- package/dist/src/sheet/editing-bridge.d.ts.map +1 -0
- package/dist/src/sheet/editing-bridge.js +231 -0
- package/dist/src/sheet/editing-bridge.js.map +1 -0
- package/dist/src/sheet/editing-types.d.ts +268 -0
- package/dist/src/sheet/editing-types.d.ts.map +1 -0
- package/dist/src/sheet/editing-types.js +34 -0
- package/dist/src/sheet/editing-types.js.map +1 -0
- package/dist/src/sheet/edits.d.ts +37 -0
- package/dist/src/sheet/edits.d.ts.map +1 -0
- package/dist/src/sheet/edits.js +31 -0
- package/dist/src/sheet/edits.js.map +1 -0
- package/dist/src/sheet/fields.d.ts +693 -0
- package/dist/src/sheet/fields.d.ts.map +1 -0
- package/dist/src/sheet/fields.js +280 -0
- package/dist/src/sheet/fields.js.map +1 -0
- package/dist/src/sheet/group.d.ts +165 -0
- package/dist/src/sheet/group.d.ts.map +1 -0
- package/dist/src/sheet/group.js +52 -0
- package/dist/src/sheet/group.js.map +1 -0
- package/dist/src/sheet/index.d.ts +542 -0
- package/dist/src/sheet/index.d.ts.map +1 -0
- package/dist/src/sheet/index.js +387 -0
- package/dist/src/sheet/index.js.map +1 -0
- package/dist/src/sheet/library.d.ts +284 -0
- package/dist/src/sheet/library.d.ts.map +1 -0
- package/dist/src/sheet/library.js +259 -0
- package/dist/src/sheet/library.js.map +1 -0
- package/dist/src/sheet/link.d.ts +398 -0
- package/dist/src/sheet/link.d.ts.map +1 -0
- package/dist/src/sheet/link.js +228 -0
- package/dist/src/sheet/link.js.map +1 -0
- package/dist/src/sheet/record.d.ts +75 -0
- package/dist/src/sheet/record.d.ts.map +1 -0
- package/dist/src/sheet/record.js +128 -0
- package/dist/src/sheet/record.js.map +1 -0
- package/dist/src/sheet/registers.d.ts +681 -0
- package/dist/src/sheet/registers.d.ts.map +1 -0
- package/dist/src/sheet/registers.js +671 -0
- package/dist/src/sheet/registers.js.map +1 -0
- package/dist/src/sheet/root.d.ts +329 -0
- package/dist/src/sheet/root.d.ts.map +1 -0
- package/dist/src/sheet/root.js +511 -0
- package/dist/src/sheet/root.js.map +1 -0
- package/dist/src/sheet/seed-bridge.d.ts +14 -0
- package/dist/src/sheet/seed-bridge.d.ts.map +1 -0
- package/dist/src/sheet/seed-bridge.js +51 -0
- package/dist/src/sheet/seed-bridge.js.map +1 -0
- package/dist/src/sheet/sheet.d.ts +11819 -0
- package/dist/src/sheet/sheet.d.ts.map +1 -0
- package/dist/src/sheet/sheet.js +236 -0
- package/dist/src/sheet/sheet.js.map +1 -0
- package/dist/src/sheet/sub-rows.d.ts +299 -0
- package/dist/src/sheet/sub-rows.d.ts.map +1 -0
- package/dist/src/sheet/sub-rows.js +272 -0
- package/dist/src/sheet/sub-rows.js.map +1 -0
- package/dist/src/sheet/templates.d.ts +161 -0
- package/dist/src/sheet/templates.d.ts.map +1 -0
- package/dist/src/sheet/templates.js +122 -0
- package/dist/src/sheet/templates.js.map +1 -0
- package/dist/src/sheet/transactions.d.ts +76 -0
- package/dist/src/sheet/transactions.d.ts.map +1 -0
- package/dist/src/sheet/transactions.js +40 -0
- package/dist/src/sheet/transactions.js.map +1 -0
- package/dist/src/sheet/types.d.ts +15226 -0
- package/dist/src/sheet/types.d.ts.map +1 -0
- package/dist/src/sheet/types.js +1070 -0
- package/dist/src/sheet/types.js.map +1 -0
- package/dist/src/sheet/views.d.ts +29 -0
- package/dist/src/sheet/views.d.ts.map +1 -0
- package/dist/src/sheet/views.js +43 -0
- package/dist/src/sheet/views.js.map +1 -0
- package/dist/src/studio/component.d.ts.map +1 -1
- package/dist/src/studio/component.js +11 -8
- package/dist/src/studio/component.js.map +1 -1
- package/dist/src/utils/derive.d.ts +134 -8
- package/dist/src/utils/derive.d.ts.map +1 -1
- package/dist/src/utils/derive.js +409 -7
- package/dist/src/utils/derive.js.map +1 -1
- package/dist/src/utils/ordered-source.d.ts +38 -0
- package/dist/src/utils/ordered-source.d.ts.map +1 -0
- package/dist/src/utils/ordered-source.js +45 -0
- package/dist/src/utils/ordered-source.js.map +1 -0
- package/dist/src/utils/row-inspector.d.ts +36 -0
- package/dist/src/utils/row-inspector.d.ts.map +1 -0
- package/dist/src/utils/row-inspector.js +49 -0
- package/dist/src/utils/row-inspector.js.map +1 -0
- package/dist/test/bind/data/data.examples.d.ts +21 -19
- package/dist/test/bind/data/data.examples.d.ts.map +1 -1
- package/dist/test/bind/data/data.examples.js +122 -122
- package/dist/test/bind/data/data.examples.js.map +1 -1
- package/dist/test/bind/record/record.examples.d.ts.map +1 -1
- package/dist/test/bind/record/record.examples.js +9 -9
- package/dist/test/bind/record/record.examples.js.map +1 -1
- package/dist/test/calendar/calendar-records.examples.d.ts +228 -0
- package/dist/test/calendar/calendar-records.examples.d.ts.map +1 -0
- package/dist/test/calendar/calendar-records.examples.js +91 -0
- package/dist/test/calendar/calendar-records.examples.js.map +1 -0
- package/dist/test/calendar/calendar.examples.d.ts +776 -0
- package/dist/test/calendar/calendar.examples.d.ts.map +1 -0
- package/dist/test/calendar/calendar.examples.js +336 -0
- package/dist/test/calendar/calendar.examples.js.map +1 -0
- package/dist/test/decision/journal.examples.d.ts +28 -28
- package/dist/test/decision/journal.examples.d.ts.map +1 -1
- package/dist/test/decision/journal.examples.js +4 -4
- package/dist/test/decision/journal.examples.js.map +1 -1
- package/dist/test/decision/queue.examples.d.ts.map +1 -1
- package/dist/test/decision/queue.examples.js +5 -7
- package/dist/test/decision/queue.examples.js.map +1 -1
- package/dist/test/flowchart/flowchart.examples.d.ts +3713 -0
- package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -0
- package/dist/test/flowchart/flowchart.examples.js +465 -0
- package/dist/test/flowchart/flowchart.examples.js.map +1 -0
- package/dist/test/plan/plan-events.examples.d.ts +3666 -0
- package/dist/test/plan/plan-events.examples.d.ts.map +1 -0
- package/dist/test/plan/plan-events.examples.js +773 -0
- package/dist/test/plan/plan-events.examples.js.map +1 -0
- package/dist/test/plan/plan-records.examples.d.ts +3 -0
- package/dist/test/plan/plan-records.examples.d.ts.map +1 -0
- package/dist/test/plan/plan-records.examples.js +45 -0
- package/dist/test/plan/plan-records.examples.js.map +1 -0
- package/dist/test/plan/plan-windows.examples.d.ts +588 -0
- package/dist/test/plan/plan-windows.examples.d.ts.map +1 -0
- package/dist/test/plan/plan-windows.examples.js +170 -0
- package/dist/test/plan/plan-windows.examples.js.map +1 -0
- package/dist/test/plan/plan.examples.d.ts +8095 -0
- package/dist/test/plan/plan.examples.d.ts.map +1 -0
- package/dist/test/plan/plan.examples.js +2500 -0
- package/dist/test/plan/plan.examples.js.map +1 -0
- package/dist/test/roster/domain.examples.d.ts +367 -0
- package/dist/test/roster/domain.examples.d.ts.map +1 -0
- package/dist/test/roster/domain.examples.js +72 -0
- package/dist/test/roster/domain.examples.js.map +1 -0
- package/dist/test/roster/roster-records.examples.d.ts +729 -0
- package/dist/test/roster/roster-records.examples.d.ts.map +1 -0
- package/dist/test/roster/roster-records.examples.js +86 -0
- package/dist/test/roster/roster-records.examples.js.map +1 -0
- package/dist/test/roster/roster.examples.d.ts +750 -0
- package/dist/test/roster/roster.examples.d.ts.map +1 -0
- package/dist/test/roster/roster.examples.js +198 -0
- package/dist/test/roster/roster.examples.js.map +1 -0
- package/dist/test/roster/warehouse.d.ts +87 -0
- package/dist/test/roster/warehouse.d.ts.map +1 -0
- package/dist/test/roster/warehouse.js +883 -0
- package/dist/test/roster/warehouse.js.map +1 -0
- package/dist/test/sheet/sheet-link.examples.d.ts +7 -0
- package/dist/test/sheet/sheet-link.examples.d.ts.map +1 -0
- package/dist/test/sheet/sheet-link.examples.js +41 -0
- package/dist/test/sheet/sheet-link.examples.js.map +1 -0
- package/dist/test/sheet/sheet-records.examples.d.ts +421 -0
- package/dist/test/sheet/sheet-records.examples.d.ts.map +1 -0
- package/dist/test/sheet/sheet-records.examples.js +79 -0
- package/dist/test/sheet/sheet-records.examples.js.map +1 -0
- package/dist/test/sheet/sheet-transactions.examples.d.ts +7 -0
- package/dist/test/sheet/sheet-transactions.examples.d.ts.map +1 -0
- package/dist/test/sheet/sheet-transactions.examples.js +58 -0
- package/dist/test/sheet/sheet-transactions.examples.js.map +1 -0
- package/dist/test/sheet/sheet.examples.d.ts +5562 -0
- package/dist/test/sheet/sheet.examples.d.ts.map +1 -0
- package/dist/test/sheet/sheet.examples.js +1178 -0
- package/dist/test/sheet/sheet.examples.js.map +1 -0
- package/dist/test/studio/studio.examples.d.ts.map +1 -1
- package/dist/test/studio/studio.examples.js +11 -11
- package/dist/test/studio/studio.examples.js.map +1 -1
- package/package.json +12 -9
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Plan value builders — shorthand resolvers, the instant sugar
|
|
7
|
+
* ({@link resolveInstant} / `Plan.at`), the axis declarations (`Plan.axis`,
|
|
8
|
+
* `.time` / `.number` / `.ordinal`), element value builders (`Plan.run` /
|
|
9
|
+
* `decision` / `port` / `event` / `marker` / `chip` / `mark`) and cell
|
|
10
|
+
* builders (`heatCells` / `weightCells` / `segmentCells` / `tableCells`).
|
|
11
|
+
* Every element is pure data — rich click/hover surfaces resolve through
|
|
12
|
+
* the ROOT's `popover` / `hover` functions over `PlanElementRefType`
|
|
13
|
+
* (`Plan Data Interface.md` §3.3), never per-element embeds.
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { East, Expr, ArrayType, BooleanType, DateTimeType, FloatType, IntegerType, OptionType, StringType, StructType, variant, some, none, } from "@elaraai/east";
|
|
18
|
+
import { EventStateType, IconType, StatusValueType, TimeResolutionType, } from "@elaraai/east-ui";
|
|
19
|
+
import { ColorSchemeType, MatrixFillType, TickFormatType, refuseNonSolid, resolveTag, } from "@elaraai/east-ui/internal";
|
|
20
|
+
import { PlanAxisType, PlanInstantType, PlanPortType, PlanCellMarkerType, PlanStretchType, PlanContentAlignType, PlanContentType, PlanAnimationType, PlanEventMarkKindType, PlanHeatCellType, PlanWeightCellType, PlanSegmentType, PlanSegmentCellType, PlanHeatCellsType, PlanTableCellType, PlanTableToneType, PlanTableSeriesType, PlanLinkType, PlanRunRefType, PlanRunType, PlanDecisionMarkType, PlanBucketEventType, PlanChipType, PlanEventMarkType, PlanLaneType, PlanRowIdType, PlanFoldType, PlanQuantityType, PlanHeatScaleType, PlanUiStateType, } from "./types.js";
|
|
21
|
+
import { eventRefKind } from "./refs.js";
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Shorthand resolvers
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Resolves the shared event-lifecycle string shorthands into an
|
|
27
|
+
* {@link EventStateType} value: `"estimated"`, `"added"`, `"recommended"`,
|
|
28
|
+
* `"removed"` (the three `proposed` flavours), `"confirmed"`,
|
|
29
|
+
* `"in-progress"`, `"actual"`, `"rejected"`.
|
|
30
|
+
*
|
|
31
|
+
* @param state - An `EventStateType` value/expression or a string shorthand
|
|
32
|
+
* @returns The resolved `EventStateType` value
|
|
33
|
+
*/
|
|
34
|
+
export function resolvePlanEventState(state) {
|
|
35
|
+
if (typeof state !== "string")
|
|
36
|
+
return state;
|
|
37
|
+
switch (state) {
|
|
38
|
+
case "estimated": return East.value(variant("estimated", null), EventStateType);
|
|
39
|
+
case "added": return East.value(variant("proposed", variant("added", null)), EventStateType);
|
|
40
|
+
case "recommended": return East.value(variant("proposed", variant("recommended", null)), EventStateType);
|
|
41
|
+
case "removed": return East.value(variant("proposed", variant("removed", null)), EventStateType);
|
|
42
|
+
case "confirmed": return East.value(variant("confirmed", null), EventStateType);
|
|
43
|
+
case "in-progress": return East.value(variant("in-progress", null), EventStateType);
|
|
44
|
+
case "actual": return East.value(variant("actual", null), EventStateType);
|
|
45
|
+
case "rejected": return East.value(variant("rejected", null), EventStateType);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Resolve a fold input, falling back to the default of what it folds.
|
|
50
|
+
*
|
|
51
|
+
* @param fold - The declared fold, if any
|
|
52
|
+
* @param fallback - The default for the values being folded (`mean` for levels, `sum` for amounts)
|
|
53
|
+
* @returns The fold
|
|
54
|
+
*/
|
|
55
|
+
export function resolveFold(fold, fallback) {
|
|
56
|
+
return resolveTag(fold ?? fallback, PlanFoldType);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Resolve a {@link PlanIconInput} into an `IconType` value.
|
|
60
|
+
*
|
|
61
|
+
* @param icon - The icon
|
|
62
|
+
* @param where - What takes it, as a refusal names it (`Plan.run icon`, …)
|
|
63
|
+
* @returns The icon as an `IconType` value or expression
|
|
64
|
+
* @throws {Error} When an icon given by value is not of Font Awesome's solid set (#1263)
|
|
65
|
+
*/
|
|
66
|
+
export function resolveIcon(icon, where = "Plan icon") {
|
|
67
|
+
if (typeof icon === "string") {
|
|
68
|
+
return East.value({ prefix: "fas", name: icon, label: none, style: none }, IconType);
|
|
69
|
+
}
|
|
70
|
+
refuseNonSolid(where, icon);
|
|
71
|
+
if (typeof icon.prefix === "string") {
|
|
72
|
+
return East.value({
|
|
73
|
+
prefix: icon.prefix,
|
|
74
|
+
name: icon.name,
|
|
75
|
+
label: none,
|
|
76
|
+
style: none,
|
|
77
|
+
}, IconType);
|
|
78
|
+
}
|
|
79
|
+
return icon;
|
|
80
|
+
}
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Instants — the axis-kind sugar
|
|
83
|
+
// ============================================================================
|
|
84
|
+
/**
|
|
85
|
+
* Resolves an instant input into a {@link PlanInstantType} value — the one
|
|
86
|
+
* place the arm is inferred (#631).
|
|
87
|
+
*
|
|
88
|
+
* @remarks
|
|
89
|
+
* The input is any {@link PlanInstantLikeType} value or expression. JS values
|
|
90
|
+
* wrap by their type (`Date` ⇒ `time`, `number` / `bigint` ⇒ `number`,
|
|
91
|
+
* `string` ⇒ `ordinal`); East expressions wrap by their STATIC type
|
|
92
|
+
* (`DateTimeType` ⇒ `time`, `FloatType` ⇒ `number`, `IntegerType` ⇒ `number`
|
|
93
|
+
* via `toFloat`, `StringType` ⇒ `ordinal`); a {@link PlanInstantType} value
|
|
94
|
+
* or expression passes through (subtype-checked by `East.value`). Nothing
|
|
95
|
+
* here knows the canvas axis — the arm is the INPUT's; the renderer holds it
|
|
96
|
+
* against the root's declaration.
|
|
97
|
+
*
|
|
98
|
+
* @param v - The instant (a value or expression of a {@link PlanInstantLikeType})
|
|
99
|
+
* @param where - The field being resolved, for the error message
|
|
100
|
+
* @returns The instant as a `PlanInstantType` expression
|
|
101
|
+
* @throws {Error} If `v` is an expression of a non-instant type
|
|
102
|
+
*/
|
|
103
|
+
export function resolveInstant(v, where) {
|
|
104
|
+
if (v instanceof Date)
|
|
105
|
+
return East.value(variant("time", v), PlanInstantType);
|
|
106
|
+
if (typeof v === "number")
|
|
107
|
+
return East.value(variant("number", v), PlanInstantType);
|
|
108
|
+
if (typeof v === "bigint")
|
|
109
|
+
return East.value(variant("number", Number(v)), PlanInstantType);
|
|
110
|
+
if (typeof v === "string")
|
|
111
|
+
return East.value(variant("ordinal", v), PlanInstantType);
|
|
112
|
+
if (v instanceof Expr) {
|
|
113
|
+
const tag = Expr.type(v).type;
|
|
114
|
+
switch (tag) {
|
|
115
|
+
case "DateTime": return East.value(variant("time", v), PlanInstantType);
|
|
116
|
+
case "Float": return East.value(variant("number", v), PlanInstantType);
|
|
117
|
+
case "Integer": return East.value(variant("number", v.toFloat()), PlanInstantType);
|
|
118
|
+
case "String": return East.value(variant("ordinal", v), PlanInstantType);
|
|
119
|
+
case "Variant": return East.value(v, PlanInstantType);
|
|
120
|
+
default:
|
|
121
|
+
throw new Error(`Plan: ${where} must be an instant — a Date / number / string, a DateTime / Float / ` +
|
|
122
|
+
`Integer / String expression, or a Plan.at.* value (got a ${tag} expression)`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// A plain variant VALUE (`variant("time", d)`, a decoded instant).
|
|
126
|
+
return East.value(v, PlanInstantType);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The `Plan.at` builders — one instant per axis kind, explicitly. The
|
|
130
|
+
* element builders already wrap by type; these are for element RECORDS
|
|
131
|
+
* written as data (`{ at: Plan.at.time(week(27n)), … }` in a
|
|
132
|
+
* `Plan.Types.HeatCell` array) and for reading as a declaration. Each
|
|
133
|
+
* result is BRANDED with its arm ({@link PlanInstantExpr}), so a cell
|
|
134
|
+
* list built from them carries the kind to the root's compile-time check.
|
|
135
|
+
*/
|
|
136
|
+
export const at = {
|
|
137
|
+
/**
|
|
138
|
+
* A `time` instant.
|
|
139
|
+
*
|
|
140
|
+
* @param v - The UTC instant (a `Date` or `DateTimeType` expression)
|
|
141
|
+
* @returns A `PlanInstantType` expression with the `time` arm, branded `"time"`
|
|
142
|
+
*/
|
|
143
|
+
time: (v) => East.value(variant("time", v), PlanInstantType),
|
|
144
|
+
/**
|
|
145
|
+
* A `number` instant.
|
|
146
|
+
*
|
|
147
|
+
* @param v - The position (a number or `FloatType` expression)
|
|
148
|
+
* @returns A `PlanInstantType` expression with the `number` arm, branded `"number"`
|
|
149
|
+
*/
|
|
150
|
+
number: (v) => East.value(variant("number", v), PlanInstantType),
|
|
151
|
+
/**
|
|
152
|
+
* An `ordinal` instant.
|
|
153
|
+
*
|
|
154
|
+
* @param v - The declared value (a string or `StringType` expression)
|
|
155
|
+
* @returns A `PlanInstantType` expression with the `ordinal` arm, branded `"ordinal"`
|
|
156
|
+
*/
|
|
157
|
+
ordinal: (v) => East.value(variant("ordinal", v), PlanInstantType),
|
|
158
|
+
};
|
|
159
|
+
// ============================================================================
|
|
160
|
+
// Axis — the three kinds
|
|
161
|
+
// ============================================================================
|
|
162
|
+
/**
|
|
163
|
+
* The axis values built WITHOUT a window (#822) — a canvas given one must bind
|
|
164
|
+
* a slice, whose range supplies the window, or the root refuses it at build
|
|
165
|
+
* time. An axis held in a variable (`$.const(Plan.axis(…))`) is not the value
|
|
166
|
+
* recorded here, so its canvas is held to the rule at render instead.
|
|
167
|
+
*/
|
|
168
|
+
export const WINDOWLESS_AXES = new WeakSet();
|
|
169
|
+
/**
|
|
170
|
+
* The kind of each axis value `Plan.axis` built (#1191) — what a Plan reads to
|
|
171
|
+
* refuse event kinds on a number or ordinal axis at build. An axis held in a
|
|
172
|
+
* variable is not the value recorded here, so its Plan checks it as it is
|
|
173
|
+
* evaluated instead.
|
|
174
|
+
*/
|
|
175
|
+
const AXIS_KINDS = new WeakMap();
|
|
176
|
+
/**
|
|
177
|
+
* The kind of an axis value `Plan.axis` built.
|
|
178
|
+
*
|
|
179
|
+
* @param axis - A Plan's `axis`
|
|
180
|
+
* @returns `"time"`, `"number"` or `"ordinal"`; `undefined` for an axis held in a variable
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
export function axisKindOf(axis) {
|
|
184
|
+
return typeof axis === "object" && axis !== null ? AXIS_KINDS.get(axis) : undefined;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Builds the `time` axis declaration — `Plan.axis({ … })` / `Plan.axis.time`.
|
|
188
|
+
*
|
|
189
|
+
* @param options - Window, resolution(s), now instant and tick format ({@link PlanAxisOptions})
|
|
190
|
+
* @returns An East expression of {@link PlanAxisType} (the `time` arm), branded `"time"` — the root's canvas kind
|
|
191
|
+
*
|
|
192
|
+
* @remarks
|
|
193
|
+
* The window is half-open `[min, max)` in UTC; omit it to follow the bound
|
|
194
|
+
* slice's datetime range — a canvas states one or the other (#822). There is
|
|
195
|
+
* no fit to the data. `resolutions` lists the WEEK/DAY-style segment options
|
|
196
|
+
* (omit ⇒ no segment). When the Plan is slice-bound, slice state supersedes
|
|
197
|
+
* window + resolution after mount — the slice is the single source of truth.
|
|
198
|
+
*/
|
|
199
|
+
export function createTimeAxis(options) {
|
|
200
|
+
const axis = East.value(variant("time", {
|
|
201
|
+
window: options.window !== undefined
|
|
202
|
+
? some({ min: options.window.min, max: options.window.max })
|
|
203
|
+
: none,
|
|
204
|
+
resolution: resolveTag(options.resolution, TimeResolutionType),
|
|
205
|
+
resolutions: (options.resolutions ?? []).map(r => resolveTag(r, TimeResolutionType)),
|
|
206
|
+
now: options.now !== undefined ? some(options.now) : none,
|
|
207
|
+
format: options.format !== undefined ? some(options.format) : none,
|
|
208
|
+
}), PlanAxisType);
|
|
209
|
+
if (options.window === undefined)
|
|
210
|
+
WINDOWLESS_AXES.add(axis);
|
|
211
|
+
AXIS_KINDS.set(axis, "time");
|
|
212
|
+
return axis;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Builds the `number` axis declaration — `Plan.axis.number({ … })`.
|
|
216
|
+
*
|
|
217
|
+
* @param options - Window, step, now position and tick format ({@link PlanNumberAxisOptions})
|
|
218
|
+
* @returns An East expression of {@link PlanAxisType} (the `number` arm), branded `"number"` — the root's canvas kind
|
|
219
|
+
* @throws {Error} If a literal `step` is not `> 0`
|
|
220
|
+
*
|
|
221
|
+
* @remarks
|
|
222
|
+
* `[min, max)` ÷ `step` = `n` buckets, edges on whole multiples of `step`
|
|
223
|
+
* (the `TimeResolution` rule, numerically). Omit the window to follow the
|
|
224
|
+
* bound slice's `float` / `integer` range — a canvas states one or the other
|
|
225
|
+
* (#822). Element instants on this canvas are numbers — a `FloatType` /
|
|
226
|
+
* `IntegerType` accessor or a bare number wraps to the `number` arm.
|
|
227
|
+
*/
|
|
228
|
+
export function createNumberAxis(options) {
|
|
229
|
+
if (typeof options.step === "number" && !(options.step > 0)) {
|
|
230
|
+
throw new Error(`Plan.axis.number: \`step\` must be > 0 (got ${options.step}) — it is the bucket width`);
|
|
231
|
+
}
|
|
232
|
+
const axis = East.value(variant("number", {
|
|
233
|
+
window: options.window !== undefined
|
|
234
|
+
? some({ min: options.window.min, max: options.window.max })
|
|
235
|
+
: none,
|
|
236
|
+
step: options.step,
|
|
237
|
+
now: options.now !== undefined ? some(options.now) : none,
|
|
238
|
+
format: options.format !== undefined ? some(options.format) : none,
|
|
239
|
+
}), PlanAxisType);
|
|
240
|
+
if (options.window === undefined)
|
|
241
|
+
WINDOWLESS_AXES.add(axis);
|
|
242
|
+
AXIS_KINDS.set(axis, "number");
|
|
243
|
+
return axis;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Builds the `ordinal` axis declaration — `Plan.axis.ordinal({ … })`.
|
|
247
|
+
*
|
|
248
|
+
* @param options - The ordered values and the now value ({@link PlanOrdinalAxisOptions})
|
|
249
|
+
* @returns An East expression of {@link PlanAxisType} (the `ordinal` arm), branded `"ordinal"` — the root's canvas kind
|
|
250
|
+
* @throws {Error} If a literal `values` list is empty
|
|
251
|
+
*
|
|
252
|
+
* @remarks
|
|
253
|
+
* The declared values ARE the buckets, one each, in order; the window is
|
|
254
|
+
* the whole list, so there is no slice range to brush and the window keys
|
|
255
|
+
* idle. Element instants on this canvas are the values — a `StringType`
|
|
256
|
+
* accessor or a bare string wraps to the `ordinal` arm.
|
|
257
|
+
*/
|
|
258
|
+
export function createOrdinalAxis(options) {
|
|
259
|
+
if (Array.isArray(options.values) && options.values.length === 0) {
|
|
260
|
+
throw new Error("Plan.axis.ordinal: `values` must list at least one value — the list is the axis");
|
|
261
|
+
}
|
|
262
|
+
const axis = East.value(variant("ordinal", {
|
|
263
|
+
values: East.value(options.values, ArrayType(StringType)),
|
|
264
|
+
now: options.now !== undefined ? some(options.now) : none,
|
|
265
|
+
}), PlanAxisType);
|
|
266
|
+
AXIS_KINDS.set(axis, "ordinal");
|
|
267
|
+
return axis;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Builds the shared axis declaration — `Plan.axis({ … })` is the `time`
|
|
271
|
+
* shorthand; `Plan.axis.time` / `.number` / `.ordinal` declare each kind.
|
|
272
|
+
*
|
|
273
|
+
* @param options - The time-axis options ({@link PlanAxisOptions})
|
|
274
|
+
* @returns An East expression of {@link PlanAxisType}, branded with its kind
|
|
275
|
+
*/
|
|
276
|
+
export const createAxis = Object.assign(function axis(options) { return createTimeAxis(options); }, { time: createTimeAxis, number: createNumberAxis, ordinal: createOrdinalAxis });
|
|
277
|
+
/**
|
|
278
|
+
* Builds a quantity — a number with its unit and how it prints (#824). A run
|
|
279
|
+
* carries one as its `quantity` (its bar prints it; a parent's rollup band sums
|
|
280
|
+
* its runs' per unit), and so does a link (its weight and its caption).
|
|
281
|
+
*
|
|
282
|
+
* @param value - The amount (a number or `FloatType` expression)
|
|
283
|
+
* @param options - Its unit, format and caption override ({@link PlanQuantityOptions})
|
|
284
|
+
* @returns An East expression of {@link PlanQuantityType}
|
|
285
|
+
*/
|
|
286
|
+
export function createQuantity(value, options) {
|
|
287
|
+
return East.value({
|
|
288
|
+
value,
|
|
289
|
+
unit: options?.unit !== undefined ? some(options.unit) : none,
|
|
290
|
+
format: options?.format !== undefined ? some(East.value(options.format, TickFormatType)) : none,
|
|
291
|
+
text: options?.text !== undefined ? some(options.text) : none,
|
|
292
|
+
}, PlanQuantityType);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Builds one span run from a flat input. The result is BRANDED with the axis
|
|
296
|
+
* kind `start` / `end` imply ({@link PlanKindOf}) — a `DateTimeType` accessor
|
|
297
|
+
* makes a `"time"` run, a `FloatType` one a `"number"` run — so the series and
|
|
298
|
+
* root can refuse a mismatched kind at compile time; an erased input (an
|
|
299
|
+
* `Expr<PlanInstantType>`) leaves the run unbranded.
|
|
300
|
+
*
|
|
301
|
+
* @typeParam S - The `start` input's type
|
|
302
|
+
* @typeParam E - The `end` input's type
|
|
303
|
+
* @param input - The run configuration ({@link PlanRunInput})
|
|
304
|
+
* @returns An East expression of {@link PlanRunType}, branded with its kind
|
|
305
|
+
*/
|
|
306
|
+
export function createRun(input) {
|
|
307
|
+
return East.value({
|
|
308
|
+
key: input.key,
|
|
309
|
+
start: resolveInstant(input.start, "run start"),
|
|
310
|
+
end: resolveInstant(input.end, "run end"),
|
|
311
|
+
label: input.label,
|
|
312
|
+
quantity: input.quantity !== undefined ? some(East.value(input.quantity, PlanQuantityType)) : none,
|
|
313
|
+
state: resolvePlanEventState(input.state),
|
|
314
|
+
status: input.status !== undefined ? some(resolveTag(input.status, StatusValueType)) : none,
|
|
315
|
+
moved: input.moved !== undefined ? some(typeof input.moved === "number" ? BigInt(input.moved) : input.moved) : none,
|
|
316
|
+
icon: input.icon !== undefined ? some(resolveIcon(input.icon, "Plan.run icon")) : none,
|
|
317
|
+
}, PlanRunType);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Builds one decision mark from a flat input, branded with `at`'s kind.
|
|
321
|
+
*
|
|
322
|
+
* @typeParam A - The `at` input's type
|
|
323
|
+
* @param input - The decision configuration ({@link PlanDecisionInput})
|
|
324
|
+
* @returns An East expression of {@link PlanDecisionMarkType}, branded with its kind
|
|
325
|
+
*/
|
|
326
|
+
export function createDecision(input) {
|
|
327
|
+
return East.value({
|
|
328
|
+
key: input.key,
|
|
329
|
+
at: resolveInstant(input.at, "decision at"),
|
|
330
|
+
applied: input.applied,
|
|
331
|
+
}, PlanDecisionMarkType);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Builds one port glyph from a flat input, branded with `at`'s kind.
|
|
335
|
+
*
|
|
336
|
+
* @typeParam A - The `at` input's type
|
|
337
|
+
* @param input - The port configuration ({@link PlanPortInput})
|
|
338
|
+
* @returns An East expression of {@link PlanPortType}, branded with its kind
|
|
339
|
+
*/
|
|
340
|
+
export function createPort(input) {
|
|
341
|
+
return East.value({
|
|
342
|
+
at: resolveInstant(input.at, "port at"),
|
|
343
|
+
label: input.label !== undefined ? some(input.label) : none,
|
|
344
|
+
}, PlanPortType);
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Builds one bucket event from a flat input, branded with `at`'s kind.
|
|
348
|
+
*
|
|
349
|
+
* @typeParam A - The `at` input's type
|
|
350
|
+
* @param input - The event configuration ({@link PlanBucketEventInput})
|
|
351
|
+
* @returns An East expression of {@link PlanBucketEventType}, branded with its kind
|
|
352
|
+
*/
|
|
353
|
+
export function createBucketEvent(input) {
|
|
354
|
+
const content = input.content !== undefined
|
|
355
|
+
? some(East.value({
|
|
356
|
+
horizontal: input.content.horizontal !== undefined ? some(resolveTag(input.content.horizontal, PlanContentAlignType)) : none,
|
|
357
|
+
vertical: input.content.vertical !== undefined ? some(resolveTag(input.content.vertical, PlanContentAlignType)) : none,
|
|
358
|
+
}, PlanContentType))
|
|
359
|
+
: none;
|
|
360
|
+
return East.value({
|
|
361
|
+
key: input.key,
|
|
362
|
+
at: resolveInstant(input.at, "event at"),
|
|
363
|
+
lane: input.lane !== undefined ? some(input.lane) : none,
|
|
364
|
+
label: input.label !== undefined ? some(input.label) : none,
|
|
365
|
+
icon: input.icon !== undefined ? some(resolveIcon(input.icon, "Plan.event icon")) : none,
|
|
366
|
+
state: resolvePlanEventState(input.state),
|
|
367
|
+
tone: input.tone !== undefined ? some(resolveTag(input.tone, StatusValueType)) : none,
|
|
368
|
+
color: input.color !== undefined ? some(input.color) : none,
|
|
369
|
+
colorPalette: input.colorPalette !== undefined ? some(resolveTag(input.colorPalette, ColorSchemeType)) : none,
|
|
370
|
+
stretch: input.stretch !== undefined ? some(resolveTag(input.stretch, PlanStretchType)) : none,
|
|
371
|
+
content,
|
|
372
|
+
animation: input.animation !== undefined ? some(resolveTag(input.animation, PlanAnimationType)) : none,
|
|
373
|
+
}, PlanBucketEventType);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Builds one bucket-row lane from a flat input.
|
|
377
|
+
*
|
|
378
|
+
* @param input - The lane configuration ({@link PlanLaneInput})
|
|
379
|
+
* @returns An East expression of {@link PlanLaneType}
|
|
380
|
+
*/
|
|
381
|
+
export function createLane(input) {
|
|
382
|
+
return East.value({
|
|
383
|
+
key: input.key,
|
|
384
|
+
label: input.label !== undefined ? some(input.label) : none,
|
|
385
|
+
}, PlanLaneType);
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* A row's id by its series and path — `Plan.ref("press-jobs", "H1", "p03")`
|
|
389
|
+
* is the row series `press-jobs` made from entry `p03` under `H1` (#822).
|
|
390
|
+
* What `links` name their ends with, and what a callback's row compares to.
|
|
391
|
+
*
|
|
392
|
+
* @remarks
|
|
393
|
+
* A segment is an entry's key as the canvas prints it: a String key as is, any
|
|
394
|
+
* other key type as its `.east` text (`printFor`), an `Array` child's index as
|
|
395
|
+
* its digits.
|
|
396
|
+
*
|
|
397
|
+
* @param series - The series key
|
|
398
|
+
* @param path - The entry keys that lead to the row, outermost first
|
|
399
|
+
* @returns The `entry` id
|
|
400
|
+
*/
|
|
401
|
+
export function createRef(series, ...path) {
|
|
402
|
+
return East.value(variant("entry", { series, path }), PlanRowIdType);
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* A section header's id — `Plan.sectionRef("crew-block", "H1")` is the
|
|
406
|
+
* `crew-block` section's header under entry `H1`; a top-level section's path
|
|
407
|
+
* is empty (#822).
|
|
408
|
+
*
|
|
409
|
+
* @param series - The section's series key
|
|
410
|
+
* @param path - The path of the entry the section sits under (empty at the top level)
|
|
411
|
+
* @returns The `section` id
|
|
412
|
+
*/
|
|
413
|
+
export function createSectionRef(series, ...path) {
|
|
414
|
+
return East.value(variant("section", { series, path }), PlanRowIdType);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Builds a {@link PlanUiStateType} value — the seed of a bound `ui` state
|
|
418
|
+
* (`State.bind([Plan.Types.UiState], key, Plan.uiState())`, #824). Omitted
|
|
419
|
+
* fields are empty: nothing selected, every row as it declares, no chart
|
|
420
|
+
* expanded, nothing to bring into view.
|
|
421
|
+
*
|
|
422
|
+
* @param init - What the state starts as ({@link PlanUiStateInput})
|
|
423
|
+
* @returns An East expression of {@link PlanUiStateType}
|
|
424
|
+
*/
|
|
425
|
+
export function createUiState(init) {
|
|
426
|
+
const ids = (list) => East.value((list ?? []), ArrayType(PlanRowIdType));
|
|
427
|
+
return East.value({
|
|
428
|
+
selected: init?.selected !== undefined ? some(East.value(init.selected, PlanRowIdType)) : none,
|
|
429
|
+
collapsed: ids(init?.collapsed),
|
|
430
|
+
expanded: ids(init?.expanded),
|
|
431
|
+
charts: ids(init?.charts),
|
|
432
|
+
focus: init?.focus !== undefined ? some(East.value(init.focus, PlanRowIdType)) : none,
|
|
433
|
+
}, PlanUiStateType);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* The event kinds each link `Plan.link` built names at its ends — none for a
|
|
437
|
+
* link between rows — by the value it returned (#1191). A link whose event end
|
|
438
|
+
* was held in a variable is not recorded: its kind is not known here.
|
|
439
|
+
*/
|
|
440
|
+
const LINK_EVENT_KINDS = new WeakMap();
|
|
441
|
+
/**
|
|
442
|
+
* The event kinds a link names at its ends, when they are known at build —
|
|
443
|
+
* what a Plan checks against its `events` (#1191).
|
|
444
|
+
*
|
|
445
|
+
* @param link - A link value
|
|
446
|
+
* @returns The kinds its event ends name, in order — none for a link between rows; `undefined` for a link
|
|
447
|
+
* `Plan.link` did not build here (held in a variable, or built in East) or whose event end was held in a
|
|
448
|
+
* variable, which a Plan checks as it is evaluated instead
|
|
449
|
+
* @internal
|
|
450
|
+
*/
|
|
451
|
+
export function linkEventKinds(link) {
|
|
452
|
+
return typeof link === "object" && link !== null ? LINK_EVENT_KINDS.get(link) : undefined;
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Whether a link end is an event (`Plan.eventRef`'s run ref, a struct) rather
|
|
456
|
+
* than a row's id (a variant).
|
|
457
|
+
*
|
|
458
|
+
* @param end - The end
|
|
459
|
+
* @returns `true` for an event
|
|
460
|
+
*/
|
|
461
|
+
function isEventEnd(end) {
|
|
462
|
+
return end instanceof Expr && Expr.type(end).type === "Struct";
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* One link end on the wire: a row's id with its run, or an event's ref as it is.
|
|
466
|
+
*
|
|
467
|
+
* @param end - The end — a row's id, or an event (`Plan.eventRef`)
|
|
468
|
+
* @param run - The run on the row
|
|
469
|
+
* @param name - `"from"` or `"to"`, for the message
|
|
470
|
+
* @returns The run ref
|
|
471
|
+
* @throws {Error} When a row's end has no run, or an event's end names one
|
|
472
|
+
*/
|
|
473
|
+
function linkEnd(end, run, name) {
|
|
474
|
+
if (isEventEnd(end)) {
|
|
475
|
+
if (run !== undefined) {
|
|
476
|
+
throw new Error(`Plan.link: \`${name}\` is an event, which names its own run — leave out \`${name}Run\``);
|
|
477
|
+
}
|
|
478
|
+
return end;
|
|
479
|
+
}
|
|
480
|
+
if (run === undefined) {
|
|
481
|
+
throw new Error(`Plan.link: \`${name}\` is a row's id — name the run on it with \`${name}Run\`, or name an event with Plan.eventRef(kind, key)`);
|
|
482
|
+
}
|
|
483
|
+
return { row: end, run };
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Builds one link edge from a flat input. Links are root DATA
|
|
487
|
+
* (`links={transfers.map(($, t) => Plan.link({ … }))}`): the links-focus
|
|
488
|
+
* control gathers a row's transitive upstream/downstream family over them.
|
|
489
|
+
*
|
|
490
|
+
* @param input - The link configuration ({@link PlanLinkInput})
|
|
491
|
+
* @returns An East expression of {@link PlanLinkType}
|
|
492
|
+
* @throws {Error} When an end is a row's id without its run, or an event with one
|
|
493
|
+
*/
|
|
494
|
+
export function createLink(input) {
|
|
495
|
+
const link = East.value({
|
|
496
|
+
key: input.key,
|
|
497
|
+
from: linkEnd(input.from, input.fromRun, "from"),
|
|
498
|
+
to: linkEnd(input.to, input.toRun, "to"),
|
|
499
|
+
quantity: input.quantity !== undefined ? some(East.value(input.quantity, PlanQuantityType)) : none,
|
|
500
|
+
}, PlanLinkType);
|
|
501
|
+
// The kinds its event ends name, when each is `Plan.eventRef`'s own value.
|
|
502
|
+
const kinds = [input.from, input.to].filter(isEventEnd).map(eventRefKind);
|
|
503
|
+
if (kinds.every((k) => k !== undefined))
|
|
504
|
+
LINK_EVENT_KINDS.set(link, kinds);
|
|
505
|
+
return link;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Builds one cell marker from a flat input, branded with `at`'s kind.
|
|
509
|
+
*
|
|
510
|
+
* @typeParam A - The `at` input's type
|
|
511
|
+
* @param input - The marker configuration ({@link PlanCellMarkerInput})
|
|
512
|
+
* @returns An East expression of {@link PlanCellMarkerType}, branded with its kind
|
|
513
|
+
*/
|
|
514
|
+
export function createCellMarker(input) {
|
|
515
|
+
return East.value({
|
|
516
|
+
at: resolveInstant(input.at, "marker at"),
|
|
517
|
+
lane: input.lane !== undefined ? some(input.lane) : none,
|
|
518
|
+
status: resolveTag(input.status ?? "danger", StatusValueType),
|
|
519
|
+
message: input.message,
|
|
520
|
+
}, PlanCellMarkerType);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Builds one cards chip from a flat input, branded with the kind `from` /
|
|
524
|
+
* `to` imply.
|
|
525
|
+
*
|
|
526
|
+
* @typeParam F - The `from` input's type
|
|
527
|
+
* @typeParam T - The `to` input's type
|
|
528
|
+
* @param input - The chip configuration ({@link PlanChipInput})
|
|
529
|
+
* @returns An East expression of {@link PlanChipType}, branded with its kind
|
|
530
|
+
*/
|
|
531
|
+
export function createChip(input) {
|
|
532
|
+
return East.value({
|
|
533
|
+
key: input.key,
|
|
534
|
+
from: resolveInstant(input.from, "chip from"),
|
|
535
|
+
to: resolveInstant(input.to, "chip to"),
|
|
536
|
+
label: input.label,
|
|
537
|
+
state: resolvePlanEventState(input.state),
|
|
538
|
+
icon: input.icon !== undefined ? some(resolveIcon(input.icon, "Plan.chip icon")) : none,
|
|
539
|
+
}, PlanChipType);
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Builds one event mark from a flat input, branded with `at`'s kind.
|
|
543
|
+
*
|
|
544
|
+
* @typeParam A - The `at` input's type
|
|
545
|
+
* @param input - The mark configuration ({@link PlanEventMarkInput})
|
|
546
|
+
* @returns An East expression of {@link PlanEventMarkType}, branded with its kind
|
|
547
|
+
*/
|
|
548
|
+
export function createEventMark(input) {
|
|
549
|
+
return East.value({
|
|
550
|
+
key: input.key,
|
|
551
|
+
at: resolveInstant(input.at, "mark at"),
|
|
552
|
+
kind: typeof input.kind === "string" ? East.value(variant(input.kind, null), PlanEventMarkKindType) : input.kind,
|
|
553
|
+
icon: input.icon !== undefined ? some(resolveIcon(input.icon, "Plan.mark icon")) : none,
|
|
554
|
+
label: input.label !== undefined ? some(input.label) : none,
|
|
555
|
+
}, PlanEventMarkType);
|
|
556
|
+
}
|
|
557
|
+
/** The `Plan.markKind` builders — non-null mark kinds. */
|
|
558
|
+
export const markKind = {
|
|
559
|
+
/**
|
|
560
|
+
* A decision diamond mark — ◇ pending / ◆ applied.
|
|
561
|
+
*
|
|
562
|
+
* @param applied - `true` fills the diamond
|
|
563
|
+
* @returns A `PlanEventMarkKindType` expression with the `decision` arm
|
|
564
|
+
*/
|
|
565
|
+
decision: (applied) => East.value(variant("decision", { applied }), PlanEventMarkKindType),
|
|
566
|
+
};
|
|
567
|
+
/**
|
|
568
|
+
* Build a heat scale value from its input.
|
|
569
|
+
*
|
|
570
|
+
* @param input - The scale ({@link PlanHeatScaleInput}); omit ⇒ every bound from the values shown
|
|
571
|
+
* @returns An East expression of {@link PlanHeatScaleType}
|
|
572
|
+
*/
|
|
573
|
+
export function createHeatScale(input) {
|
|
574
|
+
return East.value({
|
|
575
|
+
min: input?.min !== undefined ? some(input.min) : none,
|
|
576
|
+
max: input?.max !== undefined ? some(input.max) : none,
|
|
577
|
+
warnAt: input?.warnAt !== undefined ? some(input.warnAt) : none,
|
|
578
|
+
}, PlanHeatScaleType);
|
|
579
|
+
}
|
|
580
|
+
/** The declared `format`, as the arm's option. */
|
|
581
|
+
function formatOpt(format) {
|
|
582
|
+
return format !== undefined
|
|
583
|
+
? East.value(some(East.value(format, TickFormatType)), OptionType(TickFormatType))
|
|
584
|
+
: East.value(none, OptionType(TickFormatType));
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Wraps per-bucket heat cells into the `heat` arm of {@link PlanHeatCellsType}.
|
|
588
|
+
* Literal records whose `at` is a `Plan.at.*` value brand the result with
|
|
589
|
+
* that kind ({@link PlanCellsInput}); an East array is kind-erased.
|
|
590
|
+
*
|
|
591
|
+
* @remarks
|
|
592
|
+
* At a coarser resolution than the cells', a bucket shows ONE cell — the
|
|
593
|
+
* `fold` of the cells in it (`"mean"` by default: a heat cell is a level).
|
|
594
|
+
* A cell prints its `label`; one without prints its value only through a
|
|
595
|
+
* declared `format` (#824).
|
|
596
|
+
*
|
|
597
|
+
* @typeParam K - The kind inferred from the literal records' `at`
|
|
598
|
+
* @param cells - The cells (`{ at, value, label }` structs; `value: none` ⇒ the no-data hatch)
|
|
599
|
+
* @param options - Scale, warn threshold, fold and format ({@link PlanHeatCellsOptions})
|
|
600
|
+
* @returns A `PlanHeatCellsType` expression, branded with the cells' kind
|
|
601
|
+
*/
|
|
602
|
+
export function createHeatCells(cells, options) {
|
|
603
|
+
return East.value(variant("heat", {
|
|
604
|
+
cells: East.value(cells, ArrayType(PlanHeatCellType)),
|
|
605
|
+
scale: createHeatScale(options),
|
|
606
|
+
fold: resolveFold(options?.fold, "mean"),
|
|
607
|
+
format: formatOpt(options?.format),
|
|
608
|
+
}), PlanHeatCellsType);
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Wraps per-bucket weight cells into the `weight` arm of
|
|
612
|
+
* {@link PlanHeatCellsType} (booked-vs-free bars; planned ⇒ pale). Literal
|
|
613
|
+
* records with `Plan.at.*` instants brand the result with their kind.
|
|
614
|
+
*
|
|
615
|
+
* @remarks
|
|
616
|
+
* At a coarser resolution, a bucket shows ONE bar — the `fold` of its cells'
|
|
617
|
+
* fractions (`"mean"` by default: a cell is the fraction of its bucket booked,
|
|
618
|
+
* and a month's fraction is its weeks' mean), pale only when every cell in it
|
|
619
|
+
* is planned. `format` prints the fraction in the words a reader hears
|
|
620
|
+
* (default: a percent).
|
|
621
|
+
*
|
|
622
|
+
* @typeParam K - The kind inferred from the literal records' `at`
|
|
623
|
+
* @param cells - The cells (`{ at, fraction, planned }` structs)
|
|
624
|
+
* @param options - Fold and format ({@link PlanCellsFoldOptions})
|
|
625
|
+
* @returns A `PlanHeatCellsType` expression, branded with the cells' kind
|
|
626
|
+
*/
|
|
627
|
+
export function createWeightCells(cells, options) {
|
|
628
|
+
return East.value(variant("weight", {
|
|
629
|
+
cells: East.value(cells, ArrayType(PlanWeightCellType)),
|
|
630
|
+
fold: resolveFold(options?.fold, "mean"),
|
|
631
|
+
format: formatOpt(options?.format),
|
|
632
|
+
}), PlanHeatCellsType);
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Wraps per-bucket segment cells into the `segments` arm of
|
|
636
|
+
* {@link PlanHeatCellsType} (committed / pending / slack compositions).
|
|
637
|
+
* Literal records with `Plan.at.*` instants brand the result with their kind.
|
|
638
|
+
*
|
|
639
|
+
* @remarks
|
|
640
|
+
* At a coarser resolution, a bucket shows ONE composition — each fill's
|
|
641
|
+
* weights folded across the cells in it (`"sum"` by default: the weights are
|
|
642
|
+
* amounts, and the bar normalises them). `format` prints a segment's share in
|
|
643
|
+
* the words a reader hears (default: a percent).
|
|
644
|
+
*
|
|
645
|
+
* @typeParam K - The kind inferred from the literal records' `at`
|
|
646
|
+
* @param cells - The cells (`{ at, segments }` structs — build segments with `Plan.segment`)
|
|
647
|
+
* @param options - Fold and format ({@link PlanCellsFoldOptions})
|
|
648
|
+
* @returns A `PlanHeatCellsType` expression, branded with the cells' kind
|
|
649
|
+
*/
|
|
650
|
+
export function createSegmentCells(cells, options) {
|
|
651
|
+
return East.value(variant("segments", {
|
|
652
|
+
cells: East.value(cells, ArrayType(PlanSegmentCellType)),
|
|
653
|
+
fold: resolveFold(options?.fold, "sum"),
|
|
654
|
+
format: formatOpt(options?.format),
|
|
655
|
+
}), PlanHeatCellsType);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Builds one segment from a flat input (the Matrix segment vocabulary).
|
|
659
|
+
*
|
|
660
|
+
* @param input - The segment configuration ({@link PlanSegmentInput})
|
|
661
|
+
* @returns An East expression of {@link PlanSegmentType}
|
|
662
|
+
*/
|
|
663
|
+
export function createSegment(input) {
|
|
664
|
+
return East.value({
|
|
665
|
+
fill: resolveTag(input.fill, MatrixFillType),
|
|
666
|
+
weight: input.weight,
|
|
667
|
+
label: input.label !== undefined ? some(input.label) : none,
|
|
668
|
+
}, PlanSegmentType);
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Builds one table-row value series (see {@link Plan.table}'s `series`) —
|
|
672
|
+
* per-position style declared once, raw cells beneath it; the result carries
|
|
673
|
+
* the cells' axis kind.
|
|
674
|
+
*
|
|
675
|
+
* @typeParam K - The cells' axis kind
|
|
676
|
+
* @param input - The series configuration ({@link PlanTableSeriesInput})
|
|
677
|
+
* @returns An East expression of {@link PlanTableSeriesType}, branded with the cells' kind
|
|
678
|
+
*/
|
|
679
|
+
export function createTableSeries(input) {
|
|
680
|
+
return East.value({
|
|
681
|
+
cells: East.value(input.cells, ArrayType(PlanTableCellType)),
|
|
682
|
+
format: input.format !== undefined ? some(East.value(input.format, TickFormatType)) : none,
|
|
683
|
+
tone: input.tone !== undefined ? some(resolveTag(input.tone, PlanTableToneType)) : none,
|
|
684
|
+
strong: input.strong ?? false,
|
|
685
|
+
rollup: input.rollup ?? false,
|
|
686
|
+
fold: resolveFold(input.fold, "sum"),
|
|
687
|
+
}, PlanTableSeriesType);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Builds per-bucket table cells from raw values. The RENDERER prints each
|
|
691
|
+
* value through the row's `format` (a `Format.*` spec — the shared
|
|
692
|
+
* `TickFormatType`), tones negatives `neg` and renders `none` as the muted
|
|
693
|
+
* em-dash; build `PlanTableCellType` values directly for explicit `text` /
|
|
694
|
+
* `tone` overrides.
|
|
695
|
+
*
|
|
696
|
+
* @remarks
|
|
697
|
+
* The `at` of each raw cell wraps to the axis arm by its type — a
|
|
698
|
+
* `DateTimeType` field to `time`, a numeric field to `number`, a string
|
|
699
|
+
* field to `ordinal`, a {@link PlanInstantType} field as is — so a
|
|
700
|
+
* `{ at: DateTimeType, value }` dataset keeps compiling unchanged.
|
|
701
|
+
*
|
|
702
|
+
* Literal records brand the result with the kind their `at` implies
|
|
703
|
+
* ({@link PlanKindOf}); an East array is kind-erased.
|
|
704
|
+
*
|
|
705
|
+
* @typeParam A - The literal records' `at` type
|
|
706
|
+
* @param cells - The raw cells (`{ at, value }` records; `value` an `Option<Float>`)
|
|
707
|
+
* @returns An `ArrayType(PlanTableCellType)` expression, branded with the cells' kind
|
|
708
|
+
* @throws {Error} If an East array's element `at` is not an instant-typed field
|
|
709
|
+
*/
|
|
710
|
+
export function createTableCells(cells) {
|
|
711
|
+
if (Array.isArray(cells)) {
|
|
712
|
+
// Each element is a literal record or a struct expression; both
|
|
713
|
+
// expose `at` / `value` (a struct expression's field accessors carry
|
|
714
|
+
// the field's static type, which is what `resolveInstant` reads).
|
|
715
|
+
const built = cells.map((c) => {
|
|
716
|
+
const rec = c;
|
|
717
|
+
return East.value({
|
|
718
|
+
at: resolveInstant(rec.at, "tableCells at"),
|
|
719
|
+
value: East.value(rec.value, OptionType(FloatType)),
|
|
720
|
+
text: none,
|
|
721
|
+
tone: none,
|
|
722
|
+
}, PlanTableCellType);
|
|
723
|
+
});
|
|
724
|
+
return East.value(built, ArrayType(PlanTableCellType));
|
|
725
|
+
}
|
|
726
|
+
// An East array — wrap `at` by its STATIC element type, once for the map.
|
|
727
|
+
const raw = cells;
|
|
728
|
+
const elem = Expr.type(raw).value;
|
|
729
|
+
const atTag = (elem.fields.at).type;
|
|
730
|
+
const wrap = (v) => {
|
|
731
|
+
switch (atTag) {
|
|
732
|
+
case "DateTime": return East.value(variant("time", v), PlanInstantType);
|
|
733
|
+
case "Float": return East.value(variant("number", v), PlanInstantType);
|
|
734
|
+
case "Integer": return East.value(variant("number", v.toFloat()), PlanInstantType);
|
|
735
|
+
case "String": return East.value(variant("ordinal", v), PlanInstantType);
|
|
736
|
+
case "Variant": return East.value(v, PlanInstantType);
|
|
737
|
+
default:
|
|
738
|
+
throw new Error("Plan.tableCells: each cell's `at` must be an instant-typed field (DateTime / Float / " +
|
|
739
|
+
`Integer / String / Plan.Types.Instant) — got ${atTag}`);
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
return raw.map((_$, c) => East.value({
|
|
743
|
+
at: wrap(c.at),
|
|
744
|
+
value: c.value,
|
|
745
|
+
text: none,
|
|
746
|
+
tone: none,
|
|
747
|
+
}, PlanTableCellType));
|
|
748
|
+
}
|
|
749
|
+
//# sourceMappingURL=builders.js.map
|