@synnaxlabs/client 0.56.1 → 0.57.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/dist/client-B08VDLSA.js +14463 -0
- package/dist/client-B08VDLSA.js.map +1 -0
- package/dist/client.js +1128 -14876
- package/dist/client.js.map +1 -0
- package/dist/src/access/client.d.ts +10 -1
- package/dist/src/access/client.d.ts.map +1 -1
- package/dist/src/access/enforce.d.ts.map +1 -1
- package/dist/src/access/external.d.ts +1 -0
- package/dist/src/access/external.d.ts.map +1 -1
- package/dist/src/access/granted.d.ts +39 -0
- package/dist/src/access/granted.d.ts.map +1 -0
- package/dist/src/access/policy/client.d.ts +136 -147
- package/dist/src/access/policy/client.d.ts.map +1 -1
- package/dist/src/access/policy/types.gen.d.ts +15 -68
- package/dist/src/access/policy/types.gen.d.ts.map +1 -1
- package/dist/src/access/role/client.d.ts +77 -58
- package/dist/src/access/role/client.d.ts.map +1 -1
- package/dist/src/access/role/types.gen.d.ts +8 -14
- package/dist/src/access/role/types.gen.d.ts.map +1 -1
- package/dist/src/actions/actions.d.ts +5 -6
- package/dist/src/actions/actions.d.ts.map +1 -1
- package/dist/src/actions/controller.d.ts +194 -0
- package/dist/src/actions/controller.d.ts.map +1 -0
- package/dist/src/actions/external.d.ts +1 -0
- package/dist/src/actions/external.d.ts.map +1 -1
- package/dist/src/arc/actions.d.ts +575 -0
- package/dist/src/arc/actions.d.ts.map +1 -0
- package/dist/src/arc/actions.gen.d.ts +1439 -0
- package/dist/src/arc/actions.gen.d.ts.map +1 -0
- package/dist/src/arc/client.d.ts +97 -13
- package/dist/src/arc/client.d.ts.map +1 -1
- package/dist/src/arc/compiler/types.gen.d.ts +3 -3
- package/dist/src/arc/compiler/types.gen.d.ts.map +1 -1
- package/dist/src/arc/external.d.ts +2 -0
- package/dist/src/arc/external.d.ts.map +1 -1
- package/dist/src/arc/graph/types.gen.d.ts +45 -597
- package/dist/src/arc/graph/types.gen.d.ts.map +1 -1
- package/dist/src/arc/ir/index.d.ts +1 -1
- package/dist/src/arc/ir/index.d.ts.map +1 -1
- package/dist/src/arc/ir/ir.d.ts +2 -0
- package/dist/src/arc/ir/ir.d.ts.map +1 -0
- package/dist/src/arc/ir/types.gen.d.ts +58 -2807
- package/dist/src/arc/ir/types.gen.d.ts.map +1 -1
- package/dist/src/arc/module/types.gen.d.ts +18 -1090
- package/dist/src/arc/module/types.gen.d.ts.map +1 -1
- package/dist/src/arc/program/types.gen.d.ts +18 -1090
- package/dist/src/arc/program/types.gen.d.ts.map +1 -1
- package/dist/src/arc/text/types.gen.d.ts +54 -1
- package/dist/src/arc/text/types.gen.d.ts.map +1 -1
- package/dist/src/arc/types/types.gen.d.ts +35 -153
- package/dist/src/arc/types/types.gen.d.ts.map +1 -1
- package/dist/src/arc/types.gen.d.ts +98 -2278
- package/dist/src/arc/types.gen.d.ts.map +1 -1
- package/dist/src/auth/auth.d.ts +14 -2
- package/dist/src/auth/auth.d.ts.map +1 -1
- package/dist/src/channel/client.d.ts +113 -75
- package/dist/src/channel/client.d.ts.map +1 -1
- package/dist/src/channel/external.d.ts +0 -1
- package/dist/src/channel/external.d.ts.map +1 -1
- package/dist/src/channel/payload.d.ts +65 -56
- package/dist/src/channel/payload.d.ts.map +1 -1
- package/dist/src/channel/types.gen.d.ts +26 -73
- package/dist/src/channel/types.gen.d.ts.map +1 -1
- package/dist/src/channel/writer.d.ts +1 -3
- package/dist/src/channel/writer.d.ts.map +1 -1
- package/dist/src/client.d.ts +55 -27
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/connection/client.d.ts +146 -0
- package/dist/src/connection/client.d.ts.map +1 -0
- package/dist/src/connection/external.d.ts +3 -0
- package/dist/src/connection/external.d.ts.map +1 -0
- package/dist/src/connection/index.d.ts +1 -1
- package/dist/src/connection/index.d.ts.map +1 -1
- package/dist/src/connection/status.d.ts +252 -0
- package/dist/src/connection/status.d.ts.map +1 -0
- package/dist/src/control/client.d.ts +31 -7
- package/dist/src/control/client.d.ts.map +1 -1
- package/dist/src/control/state.d.ts +47 -16
- package/dist/src/control/state.d.ts.map +1 -1
- package/dist/src/device/client.d.ts +59 -17
- package/dist/src/device/client.d.ts.map +1 -1
- package/dist/src/device/types.gen.d.ts +17 -67
- package/dist/src/device/types.gen.d.ts.map +1 -1
- package/dist/src/errors.d.ts +17 -20
- package/dist/src/errors.d.ts.map +1 -1
- package/dist/src/ethercat/external.d.ts +2 -0
- package/dist/src/ethercat/external.d.ts.map +1 -0
- package/dist/src/ethercat/index.d.ts +2 -0
- package/dist/src/ethercat/index.d.ts.map +1 -0
- package/dist/src/ethercat/types.gen.d.ts +243 -0
- package/dist/src/ethercat/types.gen.d.ts.map +1 -0
- package/dist/src/framer/adapter.d.ts +8 -5
- package/dist/src/framer/adapter.d.ts.map +1 -1
- package/dist/src/framer/benchutil.d.ts +19 -0
- package/dist/src/framer/benchutil.d.ts.map +1 -0
- package/dist/src/framer/cache/cache.d.ts +38 -0
- package/dist/src/framer/cache/cache.d.ts.map +1 -0
- package/dist/src/framer/cache/dynamic.d.ts +71 -0
- package/dist/src/framer/cache/dynamic.d.ts.map +1 -0
- package/dist/src/framer/cache/reader.d.ts +43 -0
- package/dist/src/framer/cache/reader.d.ts.map +1 -0
- package/dist/src/framer/cache/static.d.ts +66 -0
- package/dist/src/framer/cache/static.d.ts.map +1 -0
- package/dist/src/framer/cache/streamer.d.ts +86 -0
- package/dist/src/framer/cache/streamer.d.ts.map +1 -0
- package/dist/src/framer/cache/transform.d.ts +18 -0
- package/dist/src/framer/cache/transform.d.ts.map +1 -0
- package/dist/src/framer/cache/unary.d.ts +37 -0
- package/dist/src/framer/cache/unary.d.ts.map +1 -0
- package/dist/src/framer/client.d.ts +35 -14
- package/dist/src/framer/client.d.ts.map +1 -1
- package/dist/src/framer/codec.d.ts.map +1 -1
- package/dist/src/framer/deleter.d.ts +3 -2
- package/dist/src/framer/deleter.d.ts.map +1 -1
- package/dist/src/framer/external.d.ts +6 -0
- package/dist/src/framer/external.d.ts.map +1 -1
- package/dist/src/framer/feed.d.ts +40 -0
- package/dist/src/framer/feed.d.ts.map +1 -0
- package/dist/src/framer/frame.d.ts +16 -20
- package/dist/src/framer/frame.d.ts.map +1 -1
- package/dist/src/framer/hardened.d.ts +70 -0
- package/dist/src/framer/hardened.d.ts.map +1 -0
- package/dist/src/framer/iterator.d.ts +36 -43
- package/dist/src/framer/iterator.d.ts.map +1 -1
- package/dist/src/framer/reader.d.ts +3 -2
- package/dist/src/framer/reader.d.ts.map +1 -1
- package/dist/src/framer/streamer.d.ts +132 -205
- package/dist/src/framer/streamer.d.ts.map +1 -1
- package/dist/src/framer/writer.d.ts +130 -161
- package/dist/src/framer/writer.d.ts.map +1 -1
- package/dist/src/group/client.d.ts +66 -9
- package/dist/src/group/client.d.ts.map +1 -1
- package/dist/src/group/types.gen.d.ts +2 -2
- package/dist/src/http/external.d.ts +2 -0
- package/dist/src/http/external.d.ts.map +1 -0
- package/dist/src/http/index.d.ts +2 -0
- package/dist/src/http/index.d.ts.map +1 -0
- package/dist/src/http/types.gen.d.ts +451 -0
- package/dist/src/http/types.gen.d.ts.map +1 -0
- package/dist/src/imex/client.d.ts +88 -0
- package/dist/src/imex/client.d.ts.map +1 -0
- package/dist/src/imex/index.d.ts +2 -0
- package/dist/src/imex/index.d.ts.map +1 -0
- package/dist/src/index.d.ts +18 -5
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/label/client.d.ts +55 -36
- package/dist/src/label/client.d.ts.map +1 -1
- package/dist/src/label/external.d.ts +2 -0
- package/dist/src/label/external.d.ts.map +1 -1
- package/dist/src/label/payload.d.ts +4 -46
- package/dist/src/label/payload.d.ts.map +1 -1
- package/dist/src/label/store.d.ts +8 -0
- package/dist/src/label/store.d.ts.map +1 -0
- package/dist/src/label/types.gen.d.ts +45 -0
- package/dist/src/label/types.gen.d.ts.map +1 -0
- package/dist/src/labjack/external.d.ts +2 -0
- package/dist/src/labjack/external.d.ts.map +1 -0
- package/dist/src/labjack/index.d.ts +2 -0
- package/dist/src/labjack/index.d.ts.map +1 -0
- package/dist/src/labjack/types.gen.d.ts +442 -0
- package/dist/src/labjack/types.gen.d.ts.map +1 -0
- package/dist/src/lineplot/actions.d.ts +914 -0
- package/dist/src/lineplot/actions.d.ts.map +1 -0
- package/dist/src/lineplot/actions.gen.d.ts +4208 -0
- package/dist/src/lineplot/actions.gen.d.ts.map +1 -0
- package/dist/src/lineplot/client.d.ts +66 -16
- package/dist/src/lineplot/client.d.ts.map +1 -1
- package/dist/src/lineplot/external.d.ts +3 -0
- package/dist/src/lineplot/external.d.ts.map +1 -1
- package/dist/src/lineplot/line.d.ts +16 -0
- package/dist/src/lineplot/line.d.ts.map +1 -0
- package/dist/src/lineplot/types.gen.d.ts +837 -14
- package/dist/src/lineplot/types.gen.d.ts.map +1 -1
- package/dist/src/log/actions.d.ts +271 -0
- package/dist/src/log/actions.d.ts.map +1 -0
- package/dist/src/log/actions.gen.d.ts +1529 -0
- package/dist/src/log/actions.gen.d.ts.map +1 -0
- package/dist/src/log/client.d.ts +66 -16
- package/dist/src/log/client.d.ts.map +1 -1
- package/dist/src/log/external.d.ts +2 -0
- package/dist/src/log/external.d.ts.map +1 -1
- package/dist/src/log/types.gen.d.ts +139 -14
- package/dist/src/log/types.gen.d.ts.map +1 -1
- package/dist/src/modbus/external.d.ts +2 -0
- package/dist/src/modbus/external.d.ts.map +1 -0
- package/dist/src/modbus/index.d.ts +2 -0
- package/dist/src/modbus/index.d.ts.map +1 -0
- package/dist/src/modbus/types.gen.d.ts +280 -0
- package/dist/src/modbus/types.gen.d.ts.map +1 -0
- package/dist/src/ni/external.d.ts +2 -0
- package/dist/src/ni/external.d.ts.map +1 -0
- package/dist/src/ni/index.d.ts +2 -0
- package/dist/src/ni/index.d.ts.map +1 -0
- package/dist/src/ni/types.gen.d.ts +21029 -0
- package/dist/src/ni/types.gen.d.ts.map +1 -0
- package/dist/src/node/index.d.ts +2 -0
- package/dist/src/node/index.d.ts.map +1 -0
- package/dist/src/node/types.gen.d.ts +4 -0
- package/dist/src/node/types.gen.d.ts.map +1 -0
- package/dist/src/ontology/client.d.ts +314 -67
- package/dist/src/ontology/client.d.ts.map +1 -1
- package/dist/src/ontology/external.d.ts +1 -0
- package/dist/src/ontology/external.d.ts.map +1 -1
- package/dist/src/ontology/payload.d.ts +60 -18
- package/dist/src/ontology/payload.d.ts.map +1 -1
- package/dist/src/ontology/store.d.ts +32 -0
- package/dist/src/ontology/store.d.ts.map +1 -0
- package/dist/src/ontology/types.gen.d.ts +3 -2
- package/dist/src/ontology/types.gen.d.ts.map +1 -1
- package/dist/src/ontology/writer.d.ts +16 -10
- package/dist/src/ontology/writer.d.ts.map +1 -1
- package/dist/src/opcua/external.d.ts +2 -0
- package/dist/src/opcua/external.d.ts.map +1 -0
- package/dist/src/opcua/index.d.ts +2 -0
- package/dist/src/opcua/index.d.ts.map +1 -0
- package/dist/src/opcua/types.gen.d.ts +82 -0
- package/dist/src/opcua/types.gen.d.ts.map +1 -0
- package/dist/src/pagerduty/external.d.ts +2 -0
- package/dist/src/pagerduty/external.d.ts.map +1 -0
- package/dist/src/pagerduty/index.d.ts +2 -0
- package/dist/src/pagerduty/index.d.ts.map +1 -0
- package/dist/src/pagerduty/types.gen.d.ts +30 -0
- package/dist/src/pagerduty/types.gen.d.ts.map +1 -0
- package/dist/src/panel/actions.d.ts +273 -0
- package/dist/src/panel/actions.d.ts.map +1 -0
- package/dist/src/panel/actions.gen.d.ts +1255 -0
- package/dist/src/panel/actions.gen.d.ts.map +1 -0
- package/dist/src/panel/client.d.ts +148 -0
- package/dist/src/panel/client.d.ts.map +1 -0
- package/dist/src/panel/external.d.ts +6 -0
- package/dist/src/panel/external.d.ts.map +1 -0
- package/dist/src/panel/index.d.ts +2 -0
- package/dist/src/panel/index.d.ts.map +1 -0
- package/dist/src/panel/tree.d.ts +50 -0
- package/dist/src/panel/tree.d.ts.map +1 -0
- package/dist/src/panel/types.gen.d.ts +370 -0
- package/dist/src/panel/types.gen.d.ts.map +1 -0
- package/dist/src/project/client.d.ts +89 -0
- package/dist/src/project/client.d.ts.map +1 -0
- package/dist/src/project/external.d.ts.map +1 -0
- package/dist/src/project/index.d.ts +2 -0
- package/dist/src/project/index.d.ts.map +1 -0
- package/dist/src/project/types.gen.d.ts +27 -0
- package/dist/src/project/types.gen.d.ts.map +1 -0
- package/dist/src/query/cache.d.ts +132 -0
- package/dist/src/query/cache.d.ts.map +1 -0
- package/dist/src/query/deleted.d.ts +20 -0
- package/dist/src/query/deleted.d.ts.map +1 -0
- package/dist/src/query/derived.d.ts +33 -0
- package/dist/src/query/derived.d.ts.map +1 -0
- package/dist/src/query/external.d.ts +10 -0
- package/dist/src/query/external.d.ts.map +1 -0
- package/dist/src/query/index.d.ts +2 -0
- package/dist/src/query/index.d.ts.map +1 -0
- package/dist/src/query/query.d.ts +235 -0
- package/dist/src/query/query.d.ts.map +1 -0
- package/dist/src/query/retriever.d.ts +135 -0
- package/dist/src/query/retriever.d.ts.map +1 -0
- package/dist/src/query/streamer.d.ts +67 -0
- package/dist/src/query/streamer.d.ts.map +1 -0
- package/dist/src/query/table.d.ts +219 -0
- package/dist/src/query/table.d.ts.map +1 -0
- package/dist/src/query/types.d.ts +35 -0
- package/dist/src/query/types.d.ts.map +1 -0
- package/dist/src/query/write.d.ts +21 -0
- package/dist/src/query/write.d.ts.map +1 -0
- package/dist/src/rack/client.d.ts +58 -20
- package/dist/src/rack/client.d.ts.map +1 -1
- package/dist/src/rack/types.gen.d.ts +11 -12
- package/dist/src/rack/types.gen.d.ts.map +1 -1
- package/dist/src/range/alias/types.gen.d.ts +2 -3
- package/dist/src/range/alias/types.gen.d.ts.map +1 -1
- package/dist/src/ranger/client.d.ts +138 -27
- package/dist/src/ranger/client.d.ts.map +1 -1
- package/dist/src/ranger/kv/client.d.ts +7 -4
- package/dist/src/ranger/kv/client.d.ts.map +1 -1
- package/dist/src/ranger/payload.d.ts +3 -0
- package/dist/src/ranger/payload.d.ts.map +1 -1
- package/dist/src/ranger/types.gen.d.ts +45 -101
- package/dist/src/ranger/types.gen.d.ts.map +1 -1
- package/dist/src/ranger/writer.d.ts +2 -74
- package/dist/src/ranger/writer.d.ts.map +1 -1
- package/dist/src/schematic/actions.d.ts +90 -33
- package/dist/src/schematic/actions.d.ts.map +1 -1
- package/dist/src/schematic/actions.gen.d.ts +207 -114
- package/dist/src/schematic/actions.gen.d.ts.map +1 -1
- package/dist/src/schematic/client.d.ts +70 -68
- package/dist/src/schematic/client.d.ts.map +1 -1
- package/dist/src/schematic/symbol/client.d.ts +133 -27
- package/dist/src/schematic/symbol/client.d.ts.map +1 -1
- package/dist/src/schematic/symbol/types.gen.d.ts +258 -153
- package/dist/src/schematic/symbol/types.gen.d.ts.map +1 -1
- package/dist/src/schematic/types.gen.d.ts +17 -96
- package/dist/src/schematic/types.gen.d.ts.map +1 -1
- package/dist/src/status/client.d.ts +69 -14
- package/dist/src/status/client.d.ts.map +1 -1
- package/dist/src/status/external.d.ts +2 -0
- package/dist/src/status/external.d.ts.map +1 -1
- package/dist/src/status/payload.d.ts +2 -36
- package/dist/src/status/payload.d.ts.map +1 -1
- package/dist/src/status/status.d.ts +65 -0
- package/dist/src/status/status.d.ts.map +1 -0
- package/dist/src/status/types.gen.d.ts +58 -0
- package/dist/src/status/types.gen.d.ts.map +1 -0
- package/dist/src/table/actions.d.ts +72 -13
- package/dist/src/table/actions.d.ts.map +1 -1
- package/dist/src/table/actions.gen.d.ts +221 -137
- package/dist/src/table/actions.gen.d.ts.map +1 -1
- package/dist/src/table/client.d.ts +64 -40
- package/dist/src/table/client.d.ts.map +1 -1
- package/dist/src/table/types.gen.d.ts +20 -55
- package/dist/src/table/types.gen.d.ts.map +1 -1
- package/dist/src/task/client.d.ts +149 -28
- package/dist/src/task/client.d.ts.map +1 -1
- package/dist/src/task/types.gen.d.ts +71 -89
- package/dist/src/task/types.gen.d.ts.map +1 -1
- package/dist/src/testutil/access.d.ts +27 -1
- package/dist/src/testutil/access.d.ts.map +1 -1
- package/dist/src/testutil/channels.d.ts +2 -0
- package/dist/src/testutil/channels.d.ts.map +1 -1
- package/dist/src/testutil/client.d.ts +5 -0
- package/dist/src/testutil/client.d.ts.map +1 -1
- package/dist/src/testutil/connection.d.ts +10 -0
- package/dist/src/testutil/connection.d.ts.map +1 -0
- package/dist/src/testutil/index.d.ts +9 -0
- package/dist/src/testutil/index.d.ts.map +1 -0
- package/dist/src/testutil/panels.d.ts +8 -0
- package/dist/src/testutil/panels.d.ts.map +1 -0
- package/dist/src/testutil/proxy.d.ts +29 -0
- package/dist/src/testutil/proxy.d.ts.map +1 -0
- package/dist/src/testutil/query.d.ts +7 -0
- package/dist/src/testutil/query.d.ts.map +1 -0
- package/dist/src/testutil/telem.d.ts +4 -0
- package/dist/src/testutil/telem.d.ts.map +1 -1
- package/dist/src/transport.d.ts +10 -4
- package/dist/src/transport.d.ts.map +1 -1
- package/dist/src/user/client.d.ts +29 -28
- package/dist/src/user/client.d.ts.map +1 -1
- package/dist/src/user/external.d.ts +1 -1
- package/dist/src/user/external.d.ts.map +1 -1
- package/dist/src/user/types.gen.d.ts +4 -4
- package/dist/src/util/retrieve.d.ts +2 -2
- package/dist/src/util/retrieve.d.ts.map +1 -1
- package/dist/src/util/telem.d.ts.map +1 -1
- package/dist/src/view/client.d.ts +30 -14
- package/dist/src/view/client.d.ts.map +1 -1
- package/dist/src/view/types.gen.d.ts +7 -15
- package/dist/src/view/types.gen.d.ts.map +1 -1
- package/dist/testutil.js +189 -0
- package/dist/testutil.js.map +1 -0
- package/package.json +40 -17
- package/src/access/client.ts +14 -3
- package/src/access/enforce.ts +0 -3
- package/src/access/external.ts +1 -0
- package/src/access/granted.ts +114 -0
- package/src/access/policy/client.ts +135 -43
- package/src/access/policy/types.gen.ts +9 -11
- package/src/access/role/client.ts +160 -38
- package/src/access/role/types.gen.ts +8 -12
- package/src/actions/actions.ts +5 -6
- package/src/actions/controller.ts +626 -0
- package/src/actions/external.ts +11 -0
- package/src/arc/actions.gen.ts +313 -0
- package/src/arc/actions.ts +192 -0
- package/src/arc/client.ts +424 -41
- package/src/arc/compiler/types.gen.ts +5 -6
- package/src/arc/external.ts +2 -0
- package/src/arc/graph/types.gen.ts +24 -22
- package/src/arc/ir/index.ts +1 -1
- package/{eslint.config.ts → src/arc/ir/ir.ts} +1 -4
- package/src/arc/ir/types.gen.ts +42 -41
- package/src/arc/text/types.gen.ts +21 -2
- package/src/arc/types/types.gen.ts +40 -32
- package/src/arc/types.gen.ts +31 -29
- package/src/auth/auth.ts +40 -8
- package/src/channel/client.ts +529 -132
- package/src/channel/external.ts +0 -1
- package/src/channel/payload.ts +30 -3
- package/src/channel/types.gen.ts +37 -48
- package/src/channel/writer.ts +2 -11
- package/src/client.ts +215 -91
- package/src/connection/client.ts +495 -0
- package/src/connection/external.ts +34 -0
- package/src/connection/index.ts +1 -1
- package/src/connection/status.ts +442 -0
- package/src/control/client.ts +84 -12
- package/src/control/state.ts +17 -36
- package/src/device/client.ts +293 -41
- package/src/device/types.gen.ts +15 -26
- package/src/errors.ts +45 -22
- package/src/{workspace → ethercat}/external.ts +1 -2
- package/src/{workspace → ethercat}/index.ts +1 -1
- package/src/ethercat/types.gen.ts +151 -0
- package/src/framer/adapter.ts +60 -37
- package/src/framer/benchutil.ts +67 -0
- package/src/framer/cache/cache.ts +115 -0
- package/src/framer/cache/dynamic.ts +279 -0
- package/src/framer/cache/reader.ts +160 -0
- package/src/framer/cache/static.ts +215 -0
- package/src/framer/cache/streamer.ts +391 -0
- package/src/framer/cache/transform.ts +31 -0
- package/src/framer/cache/unary.ts +104 -0
- package/src/framer/client.ts +71 -43
- package/src/framer/codec.ts +55 -18
- package/src/framer/deleter.ts +4 -6
- package/src/framer/external.ts +10 -0
- package/src/framer/feed.ts +108 -0
- package/src/framer/frame.ts +13 -23
- package/src/framer/hardened.ts +283 -0
- package/src/framer/iterator.ts +31 -42
- package/src/framer/reader.ts +11 -11
- package/src/framer/streamer.ts +18 -178
- package/src/framer/writer.ts +39 -59
- package/src/group/client.ts +158 -23
- package/src/http/external.ts +10 -0
- package/src/{cluster → http}/index.ts +1 -1
- package/src/http/types.gen.ts +245 -0
- package/src/imex/client.ts +125 -0
- package/src/imex/index.ts +10 -0
- package/src/index.ts +18 -6
- package/src/label/client.ts +193 -54
- package/src/label/external.ts +2 -0
- package/src/label/payload.ts +4 -9
- package/src/label/store.ts +28 -0
- package/src/label/types.gen.ts +31 -0
- package/src/labjack/external.ts +10 -0
- package/src/labjack/index.ts +10 -0
- package/src/labjack/types.gen.ts +251 -0
- package/src/lineplot/actions.gen.ts +880 -0
- package/src/lineplot/actions.ts +535 -0
- package/src/lineplot/client.ts +224 -52
- package/src/lineplot/external.ts +3 -0
- package/src/lineplot/line.ts +80 -0
- package/src/lineplot/types.gen.ts +225 -12
- package/src/log/actions.gen.ts +474 -0
- package/src/log/actions.ts +242 -0
- package/src/log/client.ts +223 -52
- package/src/log/external.ts +2 -0
- package/src/log/types.gen.ts +45 -14
- package/src/modbus/external.ts +10 -0
- package/src/modbus/index.ts +10 -0
- package/src/modbus/types.gen.ts +185 -0
- package/src/ni/external.ts +10 -0
- package/src/ni/index.ts +10 -0
- package/src/ni/types.gen.ts +1632 -0
- package/src/node/index.ts +10 -0
- package/src/{cluster → node}/types.gen.ts +2 -2
- package/src/ontology/client.ts +408 -99
- package/src/ontology/external.ts +7 -0
- package/src/ontology/payload.ts +48 -7
- package/src/ontology/store.ts +83 -0
- package/src/ontology/types.gen.ts +2 -1
- package/src/ontology/writer.ts +1 -0
- package/src/opcua/external.ts +10 -0
- package/src/opcua/index.ts +10 -0
- package/src/opcua/types.gen.ts +65 -0
- package/src/pagerduty/external.ts +10 -0
- package/src/pagerduty/index.ts +10 -0
- package/src/pagerduty/types.gen.ts +41 -0
- package/src/panel/actions.gen.ts +267 -0
- package/src/panel/actions.ts +357 -0
- package/src/panel/client.ts +327 -0
- package/src/panel/external.ts +14 -0
- package/src/panel/index.ts +10 -0
- package/src/panel/tree.ts +163 -0
- package/src/panel/types.gen.ts +164 -0
- package/src/project/client.ts +273 -0
- package/src/project/external.ts +11 -0
- package/src/project/index.ts +10 -0
- package/src/project/types.gen.ts +40 -0
- package/src/query/cache.ts +326 -0
- package/src/query/deleted.ts +38 -0
- package/src/query/derived.ts +101 -0
- package/src/query/external.ts +51 -0
- package/src/query/index.ts +10 -0
- package/src/query/query.ts +865 -0
- package/src/query/retriever.ts +308 -0
- package/src/query/streamer.ts +207 -0
- package/src/query/table.ts +625 -0
- package/src/query/types.ts +54 -0
- package/src/query/write.ts +42 -0
- package/src/rack/client.ts +233 -45
- package/src/rack/types.gen.ts +15 -16
- package/src/range/alias/types.gen.ts +2 -3
- package/src/ranger/client.ts +581 -70
- package/src/ranger/kv/client.ts +52 -21
- package/src/ranger/payload.ts +3 -0
- package/src/ranger/types.gen.ts +21 -23
- package/src/ranger/writer.ts +4 -8
- package/src/schematic/actions.gen.ts +62 -53
- package/src/schematic/actions.ts +44 -42
- package/src/schematic/client.ts +226 -70
- package/src/schematic/symbol/client.ts +277 -48
- package/src/schematic/symbol/types.gen.ts +22 -34
- package/src/schematic/types.gen.ts +22 -29
- package/src/status/client.ts +321 -44
- package/src/status/external.ts +2 -0
- package/src/status/payload.ts +1 -23
- package/src/status/status.ts +241 -0
- package/src/status/types.gen.ts +108 -0
- package/src/table/actions.gen.ts +96 -63
- package/src/table/actions.ts +44 -19
- package/src/table/client.ts +220 -56
- package/src/table/types.gen.ts +24 -31
- package/src/task/client.ts +580 -101
- package/src/task/types.gen.ts +68 -75
- package/src/testutil/access.ts +102 -6
- package/src/testutil/channels.ts +29 -0
- package/src/testutil/client.ts +27 -2
- package/src/testutil/connection.ts +47 -0
- package/src/testutil/index.ts +17 -0
- package/src/testutil/panels.ts +26 -0
- package/src/testutil/proxy.ts +106 -0
- package/src/testutil/query.ts +28 -0
- package/src/testutil/telem.ts +17 -1
- package/src/transport.ts +18 -7
- package/src/user/client.ts +165 -64
- package/src/user/external.ts +1 -1
- package/src/user/types.gen.ts +5 -5
- package/src/util/retrieve.ts +4 -4
- package/src/util/telem.ts +0 -1
- package/src/view/client.ts +120 -37
- package/src/view/types.gen.ts +8 -11
- package/.turbo/turbo-build.log +0 -20
- package/.vscode/settings.json +0 -3
- package/CONTRIBUTING.md +0 -47
- package/dist/client.cjs +0 -118
- package/dist/eslint.config.d.ts +0 -4
- package/dist/eslint.config.d.ts.map +0 -1
- package/dist/src/access/enforce.spec.d.ts +0 -2
- package/dist/src/access/enforce.spec.d.ts.map +0 -1
- package/dist/src/access/policy/access.spec.d.ts +0 -2
- package/dist/src/access/policy/access.spec.d.ts.map +0 -1
- package/dist/src/access/role/role.spec.d.ts +0 -2
- package/dist/src/access/role/role.spec.d.ts.map +0 -1
- package/dist/src/actions/actions.spec.d.ts +0 -2
- package/dist/src/actions/actions.spec.d.ts.map +0 -1
- package/dist/src/arc/access.spec.d.ts +0 -2
- package/dist/src/arc/access.spec.d.ts.map +0 -1
- package/dist/src/arc/arc.spec.d.ts +0 -2
- package/dist/src/arc/arc.spec.d.ts.map +0 -1
- package/dist/src/arc/lsp.spec.d.ts +0 -2
- package/dist/src/arc/lsp.spec.d.ts.map +0 -1
- package/dist/src/auth/auth.spec.d.ts +0 -2
- package/dist/src/auth/auth.spec.d.ts.map +0 -1
- package/dist/src/channel/access.spec.d.ts +0 -2
- package/dist/src/channel/access.spec.d.ts.map +0 -1
- package/dist/src/channel/batchRetriever.spec.d.ts +0 -2
- package/dist/src/channel/batchRetriever.spec.d.ts.map +0 -1
- package/dist/src/channel/channel.spec.d.ts +0 -2
- package/dist/src/channel/channel.spec.d.ts.map +0 -1
- package/dist/src/channel/payload.spec.d.ts +0 -2
- package/dist/src/channel/payload.spec.d.ts.map +0 -1
- package/dist/src/channel/retriever.d.ts +0 -64
- package/dist/src/channel/retriever.d.ts.map +0 -1
- package/dist/src/cluster/index.d.ts +0 -2
- package/dist/src/cluster/index.d.ts.map +0 -1
- package/dist/src/cluster/types.gen.d.ts +0 -4
- package/dist/src/cluster/types.gen.d.ts.map +0 -1
- package/dist/src/connection/checker.d.ts +0 -86
- package/dist/src/connection/checker.d.ts.map +0 -1
- package/dist/src/connection/connection.spec.d.ts +0 -2
- package/dist/src/connection/connection.spec.d.ts.map +0 -1
- package/dist/src/connection.spec.d.ts +0 -2
- package/dist/src/connection.spec.d.ts.map +0 -1
- package/dist/src/control/state.spec.d.ts +0 -2
- package/dist/src/control/state.spec.d.ts.map +0 -1
- package/dist/src/device/access.spec.d.ts +0 -2
- package/dist/src/device/access.spec.d.ts.map +0 -1
- package/dist/src/device/device.spec.d.ts +0 -2
- package/dist/src/device/device.spec.d.ts.map +0 -1
- package/dist/src/device/payload.spec.d.ts +0 -2
- package/dist/src/device/payload.spec.d.ts.map +0 -1
- package/dist/src/errors.spec.d.ts +0 -2
- package/dist/src/errors.spec.d.ts.map +0 -1
- package/dist/src/framer/adapter.spec.d.ts +0 -2
- package/dist/src/framer/adapter.spec.d.ts.map +0 -1
- package/dist/src/framer/client.spec.d.ts +0 -2
- package/dist/src/framer/client.spec.d.ts.map +0 -1
- package/dist/src/framer/codec.spec.d.ts +0 -2
- package/dist/src/framer/codec.spec.d.ts.map +0 -1
- package/dist/src/framer/deleter.spec.d.ts +0 -2
- package/dist/src/framer/deleter.spec.d.ts.map +0 -1
- package/dist/src/framer/frame.spec.d.ts +0 -2
- package/dist/src/framer/frame.spec.d.ts.map +0 -1
- package/dist/src/framer/iterator.spec.d.ts +0 -2
- package/dist/src/framer/iterator.spec.d.ts.map +0 -1
- package/dist/src/framer/reader.spec.d.ts +0 -2
- package/dist/src/framer/reader.spec.d.ts.map +0 -1
- package/dist/src/framer/streamer.spec.d.ts +0 -2
- package/dist/src/framer/streamer.spec.d.ts.map +0 -1
- package/dist/src/framer/writer.spec.d.ts +0 -2
- package/dist/src/framer/writer.spec.d.ts.map +0 -1
- package/dist/src/group/access.spec.d.ts +0 -2
- package/dist/src/group/access.spec.d.ts.map +0 -1
- package/dist/src/group/group.spec.d.ts +0 -2
- package/dist/src/group/group.spec.d.ts.map +0 -1
- package/dist/src/label/access.spec.d.ts +0 -2
- package/dist/src/label/access.spec.d.ts.map +0 -1
- package/dist/src/label/label.spec.d.ts +0 -2
- package/dist/src/label/label.spec.d.ts.map +0 -1
- package/dist/src/lineplot/access.spec.d.ts +0 -2
- package/dist/src/lineplot/access.spec.d.ts.map +0 -1
- package/dist/src/lineplot/lineplot.spec.d.ts +0 -2
- package/dist/src/lineplot/lineplot.spec.d.ts.map +0 -1
- package/dist/src/log/access.spec.d.ts +0 -2
- package/dist/src/log/access.spec.d.ts.map +0 -1
- package/dist/src/log/log.spec.d.ts +0 -2
- package/dist/src/log/log.spec.d.ts.map +0 -1
- package/dist/src/ontology/ontology.spec.d.ts +0 -2
- package/dist/src/ontology/ontology.spec.d.ts.map +0 -1
- package/dist/src/rack/access.spec.d.ts +0 -2
- package/dist/src/rack/access.spec.d.ts.map +0 -1
- package/dist/src/rack/rack.spec.d.ts +0 -2
- package/dist/src/rack/rack.spec.d.ts.map +0 -1
- package/dist/src/ranger/access.spec.d.ts +0 -2
- package/dist/src/ranger/access.spec.d.ts.map +0 -1
- package/dist/src/ranger/alias/payload.spec.d.ts +0 -2
- package/dist/src/ranger/alias/payload.spec.d.ts.map +0 -1
- package/dist/src/ranger/ranger.spec.d.ts +0 -2
- package/dist/src/ranger/ranger.spec.d.ts.map +0 -1
- package/dist/src/schematic/access.spec.d.ts +0 -2
- package/dist/src/schematic/access.spec.d.ts.map +0 -1
- package/dist/src/schematic/actions.spec.d.ts +0 -2
- package/dist/src/schematic/actions.spec.d.ts.map +0 -1
- package/dist/src/schematic/schematic.spec.d.ts +0 -2
- package/dist/src/schematic/schematic.spec.d.ts.map +0 -1
- package/dist/src/schematic/symbol/access.spec.d.ts +0 -2
- package/dist/src/schematic/symbol/access.spec.d.ts.map +0 -1
- package/dist/src/schematic/symbol/client.spec.d.ts +0 -2
- package/dist/src/schematic/symbol/client.spec.d.ts.map +0 -1
- package/dist/src/status/access.spec.d.ts +0 -2
- package/dist/src/status/access.spec.d.ts.map +0 -1
- package/dist/src/status/status.spec.d.ts +0 -2
- package/dist/src/status/status.spec.d.ts.map +0 -1
- package/dist/src/table/access.spec.d.ts +0 -2
- package/dist/src/table/access.spec.d.ts.map +0 -1
- package/dist/src/table/table.spec.d.ts +0 -2
- package/dist/src/table/table.spec.d.ts.map +0 -1
- package/dist/src/task/access.spec.d.ts +0 -2
- package/dist/src/task/access.spec.d.ts.map +0 -1
- package/dist/src/task/payload.spec.d.ts +0 -2
- package/dist/src/task/payload.spec.d.ts.map +0 -1
- package/dist/src/task/task.spec.d.ts +0 -2
- package/dist/src/task/task.spec.d.ts.map +0 -1
- package/dist/src/user/access.spec.d.ts +0 -2
- package/dist/src/user/access.spec.d.ts.map +0 -1
- package/dist/src/user/user.spec.d.ts +0 -2
- package/dist/src/user/user.spec.d.ts.map +0 -1
- package/dist/src/util/retrieve.spec.d.ts +0 -2
- package/dist/src/util/retrieve.spec.d.ts.map +0 -1
- package/dist/src/view/view.spec.d.ts +0 -2
- package/dist/src/view/view.spec.d.ts.map +0 -1
- package/dist/src/workspace/access.spec.d.ts +0 -2
- package/dist/src/workspace/access.spec.d.ts.map +0 -1
- package/dist/src/workspace/client.d.ts +0 -36
- package/dist/src/workspace/client.d.ts.map +0 -1
- package/dist/src/workspace/external.d.ts.map +0 -1
- package/dist/src/workspace/index.d.ts +0 -2
- package/dist/src/workspace/index.d.ts.map +0 -1
- package/dist/src/workspace/types.gen.d.ts +0 -34
- package/dist/src/workspace/types.gen.d.ts.map +0 -1
- package/dist/src/workspace/workspace.spec.d.ts +0 -2
- package/dist/src/workspace/workspace.spec.d.ts.map +0 -1
- package/examples/node/basicReadWrite.js +0 -86
- package/examples/node/createChannels.js +0 -50
- package/examples/node/createRange.js +0 -67
- package/examples/node/package-lock.json +0 -133
- package/examples/node/package.json +0 -17
- package/examples/node/readLatest.js +0 -76
- package/examples/node/seriesAndFrames.js +0 -173
- package/examples/node/streamRead.js +0 -50
- package/examples/node/streamWrite.js +0 -87
- package/src/access/enforce.spec.ts +0 -188
- package/src/access/policy/access.spec.ts +0 -147
- package/src/access/role/role.spec.ts +0 -95
- package/src/actions/actions.spec.ts +0 -229
- package/src/arc/access.spec.ts +0 -149
- package/src/arc/arc.spec.ts +0 -44
- package/src/arc/lsp.spec.ts +0 -717
- package/src/auth/auth.spec.ts +0 -101
- package/src/channel/access.spec.ts +0 -116
- package/src/channel/batchRetriever.spec.ts +0 -115
- package/src/channel/channel.spec.ts +0 -352
- package/src/channel/payload.spec.ts +0 -117
- package/src/channel/retriever.ts +0 -252
- package/src/connection/checker.ts +0 -203
- package/src/connection/connection.spec.ts +0 -152
- package/src/connection.spec.ts +0 -145
- package/src/control/state.spec.ts +0 -22
- package/src/device/access.spec.ts +0 -159
- package/src/device/device.spec.ts +0 -461
- package/src/device/payload.spec.ts +0 -142
- package/src/errors.spec.ts +0 -71
- package/src/framer/adapter.spec.ts +0 -620
- package/src/framer/client.spec.ts +0 -180
- package/src/framer/codec.spec.ts +0 -383
- package/src/framer/deleter.spec.ts +0 -103
- package/src/framer/frame.spec.ts +0 -973
- package/src/framer/iterator.spec.ts +0 -169
- package/src/framer/reader.spec.ts +0 -865
- package/src/framer/streamer.spec.ts +0 -871
- package/src/framer/writer.spec.ts +0 -486
- package/src/group/access.spec.ts +0 -77
- package/src/group/group.spec.ts +0 -65
- package/src/label/access.spec.ts +0 -109
- package/src/label/label.spec.ts +0 -83
- package/src/lineplot/access.spec.ts +0 -134
- package/src/lineplot/lineplot.spec.ts +0 -120
- package/src/log/access.spec.ts +0 -132
- package/src/log/log.spec.ts +0 -106
- package/src/ontology/ontology.spec.ts +0 -521
- package/src/rack/access.spec.ts +0 -102
- package/src/rack/rack.spec.ts +0 -171
- package/src/ranger/access.spec.ts +0 -115
- package/src/ranger/alias/payload.spec.ts +0 -52
- package/src/ranger/ranger.spec.ts +0 -343
- package/src/schematic/access.spec.ts +0 -134
- package/src/schematic/actions.spec.ts +0 -699
- package/src/schematic/schematic.spec.ts +0 -340
- package/src/schematic/symbol/access.spec.ts +0 -172
- package/src/schematic/symbol/client.spec.ts +0 -160
- package/src/status/access.spec.ts +0 -129
- package/src/status/status.spec.ts +0 -448
- package/src/table/access.spec.ts +0 -128
- package/src/table/table.spec.ts +0 -651
- package/src/task/access.spec.ts +0 -131
- package/src/task/payload.spec.ts +0 -113
- package/src/task/task.spec.ts +0 -657
- package/src/user/access.spec.ts +0 -107
- package/src/user/user.spec.ts +0 -290
- package/src/util/retrieve.spec.ts +0 -49
- package/src/view/view.spec.ts +0 -165
- package/src/workspace/access.spec.ts +0 -108
- package/src/workspace/client.ts +0 -112
- package/src/workspace/types.gen.ts +0 -46
- package/src/workspace/workspace.spec.ts +0 -111
- package/tsconfig.json +0 -5
- package/tsconfig.vite.json +0 -4
- package/vite.config.ts +0 -29
- /package/dist/src/{workspace → project}/external.d.ts +0 -0
package/src/task/client.ts
CHANGED
|
@@ -10,30 +10,42 @@
|
|
|
10
10
|
import { type UnaryClient } from "@synnaxlabs/freighter";
|
|
11
11
|
import {
|
|
12
12
|
array,
|
|
13
|
+
binary,
|
|
13
14
|
caseconv,
|
|
14
15
|
type CrudeTimeSpan,
|
|
16
|
+
deep,
|
|
17
|
+
type destructor,
|
|
15
18
|
id,
|
|
19
|
+
primitive,
|
|
16
20
|
type record,
|
|
17
21
|
strings,
|
|
18
22
|
TimeSpan,
|
|
23
|
+
TimeStamp,
|
|
19
24
|
} from "@synnaxlabs/x";
|
|
20
25
|
import { z } from "zod";
|
|
21
26
|
|
|
22
27
|
import { type framer } from "@/framer";
|
|
23
28
|
import { ontology } from "@/ontology";
|
|
24
|
-
import {
|
|
29
|
+
import { query } from "@/query";
|
|
30
|
+
import {
|
|
31
|
+
type Key as RackKey,
|
|
32
|
+
keyZ as rackKeyZ,
|
|
33
|
+
ontologyID as rackOntologyID,
|
|
34
|
+
} from "@/rack/types.gen";
|
|
25
35
|
import { type ranger } from "@/ranger";
|
|
26
36
|
import { status } from "@/status";
|
|
27
37
|
import {
|
|
38
|
+
type Command,
|
|
39
|
+
commandZ,
|
|
28
40
|
type Key,
|
|
29
41
|
keyZ,
|
|
30
42
|
type New,
|
|
31
|
-
newZ,
|
|
32
43
|
ontologyID,
|
|
33
44
|
type Payload,
|
|
34
45
|
type PayloadSchemas as Schemas,
|
|
35
46
|
payloadZ,
|
|
36
47
|
type Status,
|
|
48
|
+
type StatusDetailsZodObject,
|
|
37
49
|
statusZ,
|
|
38
50
|
} from "@/task/types.gen";
|
|
39
51
|
import { checkForMultipleOrNoResults } from "@/util/retrieve";
|
|
@@ -44,31 +56,66 @@ export const COMMAND_CHANNEL_NAME = "sy_task_cmd";
|
|
|
44
56
|
export const SET_CHANNEL_NAME = "sy_task_set";
|
|
45
57
|
export const DELETE_CHANNEL_NAME = "sy_task_delete";
|
|
46
58
|
|
|
47
|
-
export const
|
|
59
|
+
export const setSignalZ = payloadZ().omit({ config: true, status: true });
|
|
60
|
+
export interface SetSignal extends z.infer<typeof setSignalZ> {}
|
|
61
|
+
|
|
62
|
+
export interface DriftedParams extends Pick<
|
|
63
|
+
Payload,
|
|
64
|
+
"configHash" | "rack" | "status"
|
|
65
|
+
> {}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Reports whether a task's live instance has drifted from its stored task: the task is
|
|
69
|
+
* running and the stored config or rack differs from what the instance was deployed
|
|
70
|
+
* with. Tasks that are not running never drift. Both hashes are server-assigned, so
|
|
71
|
+
* this compares two given values and never hashes a config. A status with an empty
|
|
72
|
+
* deployed hash never drifts: the deployed config is unknown, not different.
|
|
73
|
+
* @returns True when a redeploy (start) would change the running instance.
|
|
74
|
+
*/
|
|
75
|
+
export const drifted = (task: DriftedParams): boolean => {
|
|
76
|
+
const details = task.status?.details;
|
|
77
|
+
if (details == null || !details.running || details.configHash === "") return false;
|
|
78
|
+
return details.configHash !== task.configHash || details.rack !== task.rack;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
// Temporary hack that filters the set of commands that should change the
|
|
82
|
+
// status of a task to loading.
|
|
83
|
+
// Issue: https://linear.app/synnax/issue/SY-2723/fix-handling-of-non-startstop-commands-loading-indicators-in-tasks
|
|
84
|
+
const LOADING_COMMANDS = ["start", "stop"];
|
|
48
85
|
|
|
49
|
-
|
|
50
|
-
|
|
86
|
+
// The rack monitor marks a rack whose Driver is alive with one of these.
|
|
87
|
+
const HEALTHY_RACK_VARIANTS: status.Variant[] = ["success", "info"];
|
|
88
|
+
|
|
89
|
+
/** How long a command waits for the Driver before the wait is called off. */
|
|
90
|
+
const COMMAND_DEADLINE = TimeSpan.seconds(10);
|
|
91
|
+
|
|
92
|
+
const STATUS_NAME = "Task Status";
|
|
51
93
|
|
|
52
94
|
const retrieveSnapshottedTo = async (taskKey: Key, ontologyClient: ontology.Client) => {
|
|
53
|
-
const parents = await ontologyClient.
|
|
95
|
+
const parents = await ontologyClient.parents.retrieve({ ids: ontologyID(taskKey) });
|
|
54
96
|
if (parents.length === 0) return null;
|
|
55
97
|
return parents[0];
|
|
56
98
|
};
|
|
57
99
|
|
|
100
|
+
/** One command sent to a task, as issued from the task itself. */
|
|
58
101
|
export interface TaskExecuteCommandParams {
|
|
59
102
|
type: string;
|
|
60
103
|
args?: record.Unknown;
|
|
61
104
|
}
|
|
62
105
|
|
|
106
|
+
/** One command sent to a task, as issued from the client. */
|
|
63
107
|
export interface ExecuteCommandParams extends TaskExecuteCommandParams {
|
|
64
108
|
task: Key;
|
|
65
109
|
}
|
|
66
110
|
|
|
111
|
+
/** Several commands sent in one round trip. */
|
|
67
112
|
export interface ExecuteCommandsParams {
|
|
68
113
|
commands: NewCommand[];
|
|
69
114
|
}
|
|
70
115
|
|
|
116
|
+
/** A command awaited to completion, as issued from the task itself. */
|
|
71
117
|
export interface TaskExecuteCommandSyncParams extends TaskExecuteCommandParams {
|
|
118
|
+
/** How long to wait for the status before giving up. */
|
|
72
119
|
timeout?: CrudeTimeSpan;
|
|
73
120
|
}
|
|
74
121
|
|
|
@@ -82,46 +129,66 @@ export interface ExecuteCommandSyncParams<StatusData extends z.ZodType> extends
|
|
|
82
129
|
"frameClient" | "name"
|
|
83
130
|
> {}
|
|
84
131
|
|
|
132
|
+
/**
|
|
133
|
+
* A unit of work a rack runs against hardware: its config, its running status, and the
|
|
134
|
+
* commands it accepts. Get one from `client.hardware.tasks` rather than building it.
|
|
135
|
+
*/
|
|
85
136
|
export class Task<S extends Schemas = Schemas> {
|
|
86
137
|
readonly key: Key;
|
|
138
|
+
readonly rack: RackKey;
|
|
87
139
|
name: string;
|
|
88
140
|
internal: boolean;
|
|
89
141
|
type: z.infer<S["type"]>;
|
|
90
142
|
snapshot: boolean;
|
|
91
143
|
config: z.infer<S["config"]>;
|
|
144
|
+
readonly configHash: string;
|
|
92
145
|
status?: Status<S["statusData"]>;
|
|
93
146
|
|
|
94
147
|
readonly schemas: S;
|
|
95
|
-
private readonly
|
|
96
|
-
|
|
97
|
-
|
|
148
|
+
private readonly clients?: {
|
|
149
|
+
frame: framer.Client;
|
|
150
|
+
ontology: ontology.Client;
|
|
151
|
+
range: ranger.Client;
|
|
152
|
+
};
|
|
98
153
|
|
|
99
154
|
get frameClient(): framer.Client {
|
|
100
|
-
if (this.
|
|
101
|
-
return this.
|
|
155
|
+
if (this.clients == null) throw new Error("Task not created");
|
|
156
|
+
return this.clients.frame;
|
|
102
157
|
}
|
|
103
158
|
|
|
104
159
|
get ontologyClient(): ontology.Client {
|
|
105
|
-
if (this.
|
|
106
|
-
return this.
|
|
160
|
+
if (this.clients == null) throw new Error("Task not created");
|
|
161
|
+
return this.clients.ontology;
|
|
107
162
|
}
|
|
108
163
|
|
|
109
164
|
get rangeClient(): ranger.Client {
|
|
110
|
-
if (this.
|
|
111
|
-
return this.
|
|
165
|
+
if (this.clients == null) throw new Error("Task not created");
|
|
166
|
+
return this.clients.range;
|
|
112
167
|
}
|
|
113
168
|
|
|
114
169
|
constructor(
|
|
115
|
-
{
|
|
170
|
+
{
|
|
171
|
+
key,
|
|
172
|
+
rack,
|
|
173
|
+
type,
|
|
174
|
+
name,
|
|
175
|
+
config,
|
|
176
|
+
configHash = "",
|
|
177
|
+
internal = false,
|
|
178
|
+
snapshot = false,
|
|
179
|
+
status,
|
|
180
|
+
}: Payload<S>,
|
|
116
181
|
schemas?: S,
|
|
117
182
|
frameClient?: framer.Client,
|
|
118
183
|
ontologyClient?: ontology.Client,
|
|
119
184
|
rangeClient?: ranger.Client,
|
|
120
185
|
) {
|
|
121
186
|
this.key = key;
|
|
187
|
+
this.rack = rack;
|
|
122
188
|
this.name = name;
|
|
123
189
|
this.type = type;
|
|
124
190
|
this.config = config;
|
|
191
|
+
this.configHash = configHash;
|
|
125
192
|
this.schemas =
|
|
126
193
|
schemas ??
|
|
127
194
|
({
|
|
@@ -132,19 +199,25 @@ export class Task<S extends Schemas = Schemas> {
|
|
|
132
199
|
this.internal = internal;
|
|
133
200
|
this.snapshot = snapshot;
|
|
134
201
|
this.status = status;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
202
|
+
if (frameClient != null && ontologyClient != null && rangeClient != null)
|
|
203
|
+
this.clients = {
|
|
204
|
+
frame: frameClient,
|
|
205
|
+
ontology: ontologyClient,
|
|
206
|
+
range: rangeClient,
|
|
207
|
+
};
|
|
138
208
|
}
|
|
139
209
|
|
|
140
210
|
get payload(): Payload<S> {
|
|
141
211
|
return {
|
|
142
212
|
key: this.key,
|
|
213
|
+
rack: this.rack,
|
|
143
214
|
name: this.name,
|
|
144
215
|
type: this.type,
|
|
145
216
|
config: this.config,
|
|
217
|
+
configHash: this.configHash,
|
|
146
218
|
status: this.status,
|
|
147
219
|
internal: this.internal,
|
|
220
|
+
snapshot: this.snapshot,
|
|
148
221
|
};
|
|
149
222
|
}
|
|
150
223
|
|
|
@@ -157,6 +230,7 @@ export class Task<S extends Schemas = Schemas> {
|
|
|
157
230
|
...params,
|
|
158
231
|
frameClient: this.frameClient,
|
|
159
232
|
task: this.key,
|
|
233
|
+
configHash: this.configHash,
|
|
160
234
|
});
|
|
161
235
|
}
|
|
162
236
|
|
|
@@ -167,6 +241,7 @@ export class Task<S extends Schemas = Schemas> {
|
|
|
167
241
|
...params,
|
|
168
242
|
frameClient: this.frameClient,
|
|
169
243
|
task: this.key,
|
|
244
|
+
configHash: this.configHash,
|
|
170
245
|
name: this.name,
|
|
171
246
|
statusDataZ: this.schemas.statusData,
|
|
172
247
|
});
|
|
@@ -210,7 +285,7 @@ const retrieveReqZ = z.object({
|
|
|
210
285
|
limit: z.int().optional(),
|
|
211
286
|
});
|
|
212
287
|
|
|
213
|
-
const
|
|
288
|
+
const singleRetrieveParamsZ = z.union([
|
|
214
289
|
z
|
|
215
290
|
.object({ key: keyZ, includeStatus: z.boolean().optional() })
|
|
216
291
|
.transform(({ key, includeStatus }) => ({ keys: [key], includeStatus })),
|
|
@@ -221,25 +296,84 @@ const singleRetrieveArgsZ = z.union([
|
|
|
221
296
|
.object({ type: z.string(), rack: rackKeyZ.optional() })
|
|
222
297
|
.transform(({ type, rack }) => ({ types: [type], rack })),
|
|
223
298
|
]);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
299
|
+
/** Names one task: by key, by name, or by type and rack. */
|
|
300
|
+
export type RetrieveSingleParams = z.input<typeof singleRetrieveParamsZ>;
|
|
301
|
+
|
|
302
|
+
const multiRetrieveParamsZ = retrieveReqZ;
|
|
303
|
+
/** Everything a multi-task retrieval can filter on. */
|
|
304
|
+
export type RetrieveMultipleParams = z.input<typeof multiRetrieveParamsZ>;
|
|
305
|
+
|
|
306
|
+
const retrieveParamsZ = z.union([singleRetrieveParamsZ, multiRetrieveParamsZ]);
|
|
307
|
+
/** Params for a task retrieval, single or multiple. */
|
|
308
|
+
export type RetrieveParams = z.input<typeof retrieveParamsZ>;
|
|
309
|
+
|
|
310
|
+
type SingleRequest = Partial<
|
|
311
|
+
Pick<z.infer<typeof retrieveReqZ>, "keys" | "names" | "types" | "rack">
|
|
312
|
+
>;
|
|
313
|
+
|
|
314
|
+
// includeStatus does not change a query's identity: cached fetches always
|
|
315
|
+
// request it, so it is stripped before hashing.
|
|
316
|
+
const normalizeSingle = (params: RetrieveSingleParams): SingleRequest => {
|
|
317
|
+
const parsed = singleRetrieveParamsZ.parse(params);
|
|
318
|
+
if (!("includeStatus" in parsed)) return parsed;
|
|
319
|
+
const { includeStatus: _, ...rest } = parsed;
|
|
320
|
+
return rest;
|
|
321
|
+
};
|
|
228
322
|
|
|
229
|
-
const
|
|
230
|
-
|
|
323
|
+
const singleQueryZ = z
|
|
324
|
+
.union([
|
|
325
|
+
z.strictObject({ key: keyZ, includeStatus: z.boolean().optional() }),
|
|
326
|
+
z.strictObject({ name: z.string(), includeStatus: z.boolean().optional() }),
|
|
327
|
+
z.strictObject({ type: z.string(), rack: rackKeyZ.optional() }),
|
|
328
|
+
keyZ.transform((key) => ({ key })),
|
|
329
|
+
])
|
|
330
|
+
.transform(normalizeSingle);
|
|
331
|
+
|
|
332
|
+
// includeStatus does not change a request's identity either: cached fetches
|
|
333
|
+
// always request it, so the schema strips it before hashing.
|
|
334
|
+
const cacheRetrieveReqZ = retrieveReqZ.transform(
|
|
335
|
+
({ includeStatus: _, ...rest }) => rest,
|
|
336
|
+
);
|
|
337
|
+
const retrieveMultiParamsZ = cacheRetrieveReqZ.or(query.keyListZ(keyZ));
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Client-side matching for a request: key, name, type, rack, and flag
|
|
341
|
+
* filters. Server-computed shapes (search, pagination) never reach this
|
|
342
|
+
* filter; they refetch instead.
|
|
343
|
+
*/
|
|
344
|
+
const requestFilter = (
|
|
345
|
+
req: RetrieveRequest,
|
|
346
|
+
): ((t: Omit<Task, "status">) => boolean) => {
|
|
347
|
+
const keySet = primitive.isNonZero(req.keys) ? new Set(req.keys) : undefined;
|
|
348
|
+
const nameSet = primitive.isNonZero(req.names) ? new Set(req.names) : undefined;
|
|
349
|
+
const typeSet = primitive.isNonZero(req.types) ? new Set(req.types) : undefined;
|
|
350
|
+
return (t) => {
|
|
351
|
+
if (keySet != null && !keySet.has(t.key)) return false;
|
|
352
|
+
if (nameSet != null && !nameSet.has(t.name)) return false;
|
|
353
|
+
if (typeSet != null && !typeSet.has(t.type)) return false;
|
|
354
|
+
if (req.rack != null && t.rack !== req.rack) return false;
|
|
355
|
+
if (req.internal != null && t.internal !== req.internal) return false;
|
|
356
|
+
if (req.snapshot != null && t.snapshot !== req.snapshot) return false;
|
|
357
|
+
return true;
|
|
358
|
+
};
|
|
359
|
+
};
|
|
231
360
|
|
|
232
361
|
interface RetrieveSchemas<S extends Schemas = Schemas> {
|
|
233
362
|
schemas?: S;
|
|
234
363
|
}
|
|
235
364
|
|
|
236
365
|
const retrieveResZ = <S extends Schemas = Schemas>(schemas?: S) =>
|
|
237
|
-
z.object({
|
|
366
|
+
z.object({
|
|
367
|
+
tasks: payloadZ(schemas)
|
|
368
|
+
.array()
|
|
369
|
+
.default(() => []),
|
|
370
|
+
});
|
|
238
371
|
|
|
372
|
+
/** A task retrieval on the wire. */
|
|
239
373
|
export interface RetrieveRequest extends z.infer<typeof retrieveReqZ> {}
|
|
240
374
|
|
|
241
375
|
const createReqZ = <S extends Schemas = Schemas>(schemas?: S) =>
|
|
242
|
-
z.object({ tasks:
|
|
376
|
+
z.object({ tasks: payloadZ(schemas).array() });
|
|
243
377
|
const createResZ = <S extends Schemas = Schemas>(schemas?: S) =>
|
|
244
378
|
z.object({ tasks: payloadZ(schemas).array() });
|
|
245
379
|
const deleteReqZ = z.object({ keys: keyZ.array() });
|
|
@@ -248,22 +382,120 @@ const copyReqZ = z.object({ key: keyZ, name: z.string(), snapshot: z.boolean() }
|
|
|
248
382
|
const copyResZ = <S extends Schemas = Schemas>(schemas?: S) =>
|
|
249
383
|
z.object({ task: payloadZ(schemas) });
|
|
250
384
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
385
|
+
const matchesSingle = (t: Omit<Task, "status">, query: SingleRequest): boolean => {
|
|
386
|
+
if (primitive.isNonZero(query.keys)) return t.key === query.keys[0];
|
|
387
|
+
if (primitive.isNonZero(query.names)) return t.name === query.names[0];
|
|
388
|
+
if (primitive.isNonZero(query.types))
|
|
389
|
+
return t.type === query.types[0] && (query.rack == null || t.rack === query.rack);
|
|
390
|
+
return false;
|
|
391
|
+
};
|
|
256
392
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
393
|
+
/** Config for {@link Client}. */
|
|
394
|
+
export interface ClientConfig {
|
|
395
|
+
unary: UnaryClient;
|
|
396
|
+
framer: framer.Client;
|
|
397
|
+
ontology: ontology.Client;
|
|
398
|
+
ranges: ranger.Client;
|
|
399
|
+
cache: query.Cache;
|
|
400
|
+
statusStore: query.Table<status.Key, status.Status>;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Creates, reads, deletes, and commands tasks on a Core. Reach it through
|
|
405
|
+
* `client.hardware.tasks`. Reads are served from a cache a change stream keeps current.
|
|
406
|
+
*/
|
|
407
|
+
export class Client extends query.Retriever<
|
|
408
|
+
typeof retrieveMultiParamsZ,
|
|
409
|
+
Key,
|
|
410
|
+
Omit<Task, "status">,
|
|
411
|
+
Task,
|
|
412
|
+
RetrieveSingleParams,
|
|
413
|
+
SingleRequest
|
|
414
|
+
> {
|
|
415
|
+
/** The task record table; injected into sibling clients at wiring. */
|
|
416
|
+
readonly store: query.Table<Key, Omit<Task, "status">>;
|
|
417
|
+
private readonly cfg: ClientConfig;
|
|
418
|
+
private readonly commandDeadlines = new Map<Key, ReturnType<typeof setTimeout>>();
|
|
419
|
+
|
|
420
|
+
constructor(cfg: ClientConfig) {
|
|
421
|
+
const { cache, statusStore } = cfg;
|
|
422
|
+
const store = cache.createTable<Key, Omit<Task, "status">>({
|
|
423
|
+
name: "tasks",
|
|
424
|
+
equal: (a, b) => deep.equal(a.payload, b.payload),
|
|
425
|
+
fetch: async (keys) => await this.fetchThrough({ keys }),
|
|
426
|
+
listen: [
|
|
427
|
+
{
|
|
428
|
+
bind: (table) => ({
|
|
429
|
+
channel: SET_CHANNEL_NAME,
|
|
430
|
+
schema: setSignalZ,
|
|
431
|
+
// The set signal omits config: a changed hash makes the cached one stale.
|
|
432
|
+
onChange: async (changed: SetSignal[]) => {
|
|
433
|
+
const stale: Key[] = [];
|
|
434
|
+
table.batch(() =>
|
|
435
|
+
changed.forEach((sig) => {
|
|
436
|
+
const cached = table.get(sig.key);
|
|
437
|
+
if (cached == null || cached.configHash !== sig.configHash) {
|
|
438
|
+
stale.push(sig.key);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
table.set(sig.key, (prev) =>
|
|
442
|
+
prev == null ? undefined : this.sugar({ ...prev.payload, ...sig }),
|
|
443
|
+
);
|
|
444
|
+
}),
|
|
445
|
+
);
|
|
446
|
+
if (stale.length > 0) await table.retrieve(stale, { refresh: true });
|
|
447
|
+
},
|
|
448
|
+
}),
|
|
449
|
+
},
|
|
450
|
+
query.createDeleteListener(DELETE_CHANNEL_NAME, keyZ),
|
|
451
|
+
],
|
|
452
|
+
});
|
|
453
|
+
cache.listen({
|
|
454
|
+
channel: COMMAND_CHANNEL_NAME,
|
|
455
|
+
schema: commandZ,
|
|
456
|
+
onChange: (commands) =>
|
|
457
|
+
statusStore.batch(() =>
|
|
458
|
+
commands.forEach((changed) => {
|
|
459
|
+
if (!LOADING_COMMANDS.includes(changed.type)) return;
|
|
460
|
+
const key = statusKey(changed.task);
|
|
461
|
+
if (statusStore.get(key) == null) return;
|
|
462
|
+
const optimistic = this.optimisticStatus(changed);
|
|
463
|
+
statusStore.set(key, optimistic);
|
|
464
|
+
if (optimistic.variant === "loading")
|
|
465
|
+
this.armCommandDeadline(changed, optimistic);
|
|
466
|
+
}),
|
|
467
|
+
),
|
|
468
|
+
});
|
|
469
|
+
const composed = cache.derive<Key, Omit<Task, "status">, Task>({
|
|
470
|
+
name: "task.composed",
|
|
471
|
+
source: store,
|
|
472
|
+
compose: (record) => this.compose(record),
|
|
473
|
+
equal: (a, b) => deep.equal(a.payload, b.payload),
|
|
474
|
+
watch: [query.deriveWatch(statusStore, (event) => affectedTaskKeys(event))],
|
|
475
|
+
});
|
|
476
|
+
const single = cache.queries<SingleRequest, Task, Key, Task>({
|
|
477
|
+
name: "task",
|
|
478
|
+
table: composed,
|
|
479
|
+
fetch: async (q) => [(await this.fetchSingle(q)).key],
|
|
480
|
+
compose: (records) => records[0],
|
|
481
|
+
keyOf: (q) => (primitive.isNonZero(q.keys) ? q.keys[0] : null),
|
|
482
|
+
matches: matchesSingle,
|
|
483
|
+
single: true,
|
|
484
|
+
});
|
|
485
|
+
super(cache, {
|
|
486
|
+
name: "task",
|
|
487
|
+
table: store,
|
|
488
|
+
request: {
|
|
489
|
+
schema: retrieveMultiParamsZ,
|
|
490
|
+
fetch: async (req) => await this.fetchThrough(req),
|
|
491
|
+
matches: (t, req) => requestFilter(req)(t),
|
|
492
|
+
watch: [query.watch(statusStore, (event) => affectedTaskKeys(event))],
|
|
493
|
+
},
|
|
494
|
+
compose: (record) => this.compose(record),
|
|
495
|
+
single: { schema: singleQueryZ, space: single },
|
|
496
|
+
});
|
|
497
|
+
this.cfg = cfg;
|
|
498
|
+
this.store = store;
|
|
267
499
|
}
|
|
268
500
|
|
|
269
501
|
async create(task: New): Promise<Task>;
|
|
@@ -279,59 +511,108 @@ export class Client {
|
|
|
279
511
|
const isSingle = !Array.isArray(task);
|
|
280
512
|
const createReq = createReqZ(schemas);
|
|
281
513
|
const createRes = createResZ(schemas);
|
|
282
|
-
const res = await this.
|
|
514
|
+
const res = await this.cfg.unary.send(
|
|
283
515
|
"/task/create",
|
|
284
516
|
{ tasks: array.toArray(task) },
|
|
285
517
|
createReq,
|
|
286
518
|
createRes,
|
|
287
519
|
);
|
|
288
520
|
const sugared = this.sugar<S>(res.tasks as Payload<S>[], schemas);
|
|
521
|
+
sugared.forEach((t) => this.writeThrough(t));
|
|
289
522
|
return isSingle ? sugared[0] : sugared;
|
|
290
523
|
}
|
|
291
524
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
);
|
|
525
|
+
/**
|
|
526
|
+
* Forgets the tasks locally without deleting them on the cluster, for callers
|
|
527
|
+
* whose own endpoint already deleted them. Keeps a later retrieve from serving
|
|
528
|
+
* a deleted task while the delete signal is still in flight.
|
|
529
|
+
*/
|
|
530
|
+
dropCached(keys: Key | Key[]): void {
|
|
531
|
+
this.dropLocal(array.toArray(keys));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
private dropLocal(keys: Key[]): destructor.Destructor[] {
|
|
535
|
+
return [
|
|
536
|
+
this.cfg.ontology.cache.deleteResources(ontologyID(keys)),
|
|
537
|
+
this.store.delete(keys),
|
|
538
|
+
this.cfg.statusStore.delete(keys.map((k) => statusKey(k))),
|
|
539
|
+
];
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async delete(keys: Key | Key[], opts: query.WriteOptions = {}): Promise<void> {
|
|
543
|
+
const keysArr = array.toArray(keys);
|
|
544
|
+
const drop = () => this.dropLocal(keysArr);
|
|
545
|
+
await query.optimistic({
|
|
546
|
+
rollbacks: drop(),
|
|
547
|
+
onOptimistic: opts.onOptimistic,
|
|
548
|
+
commit: async () =>
|
|
549
|
+
await this.cfg.unary.send(
|
|
550
|
+
"/task/delete",
|
|
551
|
+
{ keys: keysArr },
|
|
552
|
+
deleteReqZ,
|
|
553
|
+
deleteResZ,
|
|
554
|
+
),
|
|
555
|
+
});
|
|
556
|
+
drop();
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
async rename(key: Key, name: string, opts: query.WriteOptions = {}): Promise<void> {
|
|
560
|
+
const rename = () => [
|
|
561
|
+
this.store.set(key, (p) =>
|
|
562
|
+
p == null ? undefined : this.sugar({ ...p.payload, name }),
|
|
563
|
+
),
|
|
564
|
+
this.cfg.ontology.cache.renameResource(ontologyID(key), name),
|
|
565
|
+
];
|
|
566
|
+
await query.optimistic({
|
|
567
|
+
rollbacks: rename(),
|
|
568
|
+
onOptimistic: opts.onOptimistic,
|
|
569
|
+
commit: async () => {
|
|
570
|
+
const t = await this.retrieve(key);
|
|
571
|
+
await this.create({ ...t.payload, name });
|
|
572
|
+
},
|
|
573
|
+
});
|
|
574
|
+
rename();
|
|
299
575
|
}
|
|
300
576
|
|
|
301
577
|
async retrieve<S extends Schemas = Schemas>(
|
|
302
|
-
|
|
578
|
+
params: RetrieveSingleParams & RetrieveSchemas<S>,
|
|
303
579
|
): Promise<Task<S>>;
|
|
304
|
-
async retrieve(
|
|
580
|
+
async retrieve(params: Key | RetrieveSingleParams): Promise<Task>;
|
|
305
581
|
async retrieve<S extends Schemas = Schemas>(
|
|
306
|
-
|
|
582
|
+
params: RetrieveMultipleParams & RetrieveSchemas<S>,
|
|
307
583
|
): Promise<Task<S>[]>;
|
|
308
|
-
async retrieve(
|
|
309
|
-
async retrieve<S extends Schemas = Schemas>(
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
584
|
+
async retrieve(params: RetrieveMultipleParams): Promise<Task[]>;
|
|
585
|
+
async retrieve<S extends Schemas = Schemas>(
|
|
586
|
+
rawParams: Key | (RetrieveParams & RetrieveSchemas<S>),
|
|
587
|
+
): Promise<Task<S> | Task<S>[]> {
|
|
588
|
+
const { schemas, ...params } =
|
|
589
|
+
typeof rawParams === "string" ? { key: rawParams } : rawParams;
|
|
590
|
+
const isSingle = singleRetrieveParamsZ.safeParse(params).success;
|
|
591
|
+
// Schema-parametrized retrieves validate config/status for one caller;
|
|
592
|
+
// their results are not shared through the cache.
|
|
593
|
+
if (schemas != null) {
|
|
594
|
+
const sugared = await this.execRetrieve<S>(params, schemas);
|
|
595
|
+
checkForMultipleOrNoResults("Task", params, sugared, isSingle);
|
|
596
|
+
return isSingle ? sugared[0] : sugared;
|
|
597
|
+
}
|
|
598
|
+
if (isSingle)
|
|
599
|
+
return (await super.retrieve(params as RetrieveSingleParams)) as Task<S>;
|
|
600
|
+
return (await super.retrieve(
|
|
601
|
+
params as RetrieveMultipleParams,
|
|
602
|
+
)) as unknown as Task<S>[];
|
|
324
603
|
}
|
|
325
604
|
|
|
326
605
|
async copy(key: Key, name: string, snapshot: boolean): Promise<Task> {
|
|
327
606
|
const copyRes = copyResZ();
|
|
328
|
-
const response = await this.
|
|
607
|
+
const response = await this.cfg.unary.send(
|
|
329
608
|
"/task/copy",
|
|
330
609
|
{ key, name, snapshot },
|
|
331
610
|
copyReqZ,
|
|
332
611
|
copyRes,
|
|
333
612
|
);
|
|
334
|
-
|
|
613
|
+
const sugared = this.sugar(response.task);
|
|
614
|
+
this.writeThrough(sugared);
|
|
615
|
+
return sugared;
|
|
335
616
|
}
|
|
336
617
|
|
|
337
618
|
async list(rack?: number): Promise<Task[]> {
|
|
@@ -341,8 +622,147 @@ export class Client {
|
|
|
341
622
|
}
|
|
342
623
|
|
|
343
624
|
async retrieveSnapshottedTo(taskKey: Key): Promise<ontology.Resource | null> {
|
|
344
|
-
if (this.
|
|
345
|
-
return await retrieveSnapshottedTo(taskKey, this.
|
|
625
|
+
if (this.cfg.ontology == null) throw new Error("Task not created");
|
|
626
|
+
return await retrieveSnapshottedTo(taskKey, this.cfg.ontology);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
private async execRetrieve<S extends Schemas = Schemas>(
|
|
630
|
+
params: RetrieveParams,
|
|
631
|
+
schemas?: S,
|
|
632
|
+
): Promise<Task<S>[]> {
|
|
633
|
+
const res = await this.cfg.unary.send(
|
|
634
|
+
"/task/retrieve",
|
|
635
|
+
params,
|
|
636
|
+
retrieveParamsZ,
|
|
637
|
+
retrieveResZ(schemas),
|
|
638
|
+
);
|
|
639
|
+
return this.sugar(res.tasks as Payload<S>[], schemas);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/** Rebuilds a cached task with its cached status attached. */
|
|
643
|
+
private compose(cached: Omit<Task, "status">): Task {
|
|
644
|
+
const st = this.latestStatusOf(cached.key);
|
|
645
|
+
const payload = cached.payload;
|
|
646
|
+
if (st == null) return this.sugar(payload);
|
|
647
|
+
return this.sugar({ ...payload, status: st });
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Every domain's statuses share one store, so a rack's status sits beside its
|
|
651
|
+
// tasks' under the rack's ontology ID.
|
|
652
|
+
private downRackStatus(rack: RackKey | undefined): status.Status | undefined {
|
|
653
|
+
if (rack == null || primitive.isZero(rack)) return undefined;
|
|
654
|
+
const stat = this.cfg.statusStore.get(ontology.idToString(rackOntologyID(rack)));
|
|
655
|
+
if (stat == null || HEALTHY_RACK_VARIANTS.includes(stat.variant)) return undefined;
|
|
656
|
+
return stat;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Builds the status shown while a command is in flight. A rack whose Driver is down
|
|
661
|
+
* answers nothing, so its warning stands in for a wait that would never end.
|
|
662
|
+
*/
|
|
663
|
+
private optimisticStatus(cmd: Command): Status {
|
|
664
|
+
// Carry the last known deploy info forward: zeroing it would make this
|
|
665
|
+
// optimistic status claim the task deployed with an empty config/rack.
|
|
666
|
+
const latest = this.latestStatusOf(cmd.task);
|
|
667
|
+
const key = statusKey(cmd.task);
|
|
668
|
+
const details = {
|
|
669
|
+
task: cmd.task,
|
|
670
|
+
cmd: "",
|
|
671
|
+
configHash: latest?.details.configHash ?? "",
|
|
672
|
+
rack: latest?.details.rack ?? 0,
|
|
673
|
+
data: {},
|
|
674
|
+
};
|
|
675
|
+
const down = this.downRackStatus(this.store.get(cmd.task)?.rack);
|
|
676
|
+
if (down == null)
|
|
677
|
+
return status.create<StatusDetailsZodObject>({
|
|
678
|
+
key,
|
|
679
|
+
name: STATUS_NAME,
|
|
680
|
+
variant: "loading",
|
|
681
|
+
message: `Running ${cmd.type} command...`,
|
|
682
|
+
details: { ...details, running: true },
|
|
683
|
+
});
|
|
684
|
+
return status.create<StatusDetailsZodObject>({
|
|
685
|
+
key,
|
|
686
|
+
name: STATUS_NAME,
|
|
687
|
+
variant: "warning",
|
|
688
|
+
message: down.message,
|
|
689
|
+
description: down.description,
|
|
690
|
+
details: { ...details, running: false },
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Nothing else retires the loading status: a task on a silent rack waits on the
|
|
695
|
+
// Core's next dead-rack alert, which dampens to once a minute.
|
|
696
|
+
private armCommandDeadline(cmd: Command, optimistic: Status): void {
|
|
697
|
+
const { statusStore } = this.cfg;
|
|
698
|
+
const key = statusKey(cmd.task);
|
|
699
|
+
clearTimeout(this.commandDeadlines.get(cmd.task));
|
|
700
|
+
this.commandDeadlines.set(
|
|
701
|
+
cmd.task,
|
|
702
|
+
setTimeout(() => {
|
|
703
|
+
this.commandDeadlines.delete(cmd.task);
|
|
704
|
+
// Any later write replaced the exact object this deadline was armed for.
|
|
705
|
+
if (statusStore.get(key) !== optimistic) return;
|
|
706
|
+
statusStore.set(
|
|
707
|
+
key,
|
|
708
|
+
status.create<StatusDetailsZodObject>({
|
|
709
|
+
key,
|
|
710
|
+
name: STATUS_NAME,
|
|
711
|
+
variant: "warning",
|
|
712
|
+
message: `No response to the ${cmd.type} command`,
|
|
713
|
+
description: `The Driver did not respond within ${COMMAND_DEADLINE.toString()}.`,
|
|
714
|
+
// Nothing answered, so the command is taken to have had no effect.
|
|
715
|
+
details: { ...optimistic.details, running: cmd.type === "stop" },
|
|
716
|
+
}),
|
|
717
|
+
);
|
|
718
|
+
}, COMMAND_DEADLINE.milliseconds),
|
|
719
|
+
);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// A task's status may live under the "task:<key>" row or under any status
|
|
723
|
+
// whose details reference the task; the freshest wins. Rows are parsed
|
|
724
|
+
// because the status table holds every domain's statuses generically.
|
|
725
|
+
private latestStatusOf(key: Key): Status | undefined {
|
|
726
|
+
const taskKey = statusKey(key);
|
|
727
|
+
const candidates = this.cfg.statusStore
|
|
728
|
+
.get((s) => s.key === taskKey || status.detailsOf(s)?.task === key)
|
|
729
|
+
.map((s) => statusZ().safeParse(s))
|
|
730
|
+
.filter((p) => p.success)
|
|
731
|
+
.map((p) => p.data);
|
|
732
|
+
if (candidates.length === 0) return undefined;
|
|
733
|
+
return candidates.reduce((latest, s) =>
|
|
734
|
+
new TimeStamp(s.time).afterEq(new TimeStamp(latest.time)) ? s : latest,
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
/** Writes a fetched task and its included status. */
|
|
739
|
+
private writeThrough(task: Task): void {
|
|
740
|
+
this.store.set(task);
|
|
741
|
+
if (task.status != null) this.cfg.statusStore.set(task.status);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/** Fetches tasks with statuses and writes the statuses through. */
|
|
745
|
+
private async fetchThrough(req: RetrieveRequest): Promise<Task[]> {
|
|
746
|
+
const tasks = await this.execRetrieve({ ...req, includeStatus: true });
|
|
747
|
+
tasks.forEach((t) => {
|
|
748
|
+
if (t.status != null) this.cfg.statusStore.set(t.status);
|
|
749
|
+
});
|
|
750
|
+
return tasks;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
private async fetchSingle(q: SingleRequest): Promise<Task> {
|
|
754
|
+
let cached: Omit<Task, "status"> | undefined;
|
|
755
|
+
if (primitive.isNonZero(q.keys)) cached = this.store.get(q.keys[0]);
|
|
756
|
+
else if (primitive.isNonZero(q.names))
|
|
757
|
+
[cached] = this.store.get((t) => t.name === q.names?.[0]);
|
|
758
|
+
// A cached task without a cached status is ambiguous: the task may have
|
|
759
|
+
// no status or the status may not have synced. Only both count as a hit.
|
|
760
|
+
if (cached != null && this.cfg.statusStore.has(statusKey(cached.key)))
|
|
761
|
+
return this.compose(cached);
|
|
762
|
+
const tasks = await this.execRetrieve({ ...q, includeStatus: true });
|
|
763
|
+
checkForMultipleOrNoResults("Task", q, tasks, true);
|
|
764
|
+
this.writeThrough(tasks[0]);
|
|
765
|
+
return tasks[0];
|
|
346
766
|
}
|
|
347
767
|
|
|
348
768
|
sugar<S extends Schemas = Schemas>(payloads: Payload<S>[], schemas?: S): Task<S>[];
|
|
@@ -355,26 +775,37 @@ export class Client {
|
|
|
355
775
|
): Task<S>[] | Task<S> {
|
|
356
776
|
const isSingle = !Array.isArray(payloads);
|
|
357
777
|
const res = array.toArray(payloads).map(
|
|
358
|
-
({ key, name, type, config, status, internal, snapshot }) =>
|
|
778
|
+
({ key, rack, name, type, config, configHash, status, internal, snapshot }) =>
|
|
359
779
|
new Task(
|
|
360
780
|
{
|
|
361
781
|
key,
|
|
782
|
+
rack,
|
|
362
783
|
name,
|
|
363
784
|
type,
|
|
364
785
|
config,
|
|
786
|
+
configHash,
|
|
365
787
|
internal,
|
|
366
788
|
snapshot,
|
|
367
789
|
status,
|
|
368
790
|
},
|
|
369
791
|
schemas,
|
|
370
|
-
this.
|
|
371
|
-
this.
|
|
372
|
-
this.
|
|
792
|
+
this.cfg.framer,
|
|
793
|
+
this.cfg.ontology,
|
|
794
|
+
this.cfg.ranges,
|
|
373
795
|
),
|
|
374
796
|
);
|
|
375
797
|
return isSingle ? res[0] : res;
|
|
376
798
|
}
|
|
377
799
|
|
|
800
|
+
/**
|
|
801
|
+
* Fills a command's config hash from the cached task row. A command that carries
|
|
802
|
+
* the hash lets the Driver reuse its live instance instead of redeploying.
|
|
803
|
+
*/
|
|
804
|
+
private stampConfigHash(cmd: NewCommand): NewCommand {
|
|
805
|
+
if (cmd.configHash != null) return cmd;
|
|
806
|
+
return { ...cmd, configHash: this.store.get(cmd.task)?.configHash };
|
|
807
|
+
}
|
|
808
|
+
|
|
378
809
|
async executeCommand(params: ExecuteCommandParams): Promise<string>;
|
|
379
810
|
|
|
380
811
|
async executeCommand(params: ExecuteCommandsParams): Promise<string[]>;
|
|
@@ -383,8 +814,14 @@ export class Client {
|
|
|
383
814
|
params: ExecuteCommandParams | ExecuteCommandsParams,
|
|
384
815
|
): Promise<string | string[]> {
|
|
385
816
|
if ("commands" in params)
|
|
386
|
-
return await executeCommands({
|
|
387
|
-
|
|
817
|
+
return await executeCommands({
|
|
818
|
+
commands: params.commands.map((c) => this.stampConfigHash(c)),
|
|
819
|
+
frameClient: this.cfg.framer,
|
|
820
|
+
});
|
|
821
|
+
return await executeCommand({
|
|
822
|
+
...this.stampConfigHash(params),
|
|
823
|
+
frameClient: this.cfg.framer,
|
|
824
|
+
});
|
|
388
825
|
}
|
|
389
826
|
|
|
390
827
|
async executeCommandSync<StatusData extends z.ZodType = z.ZodNever>(
|
|
@@ -397,8 +834,7 @@ export class Client {
|
|
|
397
834
|
|
|
398
835
|
async executeCommandSync<StatusData extends z.ZodType = z.ZodNever>(
|
|
399
836
|
params:
|
|
400
|
-
|
|
|
401
|
-
| ExecuteCommandSyncParams<StatusData>,
|
|
837
|
+
ExecuteCommandsSyncParams<StatusData> | ExecuteCommandSyncParams<StatusData>,
|
|
402
838
|
): Promise<Status<StatusData> | Status<StatusData>[]> {
|
|
403
839
|
if ("commands" in params) {
|
|
404
840
|
const retrieveNames = async () => {
|
|
@@ -408,30 +844,52 @@ export class Client {
|
|
|
408
844
|
};
|
|
409
845
|
return await executeCommandsSync({
|
|
410
846
|
...params,
|
|
411
|
-
|
|
847
|
+
commands: params.commands.map((c) => this.stampConfigHash(c)),
|
|
848
|
+
frameClient: this.cfg.framer,
|
|
412
849
|
name: retrieveNames,
|
|
413
850
|
});
|
|
414
851
|
}
|
|
415
852
|
const retrieveName = async () => {
|
|
416
853
|
const { task } = params;
|
|
417
|
-
const t = await this.retrieve(
|
|
854
|
+
const t = await this.retrieve(task);
|
|
418
855
|
return t.name;
|
|
419
856
|
};
|
|
420
857
|
return await executeCommandSync({
|
|
421
|
-
frameClient: this.
|
|
858
|
+
frameClient: this.cfg.framer,
|
|
422
859
|
name: retrieveName,
|
|
423
860
|
...params,
|
|
861
|
+
configHash: params.configHash ?? this.store.get(params.task)?.configHash,
|
|
424
862
|
});
|
|
425
863
|
}
|
|
426
864
|
}
|
|
427
865
|
|
|
866
|
+
/** @returns the key of the status that reports on the given task. */
|
|
428
867
|
export const statusKey = (key: Key): string => ontology.idToString(ontologyID(key));
|
|
429
868
|
|
|
869
|
+
const taskStatusZ = z.object({ details: z.object({ task: keyZ }) });
|
|
870
|
+
|
|
871
|
+
// Task statuses may arrive under any status key; the referenced task lives in
|
|
872
|
+
// the details, with the "task:<key>" status key as a fallback.
|
|
873
|
+
const affectedTaskKeys = (
|
|
874
|
+
event: query.TableEvent<status.Key, status.Status>,
|
|
875
|
+
): Key[] | null => {
|
|
876
|
+
const keys: Key[] = [];
|
|
877
|
+
if (event.variant === "set") {
|
|
878
|
+
const parsed = taskStatusZ.safeParse(event.value);
|
|
879
|
+
if (parsed.success) keys.push(parsed.data.details.task);
|
|
880
|
+
}
|
|
881
|
+
const [type, key] = event.key.split(":");
|
|
882
|
+
if (type === "task" && primitive.isNonZero(key) && !keys.includes(key))
|
|
883
|
+
keys.push(key);
|
|
884
|
+
return keys.length === 0 ? null : keys;
|
|
885
|
+
};
|
|
886
|
+
|
|
430
887
|
interface ExecuteCommandInternalParams {
|
|
431
888
|
frameClient: framer.Client | null;
|
|
432
889
|
task: Key;
|
|
433
890
|
type: string;
|
|
434
891
|
args?: {};
|
|
892
|
+
configHash?: string;
|
|
435
893
|
}
|
|
436
894
|
|
|
437
895
|
const executeCommand = async ({
|
|
@@ -439,13 +897,25 @@ const executeCommand = async ({
|
|
|
439
897
|
task,
|
|
440
898
|
type,
|
|
441
899
|
args,
|
|
900
|
+
configHash,
|
|
442
901
|
}: ExecuteCommandInternalParams): Promise<string> =>
|
|
443
|
-
(
|
|
902
|
+
(
|
|
903
|
+
await executeCommands({
|
|
904
|
+
frameClient,
|
|
905
|
+
commands: [{ args, task, type, configHash }],
|
|
906
|
+
})
|
|
907
|
+
)[0];
|
|
444
908
|
|
|
909
|
+
/** A command queued for a task. */
|
|
445
910
|
export interface NewCommand {
|
|
446
911
|
task: Key;
|
|
447
912
|
type: string;
|
|
448
913
|
args?: {};
|
|
914
|
+
/**
|
|
915
|
+
* The config hash the sender wants running. Left unset, the client fills it from
|
|
916
|
+
* its cached task row.
|
|
917
|
+
*/
|
|
918
|
+
configHash?: string;
|
|
449
919
|
}
|
|
450
920
|
|
|
451
921
|
interface ExecuteCommandsInternalParams {
|
|
@@ -459,7 +929,11 @@ const executeCommands = async ({
|
|
|
459
929
|
}: ExecuteCommandsInternalParams): Promise<string[]> => {
|
|
460
930
|
if (frameClient == null) throw new Error("Task not created");
|
|
461
931
|
const w = await frameClient.openWriter(COMMAND_CHANNEL_NAME);
|
|
462
|
-
const cmds = commands.map((c) => ({
|
|
932
|
+
const cmds = commands.map((c) => ({
|
|
933
|
+
...c,
|
|
934
|
+
configHash: c.configHash ?? "",
|
|
935
|
+
key: id.create(),
|
|
936
|
+
}));
|
|
463
937
|
await w.write(COMMAND_CHANNEL_NAME, cmds);
|
|
464
938
|
await w.close();
|
|
465
939
|
return cmds.map((c) => c.key);
|
|
@@ -470,6 +944,7 @@ interface ExecuteCommandSyncInternalParams<StatusData extends z.ZodType = z.ZodN
|
|
|
470
944
|
Omit<ExecuteCommandsSyncInternalParams<StatusData>, "commands">,
|
|
471
945
|
TaskExecuteCommandSyncParams {
|
|
472
946
|
task: Key;
|
|
947
|
+
configHash?: string;
|
|
473
948
|
}
|
|
474
949
|
|
|
475
950
|
const executeCommandSync = async <StatusData extends z.ZodType = z.ZodNever>({
|
|
@@ -480,11 +955,12 @@ const executeCommandSync = async <StatusData extends z.ZodType = z.ZodNever>({
|
|
|
480
955
|
name: taskName,
|
|
481
956
|
statusDataZ,
|
|
482
957
|
args,
|
|
958
|
+
configHash,
|
|
483
959
|
}: ExecuteCommandSyncInternalParams<StatusData>): Promise<Status<StatusData>> =>
|
|
484
960
|
(
|
|
485
961
|
await executeCommandsSync({
|
|
486
962
|
frameClient,
|
|
487
|
-
commands: [{ args, task, type }],
|
|
963
|
+
commands: [{ args, task, type, configHash }],
|
|
488
964
|
timeout,
|
|
489
965
|
statusDataZ,
|
|
490
966
|
name: taskName,
|
|
@@ -502,7 +978,7 @@ interface ExecuteCommandsSyncInternalParams<StatusData extends z.ZodType = z.Zod
|
|
|
502
978
|
const executeCommandsSync = async <StatusData extends z.ZodType = z.ZodNever>({
|
|
503
979
|
frameClient,
|
|
504
980
|
commands,
|
|
505
|
-
timeout =
|
|
981
|
+
timeout = COMMAND_DEADLINE,
|
|
506
982
|
statusDataZ,
|
|
507
983
|
name: taskName,
|
|
508
984
|
}: ExecuteCommandsSyncInternalParams<StatusData>): Promise<Status<StatusData>[]> => {
|
|
@@ -514,23 +990,26 @@ const executeCommandsSync = async <StatusData extends z.ZodType = z.ZodNever>({
|
|
|
514
990
|
let timeoutID: NodeJS.Timeout | undefined;
|
|
515
991
|
const timeoutPromise = new Promise<never>((_, reject) => {
|
|
516
992
|
timeoutID = setTimeout(() => {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
reject
|
|
520
|
-
|
|
993
|
+
const taskKeys = commands.map((c) => c.task);
|
|
994
|
+
formatTimeoutError("command", taskName, parsedTimeout, taskKeys).then(
|
|
995
|
+
reject,
|
|
996
|
+
reject,
|
|
997
|
+
);
|
|
521
998
|
}, parsedTimeout.milliseconds);
|
|
522
999
|
});
|
|
523
1000
|
try {
|
|
524
1001
|
while (true) {
|
|
525
1002
|
const frame = await Promise.race([streamer.read(), timeoutPromise]);
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
)
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
1003
|
+
// A frame can hold statuses for other tasks and racks, which have a different
|
|
1004
|
+
// shape and fail to parse.
|
|
1005
|
+
for (const str of frame.get(status.SET_CHANNEL_NAME).toStrings()) {
|
|
1006
|
+
const res = statusZ(statusDataZ).safeParse(binary.JSON_CODEC.decodeString(str));
|
|
1007
|
+
if (!res.success) continue;
|
|
1008
|
+
const state = res.data;
|
|
1009
|
+
if (state.details.cmd == null || !cmdKeys.includes(state.details.cmd)) continue;
|
|
1010
|
+
states = [...states.filter((s) => s.key !== state.key), state];
|
|
1011
|
+
if (states.length === cmdKeys.length) return states;
|
|
1012
|
+
}
|
|
534
1013
|
}
|
|
535
1014
|
} finally {
|
|
536
1015
|
clearTimeout(timeoutID);
|