@readymadeit/mcp 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +114 -2
- package/bundle/LICENSE +201 -0
- package/bundle/boards/aggregator-demo-board.json +54 -0
- package/bundle/boards/alpaca-board.json +316 -0
- package/bundle/boards/animate-board.json +159 -0
- package/bundle/boards/ascii-art-demo-board.json +33 -0
- package/bundle/boards/ascii-cam-board.json +184 -0
- package/bundle/boards/asset-demo-board.json +54 -0
- package/bundle/boards/audio-encode-demo-board.json +153 -0
- package/bundle/boards/audiolize-board.json +152 -0
- package/bundle/boards/batcher-demo-board.json +43 -0
- package/bundle/boards/buffer-demo-board.json +53 -0
- package/bundle/boards/cache-demo-board.json +59 -0
- package/bundle/boards/camera-demo-board.json +28 -0
- package/bundle/boards/canvas-demo-board.json +55 -0
- package/bundle/boards/changes-demo-board.json +60 -0
- package/bundle/boards/court-booking-browser-demo-board.json +221 -0
- package/bundle/boards/court-booking-demo-board.json +218 -0
- package/bundle/boards/current-time-board.json +32 -0
- package/bundle/boards/debounce-demo-board.json +43 -0
- package/bundle/boards/decrypt-demo-board.json +47 -0
- package/bundle/boards/delay-demo-board.json +28 -0
- package/bundle/boards/detect-demo-board.json +64 -0
- package/bundle/boards/document-extract-demo-board.json +55 -0
- package/bundle/boards/dropitapp-board.json +138 -0
- package/bundle/boards/encode-demo-board.json +39 -0
- package/bundle/boards/encrypt-board.json +185 -0
- package/bundle/boards/encrypt-demo-board.json +39 -0
- package/bundle/boards/face-alert-board.json +181 -0
- package/bundle/boards/fetcher-demo-board.json +40 -0
- package/bundle/boards/fft-demo-board.json +28 -0
- package/bundle/boards/filter-demo-board.json +55 -0
- package/bundle/boards/flat-map-demo-board.json +42 -0
- package/bundle/boards/frame-limit-test-board.json +130 -0
- package/bundle/boards/game-board.json +413 -0
- package/bundle/boards/game-of-life-board.json +139 -0
- package/bundle/boards/game-of-life-demo-board.json +34 -0
- package/bundle/boards/gather-demo-board.json +62 -0
- package/bundle/boards/group-by-demo-board.json +62 -0
- package/bundle/boards/hacker-demo-board.json +45 -0
- package/bundle/boards/hacker-news-board.json +741 -0
- package/bundle/boards/hash-demo-board.json +40 -0
- package/bundle/boards/health-log-browser-demo-board.json +537 -0
- package/bundle/boards/health-log-demo-board.json +498 -0
- package/bundle/boards/helloworld-board.json +57 -0
- package/bundle/boards/hold-demo-board.json +67 -0
- package/bundle/boards/hold-scopes-demo-board.json +141 -0
- package/bundle/boards/http-client-browser-demo-board.json +379 -0
- package/bundle/boards/http-client-demo-board.json +380 -0
- package/bundle/boards/image-picker-demo-board.json +22 -0
- package/bundle/boards/imap-email-demo-board.json +35 -0
- package/bundle/boards/injector-demo-board.json +55 -0
- package/bundle/boards/iterator-demo-board.json +55 -0
- package/bundle/boards/limit-demo-board.json +66 -0
- package/bundle/boards/link-debugger.json +32 -0
- package/bundle/boards/live-location-demo-board.json +93 -0
- package/bundle/boards/live-radio-cloud-demo-board.json +216 -0
- package/bundle/boards/live-radio-cloud-direct-demo-board.json +311 -0
- package/bundle/boards/live-radio-demo-board.json +211 -0
- package/bundle/boards/live-radio-members-demo-board.json +314 -0
- package/bundle/boards/local-storage-demo-board.json +30 -0
- package/bundle/boards/lz-compress-demo-board.json +52 -0
- package/bundle/boards/map-demo-board.json +46 -0
- package/bundle/boards/match-filter-demo-board.json +43 -0
- package/bundle/boards/meeting-poll-browser-demo-board.json +649 -0
- package/bundle/boards/meeting-poll-demo-board.json +650 -0
- package/bundle/boards/microphone-monitor-demo-board.json +28 -0
- package/bundle/boards/microphone-speaker-demo-board.json +86 -0
- package/bundle/boards/monitor-demo-board.json +52 -0
- package/bundle/boards/mounted-endpoint-demo-board-hkp-rt.json +84 -0
- package/bundle/boards/mounted-endpoint-demo-board.json +84 -0
- package/bundle/boards/nested-rhythm-demo-board.json +1160 -0
- package/bundle/boards/next-bus-board.json +52 -0
- package/bundle/boards/next-bus-switch-board.json +79 -0
- package/bundle/boards/night-groove-demo-board.json +742 -0
- package/bundle/boards/noise-alert-board.json +146 -0
- package/bundle/boards/offer-followup-demo-board.json +291 -0
- package/bundle/boards/offer-intake-demo-board.json +289 -0
- package/bundle/boards/offer-intake-hetzner-demo-board.json +286 -0
- package/bundle/boards/offer-intake-imap-demo-board.json +289 -0
- package/bundle/boards/offer-intake-imap-hetzner-demo-board.json +354 -0
- package/bundle/boards/p2p-receiver-demo-board.json +65 -0
- package/bundle/boards/p2p-sender-demo-board.json +94 -0
- package/bundle/boards/pad-groove-demo-board.json +644 -0
- package/bundle/boards/peer-chat-board.json +109 -0
- package/bundle/boards/peer-chat-node-board.json +97 -0
- package/bundle/boards/qr-code-demo-board.json +22 -0
- package/bundle/boards/queue-demo-board.json +239 -0
- package/bundle/boards/reduce-demo-board.json +54 -0
- package/bundle/boards/remote-named-demo-board-hkp-rt.json +61 -0
- package/bundle/boards/remote-named-demo-board.json +61 -0
- package/bundle/boards/rss-demo-board.json +530 -0
- package/bundle/boards/rss-radio-board.json +515 -0
- package/bundle/boards/rss-radio-brief-one-board.json +237 -0
- package/bundle/boards/rss-radio-editor-unit-board.json +555 -0
- package/bundle/boards/rss-radio-library-unit-board.json +293 -0
- package/bundle/boards/rss-radio-unit-board.json +809 -0
- package/bundle/boards/rss-radio-voice-unit-board.json +146 -0
- package/bundle/boards/runtime-configs/hold-example.json +41 -0
- package/bundle/boards/runtime-configs/injector-example.json +23 -0
- package/bundle/boards/runtime-configs/speech-to-text-example.json +35 -0
- package/bundle/boards/runtime-configs/text-generation-example.json +31 -0
- package/bundle/boards/runtime-configs/text-to-speech-example.json +28 -0
- package/bundle/boards/runtime-configs/text-to-speech-inflect-example.json +28 -0
- package/bundle/boards/runtime-configs/ws-audio-playback-example.json +23 -0
- package/bundle/boards/select-demo-board.json +32 -0
- package/bundle/boards/send-ntfy-board.json +52 -0
- package/bundle/boards/shared-costs-demo-board.json +361 -0
- package/bundle/boards/sign-demo-board.json +41 -0
- package/bundle/boards/skill-router-demo-board.json +210 -0
- package/bundle/boards/smooth-demo-board.json +91 -0
- package/bundle/boards/smtp-email-demo-board.json +34 -0
- package/bundle/boards/sort-demo-board.json +55 -0
- package/bundle/boards/sound-demo-board.json +65 -0
- package/bundle/boards/spectral-modifier-board.json +98 -0
- package/bundle/boards/speech-synth-demo-board.json +37 -0
- package/bundle/boards/speech-to-text-demo-board.json +146 -0
- package/bundle/boards/spotify-board.json +75 -0
- package/bundle/boards/spread-demo-board.json +35 -0
- package/bundle/boards/sql-demo-board.json +56 -0
- package/bundle/boards/sql-explorer-board.json +447 -0
- package/bundle/boards/sql-explorer-node-board.json +474 -0
- package/bundle/boards/sql-import-board.json +156 -0
- package/bundle/boards/state-demo-board.json +65 -0
- package/bundle/boards/stopper-demo-board.json +40 -0
- package/bundle/boards/storage-demo-board.json +193 -0
- package/bundle/boards/store-demo-board.json +63 -0
- package/bundle/boards/swimlanes-demo-board.json +197 -0
- package/bundle/boards/switch-demo-board.json +51 -0
- package/bundle/boards/syn-board.json +19 -0
- package/bundle/boards/syn-booking-unit-board.json +998 -0
- package/bundle/boards/syn-conversations-anthropic-demo-board.json +925 -0
- package/bundle/boards/syn-conversations-demo-board.json +925 -0
- package/bundle/boards/syn-hotels-unit-board.json +287 -0
- package/bundle/boards/syn-mail-desk-board.json +25 -0
- package/bundle/boards/syn-mail-desk-unit-board.json +254 -0
- package/bundle/boards/telegram-listener-demo-board.json +31 -0
- package/bundle/boards/text-generation-anthropic-demo-board.json +66 -0
- package/bundle/boards/text-generation-demo-board.json +51 -0
- package/bundle/boards/text-generation-local-demo-board.json +80 -0
- package/bundle/boards/text-to-speech-demo-board.json +58 -0
- package/bundle/boards/timeline-demo-board.json +477 -0
- package/bundle/boards/timer-demo-board.json +35 -0
- package/bundle/boards/tracks-demo-board.json +95 -0
- package/bundle/boards/trigger-pad-demo-board.json +47 -0
- package/bundle/boards/triggerpad-board.json +31 -0
- package/bundle/boards/triggerpad-recorder-board.json +56 -0
- package/bundle/boards/uuid-generator-demo-board.json +166 -0
- package/bundle/boards/voice-assistant-demo-board.json +230 -0
- package/bundle/boards/voice-assistant-hkp-rt-demo-board.json +239 -0
- package/bundle/boards/voice-assistant-local-demo-board.json +232 -0
- package/bundle/boards/voice-assistant-skills-demo-board.json +316 -0
- package/bundle/boards/voice-assistant-skills-local-demo-board.json +316 -0
- package/bundle/boards/xy-pad-demo-board.json +36 -0
- package/bundle/docs/content/board-json.md +277 -0
- package/bundle/docs/content/boards/alpaca-board.md +56 -0
- package/bundle/docs/content/boards/animate-board.md +40 -0
- package/bundle/docs/content/boards/ascii-cam-board.md +37 -0
- package/bundle/docs/content/boards/audiolize-board.md +47 -0
- package/bundle/docs/content/boards/court-booking-browser-demo-board.md +43 -0
- package/bundle/docs/content/boards/court-booking-demo-board.md +120 -0
- package/bundle/docs/content/boards/current-time-board.md +32 -0
- package/bundle/docs/content/boards/dropitapp-board.md +57 -0
- package/bundle/docs/content/boards/encrypt-board.md +36 -0
- package/bundle/docs/content/boards/face-alert-board.md +50 -0
- package/bundle/docs/content/boards/game-board.md +69 -0
- package/bundle/docs/content/boards/game-of-life-board.md +47 -0
- package/bundle/docs/content/boards/hacker-news-board.md +76 -0
- package/bundle/docs/content/boards/health-log-browser-demo-board.md +56 -0
- package/bundle/docs/content/boards/health-log-demo-board.md +138 -0
- package/bundle/docs/content/boards/helloworld-board.md +40 -0
- package/bundle/docs/content/boards/link-debugger.md +31 -0
- package/bundle/docs/content/boards/live-radio-cloud-demo-board.md +70 -0
- package/bundle/docs/content/boards/live-radio-cloud-direct-demo-board.md +89 -0
- package/bundle/docs/content/boards/live-radio-demo-board.md +102 -0
- package/bundle/docs/content/boards/live-radio-members-demo-board.md +91 -0
- package/bundle/docs/content/boards/meeting-poll-browser-demo-board.md +45 -0
- package/bundle/docs/content/boards/meeting-poll-demo-board.md +121 -0
- package/bundle/docs/content/boards/mounted-endpoint-demo-board-hkp-rt.md +50 -0
- package/bundle/docs/content/boards/nested-rhythm-demo-board.md +165 -0
- package/bundle/docs/content/boards/next-bus-board.md +38 -0
- package/bundle/docs/content/boards/next-bus-switch-board.md +44 -0
- package/bundle/docs/content/boards/night-groove-demo-board.md +110 -0
- package/bundle/docs/content/boards/noise-alert-board.md +44 -0
- package/bundle/docs/content/boards/pad-groove-demo-board.md +93 -0
- package/bundle/docs/content/boards/peer-chat-board.md +49 -0
- package/bundle/docs/content/boards/peer-chat-node-board.md +47 -0
- package/bundle/docs/content/boards/rss-radio-board.md +221 -0
- package/bundle/docs/content/boards/send-ntfy-board.md +33 -0
- package/bundle/docs/content/boards/shared-costs-demo-board.md +65 -0
- package/bundle/docs/content/boards/spectral-modifier-board.md +55 -0
- package/bundle/docs/content/boards/spotify-board.md +46 -0
- package/bundle/docs/content/boards/sql-explorer-board.md +70 -0
- package/bundle/docs/content/boards/sql-explorer-node-board.md +76 -0
- package/bundle/docs/content/boards/sql-import-board.md +37 -0
- package/bundle/docs/content/boards/swimlanes-demo-board.md +148 -0
- package/bundle/docs/content/boards/syn-mail-desk-board.md +52 -0
- package/bundle/docs/content/boards/timeline-demo-board.md +115 -0
- package/bundle/docs/content/boards/triggerpad-board.md +32 -0
- package/bundle/docs/content/boards/triggerpad-recorder-board.md +52 -0
- package/bundle/docs/content/boards/voice-assistant-demo-board.md +51 -0
- package/bundle/docs/content/concepts/assets.md +245 -0
- package/bundle/docs/content/concepts/blocks.md +300 -0
- package/bundle/docs/content/concepts/board-assistant.md +307 -0
- package/bundle/docs/content/concepts/board.md +265 -0
- package/bundle/docs/content/concepts/cloud-boards.md +803 -0
- package/bundle/docs/content/concepts/coordinator.md +297 -0
- package/bundle/docs/content/concepts/logging.md +293 -0
- package/bundle/docs/content/concepts/mounts.md +314 -0
- package/bundle/docs/content/concepts/presets.md +360 -0
- package/bundle/docs/content/concepts/remotes.md +423 -0
- package/bundle/docs/content/concepts/runtime.md +664 -0
- package/bundle/docs/content/concepts/scopes.md +256 -0
- package/bundle/docs/content/concepts/service.md +227 -0
- package/bundle/docs/content/concepts/units.md +321 -0
- package/bundle/docs/content/introduction.md +163 -0
- package/bundle/docs/content/llm/circle-text-board.json +55 -0
- package/bundle/docs/content/llm/howto-workflow.md +369 -0
- package/bundle/docs/content/repository.md +161 -0
- package/bundle/docs/content/services/aggregator.md +76 -0
- package/bundle/docs/content/services/analyzer.md +44 -0
- package/bundle/docs/content/services/ascii-art.md +58 -0
- package/bundle/docs/content/services/asset.md +88 -0
- package/bundle/docs/content/services/audio-editor.md +57 -0
- package/bundle/docs/content/services/audio-encode.md +115 -0
- package/bundle/docs/content/services/audio-io.md +173 -0
- package/bundle/docs/content/services/batcher.md +49 -0
- package/bundle/docs/content/services/board-service.md +48 -0
- package/bundle/docs/content/services/browser-sub-service.md +75 -0
- package/bundle/docs/content/services/buffer.md +70 -0
- package/bundle/docs/content/services/cache.md +92 -0
- package/bundle/docs/content/services/camera.md +85 -0
- package/bundle/docs/content/services/canvas.md +196 -0
- package/bundle/docs/content/services/changes.md +87 -0
- package/bundle/docs/content/services/chunked-file-provider.md +63 -0
- package/bundle/docs/content/services/communication-dispatcher.md +190 -0
- package/bundle/docs/content/services/configurator.md +66 -0
- package/bundle/docs/content/services/conversations.md +244 -0
- package/bundle/docs/content/services/debounce.md +45 -0
- package/bundle/docs/content/services/decrypt.md +53 -0
- package/bundle/docs/content/services/delay.md +55 -0
- package/bundle/docs/content/services/detect.md +101 -0
- package/bundle/docs/content/services/document-extract.md +174 -0
- package/bundle/docs/content/services/download.md +67 -0
- package/bundle/docs/content/services/encode.md +63 -0
- package/bundle/docs/content/services/encrypt.md +53 -0
- package/bundle/docs/content/services/fetcher.md +122 -0
- package/bundle/docs/content/services/fft.md +96 -0
- package/bundle/docs/content/services/file-source.md +67 -0
- package/bundle/docs/content/services/filesystem.md +157 -0
- package/bundle/docs/content/services/filter.md +133 -0
- package/bundle/docs/content/services/flat-map.md +62 -0
- package/bundle/docs/content/services/game-of-life.md +93 -0
- package/bundle/docs/content/services/gather.md +135 -0
- package/bundle/docs/content/services/gif-encoder.md +56 -0
- package/bundle/docs/content/services/github.md +85 -0
- package/bundle/docs/content/services/group-by.md +54 -0
- package/bundle/docs/content/services/hacker.md +79 -0
- package/bundle/docs/content/services/hash.md +59 -0
- package/bundle/docs/content/services/hold.md +182 -0
- package/bundle/docs/content/services/http-relay-client.md +48 -0
- package/bundle/docs/content/services/http-uploader.md +62 -0
- package/bundle/docs/content/services/http.md +424 -0
- package/bundle/docs/content/services/if.md +79 -0
- package/bundle/docs/content/services/ifft.md +46 -0
- package/bundle/docs/content/services/image-picker.md +50 -0
- package/bundle/docs/content/services/imap-email.md +104 -0
- package/bundle/docs/content/services/injector.md +129 -0
- package/bundle/docs/content/services/input.md +90 -0
- package/bundle/docs/content/services/iterator.md +186 -0
- package/bundle/docs/content/services/join.md +153 -0
- package/bundle/docs/content/services/limit.md +47 -0
- package/bundle/docs/content/services/local-storage.md +47 -0
- package/bundle/docs/content/services/looper.md +62 -0
- package/bundle/docs/content/services/lz-compress.md +52 -0
- package/bundle/docs/content/services/map.md +257 -0
- package/bundle/docs/content/services/match-filter.md +38 -0
- package/bundle/docs/content/services/microphone-monitor.md +66 -0
- package/bundle/docs/content/services/monitor.md +67 -0
- package/bundle/docs/content/services/ollama.md +116 -0
- package/bundle/docs/content/services/openai-prompt.md +74 -0
- package/bundle/docs/content/services/output.md +107 -0
- package/bundle/docs/content/services/peer-socket.md +61 -0
- package/bundle/docs/content/services/qr-code.md +48 -0
- package/bundle/docs/content/services/queue.md +201 -0
- package/bundle/docs/content/services/reduce.md +51 -0
- package/bundle/docs/content/services/rss.md +232 -0
- package/bundle/docs/content/services/select.md +47 -0
- package/bundle/docs/content/services/sign.md +53 -0
- package/bundle/docs/content/services/skill-router.md +154 -0
- package/bundle/docs/content/services/smooth.md +59 -0
- package/bundle/docs/content/services/smtp-email.md +129 -0
- package/bundle/docs/content/services/sort.md +48 -0
- package/bundle/docs/content/services/sound.md +87 -0
- package/bundle/docs/content/services/speech-synth.md +46 -0
- package/bundle/docs/content/services/speech-to-text.md +172 -0
- package/bundle/docs/content/services/spotify.md +77 -0
- package/bundle/docs/content/services/spread.md +111 -0
- package/bundle/docs/content/services/sql.md +491 -0
- package/bundle/docs/content/services/state.md +57 -0
- package/bundle/docs/content/services/static.md +47 -0
- package/bundle/docs/content/services/stopper.md +55 -0
- package/bundle/docs/content/services/storage.md +155 -0
- package/bundle/docs/content/services/store.md +255 -0
- package/bundle/docs/content/services/sub-service.md +152 -0
- package/bundle/docs/content/services/switch.md +67 -0
- package/bundle/docs/content/services/telegram-listener.md +76 -0
- package/bundle/docs/content/services/text-generation.md +390 -0
- package/bundle/docs/content/services/text-to-speech.md +130 -0
- package/bundle/docs/content/services/timeline.md +333 -0
- package/bundle/docs/content/services/timer.md +113 -0
- package/bundle/docs/content/services/tracks.md +207 -0
- package/bundle/docs/content/services/trigger-pad.md +68 -0
- package/bundle/docs/content/services/uuid-generator.md +48 -0
- package/bundle/docs/content/services/wav-reader.md +66 -0
- package/bundle/docs/content/services/websocket.md +189 -0
- package/bundle/docs/content/services/workflow-board-builder.md +65 -0
- package/bundle/docs/content/services/xy-pad.md +60 -0
- package/bundle/docs/content/targets.md +434 -0
- package/bundle/docs/content/testing.md +263 -0
- package/bundle/docs/content/vocabulary.md +171 -0
- package/bundle/hkp-frontend/src/runtime/browser/BrowserRegistry.tsx +141 -0
- package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntime.tsx +202 -0
- package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeApi.ts +306 -0
- package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeApp.ts +310 -0
- package/bundle/hkp-frontend/src/runtime/browser/BrowserRuntimeScope.ts +500 -0
- package/bundle/hkp-frontend/src/runtime/browser/UIRegistry.ts +150 -0
- package/bundle/hkp-frontend/src/runtime/browser/assetResolver.ts +123 -0
- package/bundle/hkp-frontend/src/runtime/browser/pipelineNames.ts +65 -0
- package/bundle/hkp-frontend/src/runtime/browser/registry/Default.ts +237 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Aggregator.ts +127 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AggregatorUI.tsx +83 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Analyzer.tsx +43 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/Bars.tsx +33 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/HorizontalSpectrogram.tsx +53 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/VerticalSpectogram.tsx +56 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/Waveform.tsx +109 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AnalyzerUI/index.tsx +99 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AsciiArt.ts +119 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AsciiArtUI.tsx +131 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Asset.ts +125 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AssetUI.tsx +37 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioDeviceSettings.tsx +56 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioEditor.ts +129 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioEditorUI.tsx +549 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioInput.ts +298 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioInputUI.tsx +257 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioOutput.ts +189 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/AudioOutputUI.tsx +63 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Batcher.ts +11 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BoardService.tsx +86 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BoardServiceUI.tsx +410 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BrowserGather.ts +311 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BrowserIterator.ts +167 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BrowserSubService.tsx +583 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BrowserSubServiceUI.tsx +187 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/BrowserTracks.tsx +477 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Buffer.ts +11 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Cache.ts +134 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CacheUI.tsx +125 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Camera.ts +90 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CameraUI.tsx +321 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Canvas.ts +139 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/canvasDraw.ts +543 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/canvasUtils.ts +39 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/index.tsx +287 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/canvasDraw.test.ts +355 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/canvasUtils.test.ts +89 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/CanvasUI/tests/fullscreen.test.tsx +26 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Changes.ts +201 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ChangesUI.tsx +85 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ChunkedFileProvider.tsx +183 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Configurator.ts +258 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ConfiguratorUI.tsx +83 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ConsideredHacker.tsx +28 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Debounce.ts +75 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/DebounceUI.tsx +70 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Decrypt.ts +127 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/DecryptUI.tsx +39 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Delay.tsx +110 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Detect.ts +214 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/DetectUI.tsx +86 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Download.ts +120 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/DownloadUI.tsx +61 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Encode.ts +138 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/EncodeUI.tsx +52 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Encrypt.ts +125 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/EncryptUI.tsx +39 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FFT.tsx +238 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FFTUI.tsx +112 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FeedbackService.ts +247 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FeedbackServiceUI.tsx +35 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Fetcher.tsx +232 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FetcherUI.tsx +154 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FileSource.tsx +171 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Filter.tsx +18 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FilterUI.tsx +89 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FlatMap.ts +68 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/FlatMapUI.tsx +38 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLife.ts +210 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeRenderer.ts +182 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeRendererUI.tsx +48 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GameOfLifeUI.tsx +58 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GatherUI.tsx +84 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GifEncoder.tsx +651 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubAPI.ts +294 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubComponents.tsx +389 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubSink.tsx +109 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubSinkUI.tsx +143 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubSource.tsx +86 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GithubSourceUI.tsx +162 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/GroupBy.ts +11 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HTTPUploader.ts +102 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Hacker.ts +73 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HackerUI.tsx +134 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Hash.ts +134 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HashUI.tsx +45 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Hold.ts +288 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HoldUI.tsx +43 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HttpClient.ts +558 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HttpClientUI.tsx +212 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/HttpUploaderTokenInjector.ts +149 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/IfService.ts +231 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/IfServiceUI.tsx +50 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ImagePicker.tsx +118 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Injector.ts +61 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/InjectorUI.tsx +389 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Input.ts +214 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/InputUI.tsx +71 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/IteratorUI.tsx +59 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/LZCompress.ts +63 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Limit.ts +39 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/LimitUI.tsx +41 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/LocalStorage.ts +65 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/LocalStorageUI.tsx +72 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Map.ts +14 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MapUI.tsx +334 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MapUIModeAssist.tsx +61 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MatchFilter.ts +11 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MicrophoneMonitor.ts +190 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MicrophoneMonitorUI.tsx +94 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Monitor.tsx +15 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/MonitorUI.tsx +281 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPrompt.ts +237 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/BusyIndicator.tsx +18 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/PromptInput.tsx +71 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/StreamingPreview.tsx +24 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OllamaPromptUI/index.tsx +156 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OpenAIPrompt.ts +254 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OpenAIPromptUI.tsx +189 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Output.tsx +145 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/OutputUI.tsx +118 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PeerChatTemplate.json +43 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PeerConnection.ts +260 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocket.tsx +268 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocketReceiverTemplate.json +29 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PeerSocketUI.tsx +341 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/PlaceholderUI.tsx +72 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/QrCode.ts +63 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/QrCodeUI.tsx +197 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Select.ts +40 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SelectUI.tsx +41 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/ServiceBase.ts +50 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SetRuntimeVariable.ts +65 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SetRuntimeVariableUI.tsx +50 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Sign.ts +182 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SignUI.tsx +55 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Smooth.ts +101 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SmoothUI.tsx +50 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Sort.ts +59 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SortUI.tsx +61 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Sound.ts +541 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SoundUI.tsx +183 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpeechSynth.ts +56 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpeechSynthUI.tsx +108 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Spotify.tsx +111 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyAPI.ts +113 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyComponents.tsx +104 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpotifyUI.tsx +186 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Spread.ts +117 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SpreadUI.tsx +38 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Sql.ts +448 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SqlInspector.tsx +332 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SqlUI.tsx +226 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/State.ts +149 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Stopper.ts +29 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Switch.tsx +419 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/SwitchUI.tsx +171 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TickRuleDelta.ts +101 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TickRuleDeltaUI.tsx +56 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Timeline.ts +709 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/TimelinePanel.tsx +79 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/TimelineRows.tsx +574 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/Transport.tsx +141 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/index.tsx +119 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/model.ts +425 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimelineUI/parts.tsx +708 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/Timer.ts +15 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TimerUI.tsx +213 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TracksUI.tsx +81 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TriggerPad.ts +108 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/TriggerPadUI.tsx +160 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/UuidGenerator.ts +74 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/UuidGeneratorUI.tsx +59 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/WaveformDisplay.tsx +104 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/WebsocketClient.ts +114 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/WebsocketClientUI.tsx +42 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/WorkflowBoardBuilder.ts +499 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/WorkflowBoardBuilderUI.tsx +521 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/XYPad.ts +68 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/XYPadUI.tsx +274 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/audio/audioHelper.ts +36 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Batcher.ts +76 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Buffer.ts +142 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Filter.ts +125 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/GroupBy.ts +101 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Map.ts +543 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/MatchFilter.ts +49 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Monitor.ts +75 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Reduce.ts +74 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/Timer.ts +342 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/bundle.js +7375 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/eval.ts +208 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/expressionEval.ts +223 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/helpers.ts +10 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/base/index.ts +37 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/camera/videoCapture.ts +78 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/changes-modes.ts +9 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/colorpalette.ts +26 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/detect/DetectionPreview.tsx +76 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/detect/mediapipe.ts +34 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/detect/models/README.md +14 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/detect/models/blaze_face_short_range.tflite +0 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/detect-modes.ts +7 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/encode-modes.ts +10 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/helpers.ts +300 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/http-client-methods.ts +10 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/sql-database.ts +594 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/sql-dump.ts +192 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/sql-inspect.ts +130 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/sql-inspector.css +155 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/sql-modes.ts +27 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/TESTING_APPROACH.md +169 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/__snapshots__/service-ui.future-enhancements.test.tsx.snap +5 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/audio-input-permissions.test.ts +42 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/audiolizeLanes.test.ts +70 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/browser-scopes.test.ts +305 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/cache-service.test.ts +53 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/camera-video-capture.test.ts +24 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/changes-service.test.ts +133 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/crypto-secrets.test.ts +196 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/detect-service.test.ts +119 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/download.test.ts +100 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/expressionEval.test.ts +117 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/fetcher-panel.test.tsx +35 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/fetcher-service.test.ts +80 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/filter-service.test.ts +37 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/github-secrets.test.ts +108 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/group-by-board.test.ts +42 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/hold-service.test.ts +199 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/http-client-service.test.ts +474 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/http-uploader-token-injector.test.ts +152 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/iterator-gather-service.test.ts +277 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/map-service.test.ts +1047 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/map-ui.test.tsx +70 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/nested-rhythm-board.test.ts +311 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/night-groove-board.test.ts +290 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/pad-groove-board.test.ts +230 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/peer-host-discovery.test.ts +77 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/peer-socket-discovery.test.ts +69 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/pipeline-names.test.ts +63 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/secret-canary.test.ts +121 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-modules.contract.test.ts +229 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.advanced.test.tsx +670 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.future-enhancements.test.tsx +219 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.integration.test.tsx +432 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/service-ui.smoke.test.tsx +140 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sound-service.test.ts +293 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/spread-service.test.ts +137 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-dump.test.ts +172 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-inspect.test.ts +163 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql-inspector.test.tsx +121 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sql.test.ts +702 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/sub-service-in-block.test.tsx +84 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/switch-service.test.ts +254 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-board.test.ts +218 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-service.test.ts +1002 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-ui-model.test.ts +230 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/timeline-ui.test.tsx +371 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/timer-service.test.ts +902 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/tracks-service.test.ts +275 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/tracks-ui.test.tsx +126 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/triggerpad-recorder-board.test.ts +100 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/tests/uuid-generator-service.test.ts +214 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/timeline-core.ts +410 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/DefaultWorkflowBoard.ts +90 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/RefinementSession.ts +121 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/SystemPromptCatalog.ts +245 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/catalog/browser-service-specs.json +110 -0
- package/bundle/hkp-frontend/src/runtime/browser/services/workflow-prompt/catalog/runtime-capabilities.json +37 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/asset-service.test.ts +73 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/board-persistence.integration.test.tsx +391 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/browser-runtime.identity-binding.test.tsx +81 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/demo-boards.regression.test.tsx +386 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/failed-call-lifecycle.test.ts +56 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/http-client.integration.test.ts +146 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/nested-run.integration.test.ts +415 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/replay-next.test.ts +391 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/rerun.test.ts +71 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/run-no-input.test.ts +72 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-add.integration.test.tsx +256 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-operations.integration.test.tsx +310 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-processing.integration.test.ts +311 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-removal.integration.test.tsx +454 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/runtime-update.identity.integration.test.tsx +145 -0
- package/bundle/hkp-frontend/src/runtime/browser/tests/service-operations.integration.test.tsx +511 -0
- package/bundle/hkp-node/src/address.ts +72 -0
- package/bundle/hkp-node/src/assets.ts +582 -0
- package/bundle/hkp-node/src/auth.ts +369 -0
- package/bundle/hkp-node/src/callReport.ts +281 -0
- package/bundle/hkp-node/src/coordinator/auth.ts +85 -0
- package/bundle/hkp-node/src/coordinator/binaryFrame.ts +189 -0
- package/bundle/hkp-node/src/coordinator/boardStore.ts +0 -0
- package/bundle/hkp-node/src/coordinator/bridge.ts +242 -0
- package/bundle/hkp-node/src/coordinator/bridgeProtocol.ts +200 -0
- package/bundle/hkp-node/src/coordinator/coordinator.ts +594 -0
- package/bundle/hkp-node/src/coordinator/facadeAccess.ts +426 -0
- package/bundle/hkp-node/src/coordinator/fileBoardStore.ts +159 -0
- package/bundle/hkp-node/src/coordinator/frameLimits.ts +41 -0
- package/bundle/hkp-node/src/coordinator/index.ts +12 -0
- package/bundle/hkp-node/src/coordinator/join.ts +62 -0
- package/bundle/hkp-node/src/coordinator/logStore.ts +335 -0
- package/bundle/hkp-node/src/coordinator/members.ts +133 -0
- package/bundle/hkp-node/src/coordinator/mount.ts +124 -0
- package/bundle/hkp-node/src/coordinator/participantProtocol.ts +169 -0
- package/bundle/hkp-node/src/coordinator/participants.ts +666 -0
- package/bundle/hkp-node/src/coordinator/router.ts +416 -0
- package/bundle/hkp-node/src/coordinator/session.ts +1610 -0
- package/bundle/hkp-node/src/coordinator/types.ts +95 -0
- package/bundle/hkp-node/src/coordinatorLinks.ts +712 -0
- package/bundle/hkp-node/src/credentialedFetch.ts +122 -0
- package/bundle/hkp-node/src/egress.ts +344 -0
- package/bundle/hkp-node/src/expressionEval.ts +223 -0
- package/bundle/hkp-node/src/index.ts +470 -0
- package/bundle/hkp-node/src/instance.ts +172 -0
- package/bundle/hkp-node/src/mounts.ts +296 -0
- package/bundle/hkp-node/src/origins.ts +201 -0
- package/bundle/hkp-node/src/reset.ts +187 -0
- package/bundle/hkp-node/src/runtime.ts +1345 -0
- package/bundle/hkp-node/src/secrets.ts +292 -0
- package/bundle/hkp-node/src/server.ts +2120 -0
- package/bundle/hkp-node/src/services/asset.ts +150 -0
- package/bundle/hkp-node/src/services/claudeModels.ts +370 -0
- package/bundle/hkp-node/src/services/communication-dispatcher.ts +735 -0
- package/bundle/hkp-node/src/services/conversations.ts +914 -0
- package/bundle/hkp-node/src/services/database.ts +386 -0
- package/bundle/hkp-node/src/services/document-extract.ts +575 -0
- package/bundle/hkp-node/src/services/expression.ts +417 -0
- package/bundle/hkp-node/src/services/fileStore.ts +369 -0
- package/bundle/hkp-node/src/services/filesystem.ts +280 -0
- package/bundle/hkp-node/src/services/gather.ts +335 -0
- package/bundle/hkp-node/src/services/hold.ts +275 -0
- package/bundle/hkp-node/src/services/http-client.ts +525 -0
- package/bundle/hkp-node/src/services/http-server.ts +1222 -0
- package/bundle/hkp-node/src/services/imap-email.ts +627 -0
- package/bundle/hkp-node/src/services/injector.ts +135 -0
- package/bundle/hkp-node/src/services/iterator.ts +203 -0
- package/bundle/hkp-node/src/services/join.ts +226 -0
- package/bundle/hkp-node/src/services/map.ts +632 -0
- package/bundle/hkp-node/src/services/monitor.ts +128 -0
- package/bundle/hkp-node/src/services/nested-pipeline.ts +405 -0
- package/bundle/hkp-node/src/services/peer-server.ts +268 -0
- package/bundle/hkp-node/src/services/queue-store.ts +301 -0
- package/bundle/hkp-node/src/services/queue.ts +316 -0
- package/bundle/hkp-node/src/services/recordStore.ts +341 -0
- package/bundle/hkp-node/src/services/rss-parse.ts +281 -0
- package/bundle/hkp-node/src/services/rss.ts +392 -0
- package/bundle/hkp-node/src/services/smtp-email.ts +398 -0
- package/bundle/hkp-node/src/services/spread.ts +153 -0
- package/bundle/hkp-node/src/services/sql-dump.ts +192 -0
- package/bundle/hkp-node/src/services/sql.ts +429 -0
- package/bundle/hkp-node/src/services/stopper.ts +69 -0
- package/bundle/hkp-node/src/services/storage.ts +332 -0
- package/bundle/hkp-node/src/services/store.ts +609 -0
- package/bundle/hkp-node/src/services/stream.ts +367 -0
- package/bundle/hkp-node/src/services/sub-service.ts +600 -0
- package/bundle/hkp-node/src/services/telegram-listener.ts +263 -0
- package/bundle/hkp-node/src/services/telegram-sender.ts +136 -0
- package/bundle/hkp-node/src/services/text-generation.ts +1249 -0
- package/bundle/hkp-node/src/services/timer.ts +273 -0
- package/bundle/hkp-node/src/services/tracks.ts +381 -0
- package/bundle/hkp-node/src/services/websocket-reader.ts +364 -0
- package/bundle/hkp-node/src/types.ts +465 -0
- package/bundle/hkp-node/src/wsTickets.ts +77 -0
- package/bundle/hkp-node/src/yas.ts +95 -0
- package/bundle/hkp-python/src/hkp/__init__.py +1 -0
- package/bundle/hkp-python/src/hkp/__main__.py +241 -0
- package/bundle/hkp-python/src/hkp/address.py +56 -0
- package/bundle/hkp-python/src/hkp/assets.py +439 -0
- package/bundle/hkp-python/src/hkp/auth.py +252 -0
- package/bundle/hkp-python/src/hkp/binary_frame.py +100 -0
- package/bundle/hkp-python/src/hkp/call_report.py +201 -0
- package/bundle/hkp-python/src/hkp/coordinator_links.py +667 -0
- package/bundle/hkp-python/src/hkp/data.py +118 -0
- package/bundle/hkp-python/src/hkp/egress.py +310 -0
- package/bundle/hkp-python/src/hkp/mount.py +46 -0
- package/bundle/hkp-python/src/hkp/mounts.py +288 -0
- package/bundle/hkp-python/src/hkp/origins.py +169 -0
- package/bundle/hkp-python/src/hkp/runtime.py +1131 -0
- package/bundle/hkp-python/src/hkp/secrets.py +261 -0
- package/bundle/hkp-python/src/hkp/server.py +1714 -0
- package/bundle/hkp-python/src/hkp/services/__init__.py +0 -0
- package/bundle/hkp-python/src/hkp/services/asset.py +123 -0
- package/bundle/hkp-python/src/hkp/services/audio_encode.py +190 -0
- package/bundle/hkp-python/src/hkp/services/expression.py +942 -0
- package/bundle/hkp-python/src/hkp/services/gather.py +266 -0
- package/bundle/hkp-python/src/hkp/services/hold.py +246 -0
- package/bundle/hkp-python/src/hkp/services/http_client.py +444 -0
- package/bundle/hkp-python/src/hkp/services/http_server.py +790 -0
- package/bundle/hkp-python/src/hkp/services/iterator.py +141 -0
- package/bundle/hkp-python/src/hkp/services/join.py +173 -0
- package/bundle/hkp-python/src/hkp/services/map_service.py +452 -0
- package/bundle/hkp-python/src/hkp/services/monitor.py +99 -0
- package/bundle/hkp-python/src/hkp/services/nested_pipeline.py +278 -0
- package/bundle/hkp-python/src/hkp/services/skill_router.py +388 -0
- package/bundle/hkp-python/src/hkp/services/speech_to_text.py +186 -0
- package/bundle/hkp-python/src/hkp/services/spread.py +114 -0
- package/bundle/hkp-python/src/hkp/services/stopper.py +59 -0
- package/bundle/hkp-python/src/hkp/services/sub_service.py +417 -0
- package/bundle/hkp-python/src/hkp/services/text_generation.py +498 -0
- package/bundle/hkp-python/src/hkp/services/text_to_speech.py +237 -0
- package/bundle/hkp-python/src/hkp/services/timer.py +267 -0
- package/bundle/hkp-python/src/hkp/services/tracks.py +251 -0
- package/bundle/hkp-python/src/hkp/types.py +412 -0
- package/bundle/hkp-python/src/hkp/ws_tickets.py +54 -0
- package/bundle/hkp-python/src/hkp/yas.py +192 -0
- package/bundle/hkp-rt/lib/CMakeLists.txt +193 -0
- package/bundle/hkp-rt/lib/hkp-bundles/CMakeLists.txt +55 -0
- package/bundle/hkp-rt/lib/hkp-bundles/plugin_register.cpp +14 -0
- package/bundle/hkp-rt/lib/include/app.h +201 -0
- package/bundle/hkp-rt/lib/include/assets.h +239 -0
- package/bundle/hkp-rt/lib/include/auth.h +167 -0
- package/bundle/hkp-rt/lib/include/call_report.h +197 -0
- package/bundle/hkp-rt/lib/include/coordinator_links.h +127 -0
- package/bundle/hkp-rt/lib/include/discovery_hooks.h +29 -0
- package/bundle/hkp-rt/lib/include/egress.h +379 -0
- package/bundle/hkp-rt/lib/include/files.h +275 -0
- package/bundle/hkp-rt/lib/include/log_entry.h +131 -0
- package/bundle/hkp-rt/lib/include/mounts.h +139 -0
- package/bundle/hkp-rt/lib/include/origins.h +363 -0
- package/bundle/hkp-rt/lib/include/registry.h +119 -0
- package/bundle/hkp-rt/lib/include/secrets.h +414 -0
- package/bundle/hkp-rt/lib/include/server.h +122 -0
- package/bundle/hkp-rt/lib/include/service.h +190 -0
- package/bundle/hkp-rt/lib/include/slot_store.h +41 -0
- package/bundle/hkp-rt/lib/include/standalone_config.h +253 -0
- package/bundle/hkp-rt/lib/include/types/audio.h +3 -0
- package/bundle/hkp-rt/lib/include/types/data.h +152 -0
- package/bundle/hkp-rt/lib/include/types/message.h +56 -0
- package/bundle/hkp-rt/lib/include/types/models.h +154 -0
- package/bundle/hkp-rt/lib/include/types/owns_me.h +19 -0
- package/bundle/hkp-rt/lib/include/types/ringbuffer.h +86 -0
- package/bundle/hkp-rt/lib/include/types/types.h +33 -0
- package/bundle/hkp-rt/lib/include/types/validation.h +205 -0
- package/bundle/hkp-rt/lib/src/address.h +88 -0
- package/bundle/hkp-rt/lib/src/app.cpp +591 -0
- package/bundle/hkp-rt/lib/src/assets.cpp +686 -0
- package/bundle/hkp-rt/lib/src/binary_frame.h +154 -0
- package/bundle/hkp-rt/lib/src/common/expression.h +1481 -0
- package/bundle/hkp-rt/lib/src/common/inja.h +36 -0
- package/bundle/hkp-rt/lib/src/common/link_socket.cpp +437 -0
- package/bundle/hkp-rt/lib/src/common/link_socket.h +97 -0
- package/bundle/hkp-rt/lib/src/common/realtime_wakeup.h +120 -0
- package/bundle/hkp-rt/lib/src/common/stream_broadcast.h +250 -0
- package/bundle/hkp-rt/lib/src/common/string_util.h +31 -0
- package/bundle/hkp-rt/lib/src/common/websocket_client_session.cpp +217 -0
- package/bundle/hkp-rt/lib/src/common/websocket_client_session.h +37 -0
- package/bundle/hkp-rt/lib/src/common/websocket_config.h +119 -0
- package/bundle/hkp-rt/lib/src/common/websocket_protocol.h +32 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server.cpp +82 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server.h +57 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server_listener.cpp +115 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server_listener.h +35 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server_session.cpp +172 -0
- package/bundle/hkp-rt/lib/src/common/websocket_server_session.h +53 -0
- package/bundle/hkp-rt/lib/src/common.h +13 -0
- package/bundle/hkp-rt/lib/src/coordinator_links.cpp +1142 -0
- package/bundle/hkp-rt/lib/src/discovery/discovery.cpp +707 -0
- package/bundle/hkp-rt/lib/src/discovery/discovery.h +89 -0
- package/bundle/hkp-rt/lib/src/http/auth.cpp +569 -0
- package/bundle/hkp-rt/lib/src/http/front_door.cpp +518 -0
- package/bundle/hkp-rt/lib/src/http/front_door.h +131 -0
- package/bundle/hkp-rt/lib/src/http/server.cpp +1539 -0
- package/bundle/hkp-rt/lib/src/http/ws_tickets.h +125 -0
- package/bundle/hkp-rt/lib/src/mount.h +63 -0
- package/bundle/hkp-rt/lib/src/process_context.h +335 -0
- package/bundle/hkp-rt/lib/src/process_depth.h +20 -0
- package/bundle/hkp-rt/lib/src/registry.cpp +233 -0
- package/bundle/hkp-rt/lib/src/runtime.cpp +986 -0
- package/bundle/hkp-rt/lib/src/runtime.h +225 -0
- package/bundle/hkp-rt/lib/src/runtime_host.h +180 -0
- package/bundle/hkp-rt/lib/src/service.cpp +315 -0
- package/bundle/hkp-rt/lib/src/services/asset.h +185 -0
- package/bundle/hkp-rt/lib/src/services/audio_encode.cpp +372 -0
- package/bundle/hkp-rt/lib/src/services/audio_encode.h +97 -0
- package/bundle/hkp-rt/lib/src/services/cache.h +362 -0
- package/bundle/hkp-rt/lib/src/services/cache_subservices.h +463 -0
- package/bundle/hkp-rt/lib/src/services/core_audio.cpp +384 -0
- package/bundle/hkp-rt/lib/src/services/core_audio.h +22 -0
- package/bundle/hkp-rt/lib/src/services/core_input.h +337 -0
- package/bundle/hkp-rt/lib/src/services/core_output.h +370 -0
- package/bundle/hkp-rt/lib/src/services/ffmpeg/detail.cpp +749 -0
- package/bundle/hkp-rt/lib/src/services/ffmpeg/detail.h +29 -0
- package/bundle/hkp-rt/lib/src/services/ffmpeg/ffmpeg.cpp +193 -0
- package/bundle/hkp-rt/lib/src/services/ffmpeg/ffmpeg.h +40 -0
- package/bundle/hkp-rt/lib/src/services/ffmpeg/types.h +120 -0
- package/bundle/hkp-rt/lib/src/services/fft_service.h +190 -0
- package/bundle/hkp-rt/lib/src/services/filesystem.h +309 -0
- package/bundle/hkp-rt/lib/src/services/filter.h +208 -0
- package/bundle/hkp-rt/lib/src/services/gather.h +272 -0
- package/bundle/hkp-rt/lib/src/services/hold.h +304 -0
- package/bundle/hkp-rt/lib/src/services/http_client.cpp +347 -0
- package/bundle/hkp-rt/lib/src/services/http_client.h +67 -0
- package/bundle/hkp-rt/lib/src/services/http_client_impl.h +45 -0
- package/bundle/hkp-rt/lib/src/services/http_client_template_examples.md +202 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_listener.cpp +130 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_listener.h +33 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server.cpp +351 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server.h +79 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server_impl.cpp +230 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server_impl.h +64 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server_subservices.cpp +950 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_server_subservices.h +253 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_session.cpp +495 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_session.h +169 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_stream_listener.cpp +270 -0
- package/bundle/hkp-rt/lib/src/services/http_server/http_stream_listener.h +104 -0
- package/bundle/hkp-rt/lib/src/services/http_server/request_decode.h +164 -0
- package/bundle/hkp-rt/lib/src/services/if_service.h +210 -0
- package/bundle/hkp-rt/lib/src/services/ifft_service.h +198 -0
- package/bundle/hkp-rt/lib/src/services/injector.h +162 -0
- package/bundle/hkp-rt/lib/src/services/iterator.h +201 -0
- package/bundle/hkp-rt/lib/src/services/map.h +641 -0
- package/bundle/hkp-rt/lib/src/services/monitor.h +161 -0
- package/bundle/hkp-rt/lib/src/services/mp3_frames.h +119 -0
- package/bundle/hkp-rt/lib/src/services/mp4_to_wav.cpp +281 -0
- package/bundle/hkp-rt/lib/src/services/mp4_to_wav.h +263 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_registry.cpp +88 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_registry.h +43 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_server.h +163 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_listener.cpp +133 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_listener.h +46 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_session.cpp +165 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_server_session.h +44 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_ws_session.cpp +184 -0
- package/bundle/hkp-rt/lib/src/services/peer_server/peer_ws_session.h +55 -0
- package/bundle/hkp-rt/lib/src/services/receiver_session.h +172 -0
- package/bundle/hkp-rt/lib/src/services/root_certificates.h +3959 -0
- package/bundle/hkp-rt/lib/src/services/sha256_openssl.h +49 -0
- package/bundle/hkp-rt/lib/src/services/speech_http.h +306 -0
- package/bundle/hkp-rt/lib/src/services/speech_to_text.cpp +595 -0
- package/bundle/hkp-rt/lib/src/services/speech_to_text.h +69 -0
- package/bundle/hkp-rt/lib/src/services/static.cpp +45 -0
- package/bundle/hkp-rt/lib/src/services/static.h +41 -0
- package/bundle/hkp-rt/lib/src/services/stopper.h +72 -0
- package/bundle/hkp-rt/lib/src/services/sub_service.h +286 -0
- package/bundle/hkp-rt/lib/src/services/text_generation.cpp +1132 -0
- package/bundle/hkp-rt/lib/src/services/text_generation.h +71 -0
- package/bundle/hkp-rt/lib/src/services/text_to_speech.cpp +853 -0
- package/bundle/hkp-rt/lib/src/services/text_to_speech.h +97 -0
- package/bundle/hkp-rt/lib/src/services/timer.h +300 -0
- package/bundle/hkp-rt/lib/src/services/tracks.h +397 -0
- package/bundle/hkp-rt/lib/src/services/tts_inflect.cpp +149 -0
- package/bundle/hkp-rt/lib/src/services/tts_inflect.h +82 -0
- package/bundle/hkp-rt/lib/src/services/wav_reader.h +213 -0
- package/bundle/hkp-rt/lib/src/services/websocket_client_service.h +182 -0
- package/bundle/hkp-rt/lib/src/services/websocket_reader.h +148 -0
- package/bundle/hkp-rt/lib/src/services/websocket_server_service.h +196 -0
- package/bundle/hkp-rt/lib/src/services/websocket_writer.cpp +641 -0
- package/bundle/hkp-rt/lib/src/services/websocket_writer.h +117 -0
- package/bundle/hkp-rt/lib/src/sub_runtime.cpp +234 -0
- package/bundle/hkp-rt/lib/src/sub_runtime.h +160 -0
- package/bundle/hkp-rt/lib/src/types/data.cpp +237 -0
- package/bundle/hkp-rt/lib/src/types/message.cpp +148 -0
- package/bundle/hkp-rt/lib/src/types/models.cpp +83 -0
- package/bundle/hkp-rt/lib/src/types/ringbuffer.cpp +336 -0
- package/bundle/hkp-rt/lib/src/uuid.h +12 -0
- package/bundle/readymade-mcp-commits.json +5 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +79 -0
- package/dist/git.d.ts +8 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +53 -0
- package/dist/http.d.ts +17 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +130 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/repository.d.ts +49 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +452 -0
- package/dist/schemas.d.ts +156 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +43 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +83 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +20 -0
- package/dist/validation.d.ts +9 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +101 -0
- package/package.json +52 -4
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Documentation
|
|
3
|
+
* Service ID: queue
|
|
4
|
+
* Service Name: Queue
|
|
5
|
+
* Runtime: hkp-node
|
|
6
|
+
* Modes: publish | consume | ack | fail | list
|
|
7
|
+
* Key Config: mode, topic, payloadFrom, idFrom, limit, visibilitySeconds,
|
|
8
|
+
* maxAttempts, status
|
|
9
|
+
* IO: in=whatever is being sent (publish) or a claimed message (ack/fail)
|
|
10
|
+
* publish -> the message as stored
|
|
11
|
+
* consume -> { messages, count } — claimed; pair with `iterator`
|
|
12
|
+
* ack -> { id, status: "done" }
|
|
13
|
+
* fail -> { id, status: "pending" | "dead", attempts }
|
|
14
|
+
* list -> { messages, count } — reads without claiming
|
|
15
|
+
* Arrays: a published array is one message, not many (pair with `iterator`)
|
|
16
|
+
* Binary: not accepted
|
|
17
|
+
*
|
|
18
|
+
* How one board says something to another.
|
|
19
|
+
*
|
|
20
|
+
* A board owns its data, and a second board has no business reading the first
|
|
21
|
+
* one's tables — the whole reason the two are separate boards. What crosses is
|
|
22
|
+
* a *message*: a payload on a named topic, meaning nothing to the queue and
|
|
23
|
+
* everything to the two boards that agreed on the name.
|
|
24
|
+
*
|
|
25
|
+
* **The store is the owner's, not the board's.** Every other table in this
|
|
26
|
+
* runtime lives in a per-board file, which is what stops one board reading
|
|
27
|
+
* another's. A queue is the deliberate exception and the only one: publishing
|
|
28
|
+
* and consuming are by definition not the same board, so the rows live in the
|
|
29
|
+
* owner-wide database (`DatabaseStore.openShared`). Isolation still holds
|
|
30
|
+
* where it matters — between owners, and around everything that is not a
|
|
31
|
+
* message.
|
|
32
|
+
*
|
|
33
|
+
* **Nobody dispatches.** There is no delivery loop and no router: a board
|
|
34
|
+
* *pulls*, by putting a `consume` in a pipeline a `timer` drives, exactly as
|
|
35
|
+
* it polls anything else. A queue that pushed would be a wire between boards,
|
|
36
|
+
* and wires are the thing the ordered service list exists to avoid. What the
|
|
37
|
+
* queue adds is not routing but *time* — the two sides run on different
|
|
38
|
+
* clocks, and neither has to be up when the other speaks.
|
|
39
|
+
*
|
|
40
|
+
* **Both sides are on one runtime server.** The messages live with the runtime
|
|
41
|
+
* that took them in, and a board reaching them is a board on that same server —
|
|
42
|
+
* which is the same locality rule `conversations` and `sql` already have, not a
|
|
43
|
+
* new one. Two units that talk sit on one server until a coordinator, which
|
|
44
|
+
* already holds a credential for every runtime of a board, can make the claim
|
|
45
|
+
* on a consumer's behalf.
|
|
46
|
+
*
|
|
47
|
+
* **At-least-once, and the board says when.** `consume` claims a message for
|
|
48
|
+
* `visibilitySeconds` and hands it on; the pipeline does the work; an `ack`
|
|
49
|
+
* placed where success is known closes it. Anything that stops in between —
|
|
50
|
+
* a crash, a failed send, a runtime restarted mid-flight — leaves the claim to
|
|
51
|
+
* expire and the message to be handed out again. That is the honest guarantee
|
|
52
|
+
* for work driven by mail: the same enquiry twice is a nuisance, an enquiry
|
|
53
|
+
* lost is a customer. A message handed out `maxAttempts` times without an ack
|
|
54
|
+
* stops being retried and is marked `dead`, where it stays readable rather
|
|
55
|
+
* than disappearing.
|
|
56
|
+
*
|
|
57
|
+
* **Publish before you commit.** The one thing a board has to get right: a
|
|
58
|
+
* publish that fails passes nothing on and stops the pipeline, so the state
|
|
59
|
+
* change saying the message was sent must come *after* it. Ordered that way, a
|
|
60
|
+
* failed publish leaves the board where it was and the next tick sends it
|
|
61
|
+
* again — the board's own timer is the retry, and the framework needs no
|
|
62
|
+
* outbox to make it so.
|
|
63
|
+
*
|
|
64
|
+
* **Acked messages are kept.** A queue that deletes on ack answers "what is
|
|
65
|
+
* pending" and nothing else; the question actually asked while debugging is
|
|
66
|
+
* "what did the other board send me an hour ago, and what did I do with it".
|
|
67
|
+
* `list` reads the whole log, claim state and attempt count included.
|
|
68
|
+
*/
|
|
69
|
+
import {
|
|
70
|
+
HostedService,
|
|
71
|
+
JsonRecord,
|
|
72
|
+
RuntimeHost,
|
|
73
|
+
ServiceConfiguration,
|
|
74
|
+
ServiceRegistryEntry,
|
|
75
|
+
} from "../types";
|
|
76
|
+
import { Database, DatabaseStore } from "./database";
|
|
77
|
+
import * as queue from "./queue-store";
|
|
78
|
+
|
|
79
|
+
export const queueDescriptor: ServiceRegistryEntry = {
|
|
80
|
+
serviceId: "queue",
|
|
81
|
+
serviceName: "Queue",
|
|
82
|
+
version: "v1",
|
|
83
|
+
capabilities: [],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
type Mode = "publish" | "consume" | "ack" | "fail" | "list";
|
|
87
|
+
|
|
88
|
+
const MODES: Mode[] = ["publish", "consume", "ack", "fail", "list"];
|
|
89
|
+
|
|
90
|
+
type Notify = (payload: unknown, instanceId?: string) => void;
|
|
91
|
+
|
|
92
|
+
/** The value at a dotted path, or undefined where the path does not lead. */
|
|
93
|
+
function valueAt(input: unknown, path: string): unknown {
|
|
94
|
+
if (!path) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
let current: unknown = input;
|
|
98
|
+
for (const step of path.split(".")) {
|
|
99
|
+
if (current === null || typeof current !== "object") {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
current = (current as JsonRecord)[step];
|
|
103
|
+
}
|
|
104
|
+
return current;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function reason(err: unknown): string {
|
|
108
|
+
return err instanceof Error ? err.message : String(err);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export class QueueService implements HostedService {
|
|
112
|
+
readonly serviceId = queueDescriptor.serviceId;
|
|
113
|
+
readonly serviceName = queueDescriptor.serviceName;
|
|
114
|
+
readonly uuid: string;
|
|
115
|
+
|
|
116
|
+
private host: RuntimeHost | null = null;
|
|
117
|
+
private mode: Mode = "publish";
|
|
118
|
+
private topic = "";
|
|
119
|
+
private payloadFrom = "";
|
|
120
|
+
private idFrom = "id";
|
|
121
|
+
private limit = queue.DEFAULT_LIMIT;
|
|
122
|
+
private visibilitySeconds = queue.DEFAULT_VISIBILITY_SECONDS;
|
|
123
|
+
private maxAttempts = queue.DEFAULT_MAX_ATTEMPTS;
|
|
124
|
+
private status = "";
|
|
125
|
+
|
|
126
|
+
private lastCount = 0;
|
|
127
|
+
private lastError = "";
|
|
128
|
+
/** Owners whose table this instance has already created. */
|
|
129
|
+
private prepared = new Set<string>();
|
|
130
|
+
|
|
131
|
+
constructor(
|
|
132
|
+
config: ServiceConfiguration,
|
|
133
|
+
private readonly databases: DatabaseStore,
|
|
134
|
+
) {
|
|
135
|
+
this.uuid = config.uuid;
|
|
136
|
+
if (config.state) {
|
|
137
|
+
this.configure(config.state);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setHost(host: RuntimeHost): void {
|
|
142
|
+
this.host = host;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
getState(): JsonRecord {
|
|
146
|
+
return {
|
|
147
|
+
mode: this.mode,
|
|
148
|
+
topic: this.topic,
|
|
149
|
+
payloadFrom: this.payloadFrom,
|
|
150
|
+
idFrom: this.idFrom,
|
|
151
|
+
limit: this.limit,
|
|
152
|
+
visibilitySeconds: this.visibilitySeconds,
|
|
153
|
+
maxAttempts: this.maxAttempts,
|
|
154
|
+
status: this.status,
|
|
155
|
+
lastCount: this.lastCount,
|
|
156
|
+
error: this.lastError,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
configure(config: JsonRecord): JsonRecord {
|
|
161
|
+
if (typeof config.mode === "string" && MODES.includes(config.mode as Mode)) {
|
|
162
|
+
this.mode = config.mode as Mode;
|
|
163
|
+
}
|
|
164
|
+
if (typeof config.topic === "string") {
|
|
165
|
+
this.topic = config.topic.trim();
|
|
166
|
+
}
|
|
167
|
+
if (typeof config.payloadFrom === "string") {
|
|
168
|
+
this.payloadFrom = config.payloadFrom;
|
|
169
|
+
}
|
|
170
|
+
if (typeof config.idFrom === "string" && config.idFrom) {
|
|
171
|
+
this.idFrom = config.idFrom;
|
|
172
|
+
}
|
|
173
|
+
if (typeof config.limit === "number" && config.limit > 0) {
|
|
174
|
+
this.limit = Math.floor(config.limit);
|
|
175
|
+
}
|
|
176
|
+
if (typeof config.visibilitySeconds === "number" && config.visibilitySeconds > 0) {
|
|
177
|
+
this.visibilitySeconds = Math.floor(config.visibilitySeconds);
|
|
178
|
+
}
|
|
179
|
+
if (typeof config.maxAttempts === "number" && config.maxAttempts > 0) {
|
|
180
|
+
this.maxAttempts = Math.floor(config.maxAttempts);
|
|
181
|
+
}
|
|
182
|
+
if (typeof config.status === "string") {
|
|
183
|
+
this.status = config.status.trim();
|
|
184
|
+
}
|
|
185
|
+
return this.getState();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Runs the mode and returns what it produced.
|
|
190
|
+
*
|
|
191
|
+
* Synchronous, like `sql` and `conversations`: SQLite answers inside the
|
|
192
|
+
* call, so there is nothing to wait for.
|
|
193
|
+
*/
|
|
194
|
+
process(input: unknown, notify: Notify): unknown {
|
|
195
|
+
const scope = this.host?.scope();
|
|
196
|
+
if (!scope) {
|
|
197
|
+
return this.fail(notify, "queue has no runtime to scope its database to");
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
return this.run(input, notify, scope.owner, scope.boardName);
|
|
202
|
+
} catch (err) {
|
|
203
|
+
return this.fail(notify, `${this.mode} failed: ${reason(err)}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
destroy(): void {
|
|
208
|
+
this.host = null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ── Private ───────────────────────────────────────────────────────────────
|
|
212
|
+
|
|
213
|
+
private run(
|
|
214
|
+
input: unknown,
|
|
215
|
+
notify: Notify,
|
|
216
|
+
owner: string,
|
|
217
|
+
board: string,
|
|
218
|
+
): unknown {
|
|
219
|
+
let db: Database;
|
|
220
|
+
try {
|
|
221
|
+
db = this.databases.openShared(owner);
|
|
222
|
+
if (!this.prepared.has(owner)) {
|
|
223
|
+
queue.prepare(db);
|
|
224
|
+
this.prepared.add(owner);
|
|
225
|
+
}
|
|
226
|
+
} catch (err) {
|
|
227
|
+
return this.fail(notify, `could not open the owner's database: ${reason(err)}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
switch (this.mode) {
|
|
231
|
+
case "publish": {
|
|
232
|
+
if (!this.topic) {
|
|
233
|
+
return this.fail(notify, "publish needs a topic");
|
|
234
|
+
}
|
|
235
|
+
const payload = this.payloadFrom
|
|
236
|
+
? valueAt(input, this.payloadFrom)
|
|
237
|
+
: input;
|
|
238
|
+
if (payload === undefined || payload === null) {
|
|
239
|
+
// Nothing to say is not the same as saying nothing: a pipeline that
|
|
240
|
+
// produced no payload has not produced a message either.
|
|
241
|
+
return this.fail(
|
|
242
|
+
notify,
|
|
243
|
+
this.payloadFrom
|
|
244
|
+
? `nothing at '${this.payloadFrom}' to publish`
|
|
245
|
+
: "publish was given nothing to send",
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
return this.reported(
|
|
249
|
+
notify,
|
|
250
|
+
queue.publish(db, { topic: this.topic, payload, publishedBy: board }),
|
|
251
|
+
1,
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
case "consume": {
|
|
256
|
+
if (!this.topic) {
|
|
257
|
+
return this.fail(notify, "consume needs a topic");
|
|
258
|
+
}
|
|
259
|
+
const result = queue.consume(db, {
|
|
260
|
+
topic: this.topic,
|
|
261
|
+
limit: this.limit,
|
|
262
|
+
visibilitySeconds: this.visibilitySeconds,
|
|
263
|
+
maxAttempts: this.maxAttempts,
|
|
264
|
+
});
|
|
265
|
+
return this.reported(notify, result, result.count);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
case "ack":
|
|
269
|
+
case "fail": {
|
|
270
|
+
const id = valueAt(input, this.idFrom);
|
|
271
|
+
if (typeof id !== "string" || !id) {
|
|
272
|
+
return this.fail(
|
|
273
|
+
notify,
|
|
274
|
+
`${this.mode} needs the message id at '${this.idFrom}'`,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
const result = queue.close(db, {
|
|
278
|
+
id,
|
|
279
|
+
outcome: this.mode === "ack" ? "done" : "pending",
|
|
280
|
+
error: String(valueAt(input, "error") ?? ""),
|
|
281
|
+
maxAttempts: this.maxAttempts,
|
|
282
|
+
});
|
|
283
|
+
if (!result) {
|
|
284
|
+
return this.fail(notify, `no message '${id}'`);
|
|
285
|
+
}
|
|
286
|
+
return this.reported(notify, result, 1);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
case "list": {
|
|
290
|
+
const result = queue.list(db, {
|
|
291
|
+
topic: this.topic,
|
|
292
|
+
status: this.status,
|
|
293
|
+
limit: this.limit,
|
|
294
|
+
});
|
|
295
|
+
return this.reported(notify, result, result.count);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
default:
|
|
299
|
+
return this.fail(notify, `unknown mode '${this.mode}'`);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private reported(notify: Notify, result: unknown, count: number): unknown {
|
|
304
|
+
this.lastError = "";
|
|
305
|
+
this.lastCount = count;
|
|
306
|
+
notify(result);
|
|
307
|
+
return result;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
private fail(notify: Notify, error: string): null {
|
|
311
|
+
this.lastError = error;
|
|
312
|
+
this.host?.log("error", "service.failed", { message: error });
|
|
313
|
+
notify({ error });
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { promises as fs } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import { RuntimeScope } from "../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* What a board keeps between calls.
|
|
9
|
+
*
|
|
10
|
+
* ```
|
|
11
|
+
* <root>/<sha256(owner)>/<sha256(boardName)>/[<sha256(namespace)>/]<sha256(key)>.json
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* The same shape and the same reasoning as `coordinator/fileBoardStore.ts`: the
|
|
15
|
+
* names in those paths are **derived, never used directly**, because they all
|
|
16
|
+
* come from outside — an Auth0 `sub` contains characters that have no business
|
|
17
|
+
* in a path, and a key called `../../etc/passwd` must not be able to escape the
|
|
18
|
+
* root. Hashing also keeps `Foo` and `foo`, which are two keys here, from
|
|
19
|
+
* becoming one file on a case-insensitive filesystem. The real names are
|
|
20
|
+
* inside the file.
|
|
21
|
+
*
|
|
22
|
+
* One file per record rather than one map per board: a board that dumps every
|
|
23
|
+
* incoming message writes constantly and reads rarely, so appending a file must
|
|
24
|
+
* not mean rewriting everything before it, and a crash mid-write must cost the
|
|
25
|
+
* record being written rather than the table. Writes go to a temporary name and
|
|
26
|
+
* are renamed into place, which within one directory is atomic.
|
|
27
|
+
*
|
|
28
|
+
* Records carry whatever a board put in them, which for the workflows this
|
|
29
|
+
* exists for is correspondence — so the directories are `0o700` and the files
|
|
30
|
+
* `0o600`, the owner's to read and nobody else's.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/** Bumped only when the shape on disk changes; an unknown one is left alone. */
|
|
34
|
+
const FORMAT_VERSION = 1;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* A record, and whether somebody is currently dealing with it.
|
|
38
|
+
*
|
|
39
|
+
* A lease is what makes "released" different from "gone": the record has been
|
|
40
|
+
* handed to a pipeline and is no longer waiting, but it has not been settled
|
|
41
|
+
* either. Nothing removes it until something says the work finished, so a
|
|
42
|
+
* pipeline that fails leaves it recoverable rather than lost.
|
|
43
|
+
*/
|
|
44
|
+
export type RecordLease = {
|
|
45
|
+
/** When it was handed out. What a lease timeout would read. */
|
|
46
|
+
at: string;
|
|
47
|
+
/**
|
|
48
|
+
* The run it was handed to.
|
|
49
|
+
*
|
|
50
|
+
* How an acknowledgement at the far end of a pipeline knows which record it
|
|
51
|
+
* is settling: the run id threads through every service, including the ones
|
|
52
|
+
* that answer long after the pass that started them, so it survives the gap
|
|
53
|
+
* that the record's own key does not.
|
|
54
|
+
*/
|
|
55
|
+
run?: string;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type StoredRecord = {
|
|
59
|
+
key: string;
|
|
60
|
+
value: unknown;
|
|
61
|
+
createdAt: string;
|
|
62
|
+
updatedAt: string;
|
|
63
|
+
/** Absent while the record is waiting; present once it is being dealt with. */
|
|
64
|
+
lease?: RecordLease;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
type RecordFile = StoredRecord & { version: number };
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Which table a call means.
|
|
71
|
+
*
|
|
72
|
+
* The tenant and board come from the runtime and cannot be asked for; the
|
|
73
|
+
* namespace is the one part a board chooses, and it only ever subdivides what
|
|
74
|
+
* the runtime already granted. Empty means the board's own table — so a board
|
|
75
|
+
* that never mentions a namespace has exactly one, which is the common case.
|
|
76
|
+
*/
|
|
77
|
+
export type StoreScope = RuntimeScope & { namespace?: string };
|
|
78
|
+
|
|
79
|
+
export type RecordStore = {
|
|
80
|
+
put(scope: StoreScope, key: string, value: unknown): Promise<StoredRecord>;
|
|
81
|
+
get(scope: StoreScope, key: string): Promise<StoredRecord | null>;
|
|
82
|
+
/** Every record of one table, oldest first. */
|
|
83
|
+
list(scope: StoreScope): Promise<StoredRecord[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Hands a record out, or takes it back. Returns the record as it now stands,
|
|
86
|
+
* or null when there is none by that key.
|
|
87
|
+
*/
|
|
88
|
+
setLease(
|
|
89
|
+
scope: StoreScope,
|
|
90
|
+
key: string,
|
|
91
|
+
lease: RecordLease | null,
|
|
92
|
+
): Promise<StoredRecord | null>;
|
|
93
|
+
/** True when there was something to delete. */
|
|
94
|
+
remove(scope: StoreScope, key: string): Promise<boolean>;
|
|
95
|
+
/** Everything this table kept. Returns how many records went. */
|
|
96
|
+
clear(scope: StoreScope): Promise<number>;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
function hashed(value: string): string {
|
|
100
|
+
return createHash("sha256").update(value, "utf8").digest("hex");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isRecordFile(value: unknown): value is RecordFile {
|
|
104
|
+
if (!value || typeof value !== "object") {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
const record = value as Record<string, unknown>;
|
|
108
|
+
return (
|
|
109
|
+
typeof record.key === "string" &&
|
|
110
|
+
typeof record.createdAt === "string" &&
|
|
111
|
+
typeof record.updatedAt === "string" &&
|
|
112
|
+
"value" in record
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function createFileRecordStore(root: string): RecordStore {
|
|
117
|
+
// A namespace is a directory *inside* the board's, so the board's own table
|
|
118
|
+
// keeps the path it always had and a namespaced one cannot be reached from
|
|
119
|
+
// outside the board. Records are files ending in .json and namespaces are
|
|
120
|
+
// directories, so listing one never sees the other.
|
|
121
|
+
const tableDir = (scope: StoreScope) => {
|
|
122
|
+
const board = path.join(root, hashed(scope.owner), hashed(scope.boardName));
|
|
123
|
+
return scope.namespace ? path.join(board, hashed(scope.namespace)) : board;
|
|
124
|
+
};
|
|
125
|
+
const recordPath = (scope: StoreScope, key: string) =>
|
|
126
|
+
path.join(tableDir(scope), `${hashed(key)}.json`);
|
|
127
|
+
|
|
128
|
+
async function read(file: string): Promise<StoredRecord | null> {
|
|
129
|
+
let parsed: unknown;
|
|
130
|
+
try {
|
|
131
|
+
parsed = JSON.parse(await fs.readFile(file, "utf8"));
|
|
132
|
+
} catch {
|
|
133
|
+
// Missing is the common case and not an error; unreadable is rare and
|
|
134
|
+
// must not take the rest of the table down with it.
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if (!isRecordFile(parsed) || parsed.version !== FORMAT_VERSION) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
const { key, value, createdAt, updatedAt, lease } = parsed;
|
|
141
|
+
return { key, value, createdAt, updatedAt, ...(lease ? { lease } : {}) };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Writes a record whole, beside its target and then renamed into place: a
|
|
146
|
+
* rename within one directory is atomic, so a crash mid-write leaves the
|
|
147
|
+
* previous record intact rather than half of the new one.
|
|
148
|
+
*/
|
|
149
|
+
async function write(
|
|
150
|
+
scope: StoreScope,
|
|
151
|
+
record: StoredRecord,
|
|
152
|
+
): Promise<StoredRecord> {
|
|
153
|
+
const dir = tableDir(scope);
|
|
154
|
+
await fs.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
155
|
+
const file = recordPath(scope, record.key);
|
|
156
|
+
const contents: RecordFile = { version: FORMAT_VERSION, ...record };
|
|
157
|
+
const temporary = `${file}.${randomBytes(6).toString("hex")}.tmp`;
|
|
158
|
+
await fs.writeFile(temporary, JSON.stringify(contents), { mode: 0o600 });
|
|
159
|
+
try {
|
|
160
|
+
await fs.rename(temporary, file);
|
|
161
|
+
} catch (err) {
|
|
162
|
+
await fs.rm(temporary, { force: true });
|
|
163
|
+
throw err;
|
|
164
|
+
}
|
|
165
|
+
return record;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
async put(scope, key, value) {
|
|
170
|
+
const file = recordPath(scope, key);
|
|
171
|
+
const now = new Date().toISOString();
|
|
172
|
+
// Overwriting keeps the record's original age: when it first arrived is
|
|
173
|
+
// what orders a queue, and re-reading it later must not move it to the
|
|
174
|
+
// back of one.
|
|
175
|
+
const existing = await read(file);
|
|
176
|
+
const record: StoredRecord = {
|
|
177
|
+
key,
|
|
178
|
+
value,
|
|
179
|
+
createdAt: existing?.createdAt ?? now,
|
|
180
|
+
updatedAt: now,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
return write(scope, record);
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
async setLease(scope, key, lease) {
|
|
187
|
+
const record = await read(recordPath(scope, key));
|
|
188
|
+
if (!record) {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
// The value and its age are untouched: handing a record out is a fact
|
|
192
|
+
// about who is dealing with it, not an edit to what it says.
|
|
193
|
+
const updated: StoredRecord = { ...record };
|
|
194
|
+
if (lease) {
|
|
195
|
+
updated.lease = lease;
|
|
196
|
+
} else {
|
|
197
|
+
delete updated.lease;
|
|
198
|
+
}
|
|
199
|
+
return write(scope, updated);
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
async get(scope, key) {
|
|
203
|
+
return read(recordPath(scope, key));
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
async list(scope) {
|
|
207
|
+
let entries: string[];
|
|
208
|
+
try {
|
|
209
|
+
entries = await fs.readdir(tableDir(scope));
|
|
210
|
+
} catch {
|
|
211
|
+
// A board that has stored nothing has no directory, which is an empty
|
|
212
|
+
// table rather than an error.
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
const records: StoredRecord[] = [];
|
|
216
|
+
for (const entry of entries) {
|
|
217
|
+
// Only finished files: one still being written is under a temporary
|
|
218
|
+
// name, which does not end in .json.
|
|
219
|
+
if (!entry.endsWith(".json")) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const record = await read(path.join(tableDir(scope), entry));
|
|
223
|
+
if (record) {
|
|
224
|
+
records.push(record);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Oldest first, so a board reading its own table gets the order things
|
|
228
|
+
// arrived in — which is the order a queue is worked through.
|
|
229
|
+
records.sort((a, b) =>
|
|
230
|
+
a.createdAt === b.createdAt
|
|
231
|
+
? a.key.localeCompare(b.key)
|
|
232
|
+
: a.createdAt.localeCompare(b.createdAt),
|
|
233
|
+
);
|
|
234
|
+
return records;
|
|
235
|
+
},
|
|
236
|
+
|
|
237
|
+
async remove(scope, key) {
|
|
238
|
+
const file = recordPath(scope, key);
|
|
239
|
+
try {
|
|
240
|
+
await fs.rm(file);
|
|
241
|
+
return true;
|
|
242
|
+
} catch {
|
|
243
|
+
// Already gone is the outcome asked for, and worth saying apart from
|
|
244
|
+
// having deleted something.
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
|
|
249
|
+
async clear(scope) {
|
|
250
|
+
// Only this table's own records: removing the directory outright would
|
|
251
|
+
// take the namespaces nested inside it too, and emptying one table has no
|
|
252
|
+
// business emptying another.
|
|
253
|
+
const records = await this.list(scope);
|
|
254
|
+
await Promise.all(
|
|
255
|
+
records.map((record) =>
|
|
256
|
+
fs.rm(recordPath(scope, record.key), { force: true }),
|
|
257
|
+
),
|
|
258
|
+
);
|
|
259
|
+
return records.length;
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* A store that keeps nothing beyond the life of the process.
|
|
266
|
+
*
|
|
267
|
+
* What a runtime told to persist nothing uses, and what tests use. The service
|
|
268
|
+
* behaves identically against it — which is the point: a board should not have
|
|
269
|
+
* to know which one it is talking to.
|
|
270
|
+
*/
|
|
271
|
+
export function createMemoryRecordStore(): RecordStore {
|
|
272
|
+
const boards = new Map<string, Map<string, StoredRecord>>();
|
|
273
|
+
// NUL cannot occur in any of the three, so the join is unambiguous — the
|
|
274
|
+
// same reasoning as `tenantKey` in the server. Written as an escape rather
|
|
275
|
+
// than a literal control character, which does not survive an editor.
|
|
276
|
+
const keyOf = (scope: StoreScope) =>
|
|
277
|
+
`${scope.owner}\u0000${scope.boardName}\u0000${scope.namespace ?? ""}`;
|
|
278
|
+
const boardOf = (scope: StoreScope) => {
|
|
279
|
+
const id = keyOf(scope);
|
|
280
|
+
let board = boards.get(id);
|
|
281
|
+
if (!board) {
|
|
282
|
+
board = new Map();
|
|
283
|
+
boards.set(id, board);
|
|
284
|
+
}
|
|
285
|
+
return board;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
async put(scope, key, value) {
|
|
290
|
+
const board = boardOf(scope);
|
|
291
|
+
const now = new Date().toISOString();
|
|
292
|
+
const record: StoredRecord = {
|
|
293
|
+
key,
|
|
294
|
+
value,
|
|
295
|
+
createdAt: board.get(key)?.createdAt ?? now,
|
|
296
|
+
updatedAt: now,
|
|
297
|
+
};
|
|
298
|
+
board.set(key, record);
|
|
299
|
+
return record;
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
async get(scope, key) {
|
|
303
|
+
return boardOf(scope).get(key) ?? null;
|
|
304
|
+
},
|
|
305
|
+
|
|
306
|
+
async setLease(scope, key, lease) {
|
|
307
|
+
const board = boardOf(scope);
|
|
308
|
+
const record = board.get(key);
|
|
309
|
+
if (!record) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
const updated: StoredRecord = { ...record };
|
|
313
|
+
if (lease) {
|
|
314
|
+
updated.lease = lease;
|
|
315
|
+
} else {
|
|
316
|
+
delete updated.lease;
|
|
317
|
+
}
|
|
318
|
+
board.set(key, updated);
|
|
319
|
+
return updated;
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
async list(scope) {
|
|
323
|
+
return [...boardOf(scope).values()].sort((a, b) =>
|
|
324
|
+
a.createdAt === b.createdAt
|
|
325
|
+
? a.key.localeCompare(b.key)
|
|
326
|
+
: a.createdAt.localeCompare(b.createdAt),
|
|
327
|
+
);
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
async remove(scope, key) {
|
|
331
|
+
return boardOf(scope).delete(key);
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
async clear(scope) {
|
|
335
|
+
const board = boardOf(scope);
|
|
336
|
+
const size = board.size;
|
|
337
|
+
board.clear();
|
|
338
|
+
return size;
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
}
|