target-supabase-sdk 0.1.9 → 0.2.1
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 +184 -1
- package/dist/browser.d.ts +60 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +6 -0
- package/dist/browser.js.map +1 -0
- package/dist/chunks/create-logger-DyH3mZ8p.js +1028 -0
- package/dist/chunks/create-logger-DyH3mZ8p.js.map +1 -0
- package/dist/chunks/enable-log-persist-C_bSw6Kx.js +1362 -0
- package/dist/chunks/enable-log-persist-C_bSw6Kx.js.map +1 -0
- package/dist/chunks/word.interface-DLgRobKV.js +1973 -0
- package/dist/chunks/word.interface-DLgRobKV.js.map +1 -0
- package/dist/command/command.api.d.ts +1 -1
- package/dist/command/command.api.d.ts.map +1 -1
- package/dist/command/command.interface.d.ts +1 -1
- package/dist/command/command.interface.d.ts.map +1 -1
- package/dist/core.api.d.ts +10 -6
- package/dist/core.api.d.ts.map +1 -1
- package/dist/core.interface.d.ts +3 -2
- package/dist/core.interface.d.ts.map +1 -1
- package/dist/core.utils.d.ts +1 -1
- package/dist/core.utils.d.ts.map +1 -1
- package/dist/idea/idea.interface.d.ts +1 -1
- package/dist/idea/idea.interface.d.ts.map +1 -1
- package/dist/index.d.ts +2 -48
- package/dist/index.d.ts.map +1 -1
- package/dist/link/link.api.d.ts +1 -1
- package/dist/link/link.api.d.ts.map +1 -1
- package/dist/link/link.interface.d.ts +3 -3
- package/dist/link/link.interface.d.ts.map +1 -1
- package/dist/list/list.api.d.ts +3 -1
- package/dist/list/list.api.d.ts.map +1 -1
- package/dist/list/list.interface.d.ts +2 -2
- package/dist/list/list.interface.d.ts.map +1 -1
- package/dist/node/env/env-parsers.d.ts +19 -0
- package/dist/node/env/env-parsers.d.ts.map +1 -0
- package/dist/node/env/index.d.ts +11 -0
- package/dist/node/env/index.d.ts.map +1 -0
- package/dist/node/env/init-supabase-from-env.d.ts +17 -0
- package/dist/node/env/init-supabase-from-env.d.ts.map +1 -0
- package/dist/node/env/load-env.d.ts +20 -0
- package/dist/node/env/load-env.d.ts.map +1 -0
- package/dist/node/env/project-root.d.ts +11 -0
- package/dist/node/env/project-root.d.ts.map +1 -0
- package/dist/node/env/public-base-url.d.ts +10 -0
- package/dist/node/env/public-base-url.d.ts.map +1 -0
- package/dist/node/env/require-env.d.ts +3 -0
- package/dist/node/env/require-env.d.ts.map +1 -0
- package/dist/node/fs/json-state-store.d.ts +19 -0
- package/dist/node/fs/json-state-store.d.ts.map +1 -0
- package/dist/node/fs/read-source-file.d.ts +19 -0
- package/dist/node/fs/read-source-file.d.ts.map +1 -0
- package/dist/node/node-liveness.d.ts +30 -0
- package/dist/node/node-liveness.d.ts.map +1 -0
- package/dist/node/node-runtime.base.d.ts +60 -0
- package/dist/node/node-runtime.base.d.ts.map +1 -0
- package/dist/node/node.api.d.ts +4 -4
- package/dist/node/node.api.d.ts.map +1 -1
- package/dist/node/node.interface.d.ts +1 -6
- package/dist/node/node.interface.d.ts.map +1 -1
- package/dist/node/preload/run-service-preload.d.ts +14 -0
- package/dist/node/preload/run-service-preload.d.ts.map +1 -0
- package/dist/node/preload/service-preload.interface.d.ts +15 -0
- package/dist/node/preload/service-preload.interface.d.ts.map +1 -0
- package/dist/node/process/index.d.ts +5 -0
- package/dist/node/process/index.d.ts.map +1 -0
- package/dist/node/process/managed-child-processes.d.ts +37 -0
- package/dist/node/process/managed-child-processes.d.ts.map +1 -0
- package/dist/node/process/process-spawn.d.ts +27 -0
- package/dist/node/process/process-spawn.d.ts.map +1 -0
- package/dist/node/readiness/index.d.ts +9 -0
- package/dist/node/readiness/index.d.ts.map +1 -0
- package/dist/node/readiness/poll-until.d.ts +11 -0
- package/dist/node/readiness/poll-until.d.ts.map +1 -0
- package/dist/node/readiness/readiness-checks.d.ts +22 -0
- package/dist/node/readiness/readiness-checks.d.ts.map +1 -0
- package/dist/node/readiness/readiness.types.d.ts +12 -0
- package/dist/node/readiness/readiness.types.d.ts.map +1 -0
- package/dist/node/readiness/run-readiness-checks.d.ts +4 -0
- package/dist/node/readiness/run-readiness-checks.d.ts.map +1 -0
- package/dist/node/readiness/service-ready-gate.d.ts +26 -0
- package/dist/node/readiness/service-ready-gate.d.ts.map +1 -0
- package/dist/node.d.ts +36 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +2483 -0
- package/dist/node.js.map +1 -0
- package/dist/parcel/chunk-fetch-registry.d.ts +14 -0
- package/dist/parcel/chunk-fetch-registry.d.ts.map +1 -0
- package/dist/parcel/chunk-url.utils.d.ts +9 -0
- package/dist/parcel/chunk-url.utils.d.ts.map +1 -0
- package/dist/parcel/parcel-manager.d.ts +44 -20
- package/dist/parcel/parcel-manager.d.ts.map +1 -1
- package/dist/parcel/parcel.api.d.ts +306 -0
- package/dist/parcel/parcel.api.d.ts.map +1 -0
- package/dist/parcel/parcel.interface.d.ts +26 -5
- package/dist/parcel/parcel.interface.d.ts.map +1 -1
- package/dist/parcel/parcel.service.d.ts +38 -0
- package/dist/parcel/parcel.service.d.ts.map +1 -0
- package/dist/parcel/storage-provider-registry.d.ts +17 -0
- package/dist/parcel/storage-provider-registry.d.ts.map +1 -0
- package/dist/parcel/storage-provider.types.d.ts +31 -0
- package/dist/parcel/storage-provider.types.d.ts.map +1 -0
- package/dist/preload.d.ts +7 -0
- package/dist/preload.d.ts.map +1 -0
- package/dist/preload.js +47 -0
- package/dist/preload.js.map +1 -0
- package/dist/repo/repo-context.utils.d.ts.map +1 -1
- package/dist/repo/repo-manager.d.ts +14 -3
- package/dist/repo/repo-manager.d.ts.map +1 -1
- package/dist/repo/repo.api.d.ts +1 -1
- package/dist/repo/repo.api.d.ts.map +1 -1
- package/dist/repo/repo.interface.d.ts +1 -1
- package/dist/repo/repo.interface.d.ts.map +1 -1
- package/dist/repo/repo.script-loader.d.ts +5 -5
- package/dist/repo/repo.script-loader.d.ts.map +1 -1
- package/dist/service/base.interface.d.ts +54 -57
- package/dist/service/base.interface.d.ts.map +1 -1
- package/dist/service/index.d.ts +21 -0
- package/dist/service/index.d.ts.map +1 -0
- package/dist/service/service.api.d.ts +503 -0
- package/dist/service/service.api.d.ts.map +1 -0
- package/dist/service/service.interface.d.ts +36 -9
- package/dist/service/service.interface.d.ts.map +1 -1
- package/dist/shared/http/fetch-retry.d.ts +21 -0
- package/dist/shared/http/fetch-retry.d.ts.map +1 -0
- package/dist/shared/log/create-logger.d.ts +27 -0
- package/dist/shared/log/create-logger.d.ts.map +1 -0
- package/dist/shared/log/enable-log-persist.d.ts +28 -0
- package/dist/shared/log/enable-log-persist.d.ts.map +1 -0
- package/dist/shared/log/index.d.ts +10 -0
- package/dist/shared/log/index.d.ts.map +1 -0
- package/dist/shared/log/log-manager.d.ts +37 -60
- package/dist/shared/log/log-manager.d.ts.map +1 -1
- package/dist/shared/log/log-persist-batch-id.d.ts +13 -0
- package/dist/shared/log/log-persist-batch-id.d.ts.map +1 -0
- package/dist/shared/log/log-persist-flush.d.ts +8 -0
- package/dist/shared/log/log-persist-flush.d.ts.map +1 -0
- package/dist/shared/log/log-persist-hook.d.ts +6 -0
- package/dist/shared/log/log-persist-hook.d.ts.map +1 -0
- package/dist/shared/log/log-persist-logger.d.ts +15 -0
- package/dist/shared/log/log-persist-logger.d.ts.map +1 -0
- package/dist/shared/log/log-persist-registry.d.ts +17 -0
- package/dist/shared/log/log-persist-registry.d.ts.map +1 -0
- package/dist/shared/log/log-persist.config.d.ts +10 -0
- package/dist/shared/log/log-persist.config.d.ts.map +1 -0
- package/dist/shared/log/log-persist.d.ts +55 -0
- package/dist/shared/log/log-persist.d.ts.map +1 -0
- package/dist/shared/log/log-persist.interface.d.ts +116 -0
- package/dist/shared/log/log-persist.interface.d.ts.map +1 -0
- package/dist/shared/log/log-scope.d.ts +56 -0
- package/dist/shared/log/log-scope.d.ts.map +1 -0
- package/dist/shared/utils/fetch-url.d.ts +3 -0
- package/dist/shared/utils/fetch-url.d.ts.map +1 -0
- package/dist/shared/utils/network-error.d.ts +14 -0
- package/dist/shared/utils/network-error.d.ts.map +1 -0
- package/dist/shared/utils/safe-file-name.d.ts +14 -0
- package/dist/shared/utils/safe-file-name.d.ts.map +1 -0
- package/dist/shared/utils/sha256.d.ts +3 -0
- package/dist/shared/utils/sha256.d.ts.map +1 -0
- package/dist/supabase.d.ts +7 -2
- package/dist/supabase.d.ts.map +1 -1
- package/dist/task/index.d.ts +16 -0
- package/dist/task/index.d.ts.map +1 -0
- package/dist/task/local-task-registry.d.ts +11 -1
- package/dist/task/local-task-registry.d.ts.map +1 -1
- package/dist/task/task-manager.d.ts +21 -11
- package/dist/task/task-manager.d.ts.map +1 -1
- package/dist/task/task-node.d.ts +19 -0
- package/dist/task/task-node.d.ts.map +1 -0
- package/dist/task/task-post-validated.api.d.ts +19 -0
- package/dist/task/task-post-validated.api.d.ts.map +1 -0
- package/dist/task/task-post.api.d.ts +54 -0
- package/dist/task/task-post.api.d.ts.map +1 -0
- package/dist/task/task-queue.d.ts +7 -0
- package/dist/task/task-queue.d.ts.map +1 -0
- package/dist/task/task-repo-context.d.ts +2 -0
- package/dist/task/task-repo-context.d.ts.map +1 -1
- package/dist/task/task-repo-validation.d.ts +46 -0
- package/dist/task/task-repo-validation.d.ts.map +1 -0
- package/dist/task/task.api.d.ts +5 -47
- package/dist/task/task.api.d.ts.map +1 -1
- package/dist/task/task.constant.d.ts +4 -0
- package/dist/task/task.constant.d.ts.map +1 -0
- package/dist/task/task.interface.d.ts +3 -1
- package/dist/task/task.interface.d.ts.map +1 -1
- package/dist/trigger/trigger-manager.d.ts +25 -0
- package/dist/trigger/trigger-manager.d.ts.map +1 -0
- package/dist/trigger/trigger-node.d.ts +23 -0
- package/dist/trigger/trigger-node.d.ts.map +1 -0
- package/dist/trigger/trigger.api.d.ts +140 -0
- package/dist/trigger/trigger.api.d.ts.map +1 -0
- package/dist/trigger/trigger.constant.d.ts +8 -0
- package/dist/trigger/trigger.constant.d.ts.map +1 -0
- package/dist/trigger/trigger.interface.d.ts +87 -0
- package/dist/trigger/trigger.interface.d.ts.map +1 -0
- package/dist/trigger/trigger.utils.d.ts +6 -0
- package/dist/trigger/trigger.utils.d.ts.map +1 -0
- package/dist/word/word.api.d.ts +1 -1
- package/dist/word/word.api.d.ts.map +1 -1
- package/dist/word/word.interface.d.ts +2 -2
- package/dist/word/word.interface.d.ts.map +1 -1
- package/package.json +91 -61
- package/src/browser.ts +165 -0
- package/src/command/command.api.ts +20 -18
- package/src/command/command.interface.ts +2 -3
- package/src/core.api.ts +466 -477
- package/src/core.interface.ts +63 -62
- package/src/core.utils.ts +64 -64
- package/src/idea/idea.interface.ts +3 -3
- package/src/index.ts +2 -79
- package/src/link/link.api.ts +28 -30
- package/src/link/link.interface.ts +4 -5
- package/src/list/list.api.ts +50 -29
- package/src/list/list.interface.ts +3 -4
- package/src/node/env/env-parsers.ts +77 -0
- package/src/node/env/index.ts +10 -0
- package/src/node/env/init-supabase-from-env.ts +38 -0
- package/src/node/env/load-env.ts +67 -0
- package/src/node/env/project-root.ts +34 -0
- package/src/node/env/public-base-url.ts +18 -0
- package/src/node/env/require-env.ts +15 -0
- package/src/node/fs/json-state-store.ts +97 -0
- package/src/node/fs/read-source-file.ts +75 -0
- package/src/node/node-liveness.ts +80 -0
- package/src/node/node-runtime.base.ts +481 -0
- package/src/node/node.api.ts +12 -11
- package/src/node/node.interface.ts +1 -8
- package/src/node/node.utils.ts +1 -1
- package/src/node/preload/run-service-preload.ts +48 -0
- package/src/node/preload/service-preload.interface.ts +14 -0
- package/src/node/process/index.ts +8 -0
- package/src/node/process/managed-child-processes.ts +121 -0
- package/src/node/process/process-spawn.ts +61 -0
- package/src/node/readiness/index.ts +20 -0
- package/src/node/readiness/poll-until.ts +27 -0
- package/src/node/readiness/readiness-checks.ts +79 -0
- package/src/node/readiness/readiness.types.ts +13 -0
- package/src/node/readiness/run-readiness-checks.ts +20 -0
- package/src/node/readiness/service-ready-gate.ts +65 -0
- package/src/node.ts +153 -0
- package/src/parcel/chunk-fetch-registry.ts +96 -0
- package/src/parcel/chunk-url.utils.ts +30 -0
- package/src/parcel/parcel-manager.ts +431 -173
- package/src/parcel/parcel.api.ts +103 -0
- package/src/parcel/parcel.interface.ts +44 -23
- package/src/parcel/parcel.service.ts +79 -0
- package/src/parcel/storage-provider-registry.ts +49 -0
- package/src/parcel/storage-provider.types.ts +45 -0
- package/src/preload.ts +7 -0
- package/src/repo/repo-context.utils.ts +3 -4
- package/src/repo/repo-manager.ts +54 -39
- package/src/repo/repo.api.ts +5 -5
- package/src/repo/repo.interface.ts +1 -2
- package/src/repo/repo.script-loader.ts +16 -20
- package/src/service/base.interface.ts +81 -90
- package/src/service/index.ts +173 -0
- package/src/service/service.api.ts +294 -0
- package/src/service/service.interface.ts +49 -17
- package/src/shared/http/fetch-retry.ts +145 -0
- package/src/shared/log/create-logger.ts +51 -0
- package/src/shared/log/enable-log-persist.ts +225 -0
- package/src/shared/log/index.ts +31 -0
- package/src/shared/log/log-manager.ts +112 -121
- package/src/shared/log/log-persist-batch-id.ts +43 -0
- package/src/shared/log/log-persist-flush.ts +128 -0
- package/src/shared/log/log-persist-hook.ts +13 -0
- package/src/shared/log/log-persist-logger.ts +33 -0
- package/src/shared/log/log-persist-registry.ts +109 -0
- package/src/shared/log/log-persist.config.ts +97 -0
- package/src/shared/log/log-persist.interface.ts +132 -0
- package/src/shared/log/log-persist.ts +704 -0
- package/src/shared/log/log-scope.ts +123 -0
- package/src/shared/utils/config-path.utils.ts +1 -1
- package/src/shared/utils/fetch-url.ts +13 -0
- package/src/shared/utils/network-error.ts +152 -0
- package/src/shared/utils/safe-file-name.ts +37 -0
- package/src/shared/utils/sha256.ts +15 -0
- package/src/supabase.ts +125 -119
- package/src/task/index.ts +45 -0
- package/src/task/local-task-registry.ts +115 -36
- package/src/task/task-manager.ts +101 -113
- package/src/task/task-node.ts +302 -0
- package/src/task/task-post-validated.api.ts +47 -0
- package/src/task/task-post.api.ts +99 -0
- package/src/task/task-queue.ts +18 -0
- package/src/task/task-repo-context.ts +4 -1
- package/src/task/task-repo-validation.ts +169 -0
- package/src/task/task.api.ts +68 -92
- package/src/task/task.constant.ts +4 -0
- package/src/task/task.interface.ts +6 -7
- package/src/trigger/trigger-manager.ts +287 -0
- package/src/trigger/trigger-node.ts +80 -0
- package/src/trigger/trigger.api.ts +166 -0
- package/src/trigger/trigger.constant.ts +10 -0
- package/src/trigger/trigger.interface.ts +100 -0
- package/src/trigger/trigger.utils.ts +56 -0
- package/src/word/word.api.ts +28 -30
- package/src/word/word.interface.ts +3 -4
- package/dist/auth/auth.api.d.ts +0 -28
- package/dist/auth/auth.api.d.ts.map +0 -1
- package/dist/auth/auth.api.js +0 -51
- package/dist/auth/auth.api.js.map +0 -1
- package/dist/command/command.api.js +0 -58
- package/dist/command/command.api.js.map +0 -1
- package/dist/command/command.interface.js +0 -9
- package/dist/command/command.interface.js.map +0 -1
- package/dist/core.api.js +0 -412
- package/dist/core.api.js.map +0 -1
- package/dist/core.interface.js +0 -46
- package/dist/core.interface.js.map +0 -1
- package/dist/core.utils.js +0 -81
- package/dist/core.utils.js.map +0 -1
- package/dist/feed/feed.interface.d.ts +0 -27
- package/dist/feed/feed.interface.d.ts.map +0 -1
- package/dist/feed/feed.interface.js +0 -17
- package/dist/feed/feed.interface.js.map +0 -1
- package/dist/file/file-manager.d.ts +0 -24
- package/dist/file/file-manager.d.ts.map +0 -1
- package/dist/file/file-manager.js +0 -109
- package/dist/file/file-manager.js.map +0 -1
- package/dist/file/file.api.d.ts +0 -15
- package/dist/file/file.api.d.ts.map +0 -1
- package/dist/file/file.api.js +0 -30
- package/dist/file/file.api.js.map +0 -1
- package/dist/file/file.interface.d.ts +0 -25
- package/dist/file/file.interface.d.ts.map +0 -1
- package/dist/file/file.interface.js +0 -9
- package/dist/file/file.interface.js.map +0 -1
- package/dist/file-list/file-list.api.d.ts +0 -15
- package/dist/file-list/file-list.api.d.ts.map +0 -1
- package/dist/file-list/file-list.api.js +0 -54
- package/dist/file-list/file-list.api.js.map +0 -1
- package/dist/file-list/file-list.interface.d.ts +0 -22
- package/dist/file-list/file-list.interface.d.ts.map +0 -1
- package/dist/file-list/file-list.interface.js +0 -5
- package/dist/file-list/file-list.interface.js.map +0 -1
- package/dist/idea/idea.interface.js +0 -15
- package/dist/idea/idea.interface.js.map +0 -1
- package/dist/index.js +0 -42
- package/dist/index.js.map +0 -1
- package/dist/link/link.api.js +0 -30
- package/dist/link/link.api.js.map +0 -1
- package/dist/link/link.interface.js +0 -7
- package/dist/link/link.interface.js.map +0 -1
- package/dist/list/list.api.js +0 -30
- package/dist/list/list.api.js.map +0 -1
- package/dist/list/list.interface.js +0 -6
- package/dist/list/list.interface.js.map +0 -1
- package/dist/node/node-manager.d.ts +0 -48
- package/dist/node/node-manager.d.ts.map +0 -1
- package/dist/node/node-manager.js +0 -619
- package/dist/node/node-manager.js.map +0 -1
- package/dist/node/node-task.preset.d.ts +0 -1
- package/dist/node/node-task.preset.d.ts.map +0 -1
- package/dist/node/node-task.preset.js +0 -14
- package/dist/node/node-task.preset.js.map +0 -1
- package/dist/node/node.api.js +0 -100
- package/dist/node/node.api.js.map +0 -1
- package/dist/node/node.interface.js +0 -19
- package/dist/node/node.interface.js.map +0 -1
- package/dist/node/node.utils.js +0 -36
- package/dist/node/node.utils.js.map +0 -1
- package/dist/parcel/parcel-manager.js +0 -156
- package/dist/parcel/parcel-manager.js.map +0 -1
- package/dist/parcel/parcel.interface.js +0 -11
- package/dist/parcel/parcel.interface.js.map +0 -1
- package/dist/question-list/question-list.api.d.ts +0 -13
- package/dist/question-list/question-list.api.d.ts.map +0 -1
- package/dist/question-list/question-list.api.js +0 -35
- package/dist/question-list/question-list.api.js.map +0 -1
- package/dist/question-list/question-list.interface.d.ts +0 -18
- package/dist/question-list/question-list.interface.d.ts.map +0 -1
- package/dist/question-list/question-list.interface.js +0 -5
- package/dist/question-list/question-list.interface.js.map +0 -1
- package/dist/repo/repo-context.utils.js +0 -81
- package/dist/repo/repo-context.utils.js.map +0 -1
- package/dist/repo/repo-manager.js +0 -156
- package/dist/repo/repo-manager.js.map +0 -1
- package/dist/repo/repo.api.js +0 -40
- package/dist/repo/repo.api.js.map +0 -1
- package/dist/repo/repo.interface.js +0 -8
- package/dist/repo/repo.interface.js.map +0 -1
- package/dist/repo/repo.script-loader.js +0 -108
- package/dist/repo/repo.script-loader.js.map +0 -1
- package/dist/review/review.api.d.ts +0 -14
- package/dist/review/review.api.d.ts.map +0 -1
- package/dist/review/review.api.js +0 -133
- package/dist/review/review.api.js.map +0 -1
- package/dist/review/review.interface.d.ts +0 -24
- package/dist/review/review.interface.d.ts.map +0 -1
- package/dist/review/review.interface.js +0 -10
- package/dist/review/review.interface.js.map +0 -1
- package/dist/review-v2/apis/post-review-setting.api.d.ts +0 -12
- package/dist/review-v2/apis/post-review-setting.api.d.ts.map +0 -1
- package/dist/review-v2/apis/post-review-setting.api.js +0 -27
- package/dist/review-v2/apis/post-review-setting.api.js.map +0 -1
- package/dist/review-v2/apis/post-review.api.d.ts +0 -13
- package/dist/review-v2/apis/post-review.api.d.ts.map +0 -1
- package/dist/review-v2/apis/post-review.api.js +0 -46
- package/dist/review-v2/apis/post-review.api.js.map +0 -1
- package/dist/review-v2/review-setting.interface.d.ts +0 -23
- package/dist/review-v2/review-setting.interface.d.ts.map +0 -1
- package/dist/review-v2/review-setting.interface.js +0 -5
- package/dist/review-v2/review-setting.interface.js.map +0 -1
- package/dist/review-v2/review.interface.d.ts +0 -20
- package/dist/review-v2/review.interface.d.ts.map +0 -1
- package/dist/review-v2/review.interface.js +0 -5
- package/dist/review-v2/review.interface.js.map +0 -1
- package/dist/service/api.interface.d.ts +0 -35
- package/dist/service/api.interface.d.ts.map +0 -1
- package/dist/service/api.interface.js +0 -12
- package/dist/service/api.interface.js.map +0 -1
- package/dist/service/base.interface.js +0 -7
- package/dist/service/base.interface.js.map +0 -1
- package/dist/service/service.interface.js +0 -11
- package/dist/service/service.interface.js.map +0 -1
- package/dist/shared/log/create-api-logger.d.ts +0 -17
- package/dist/shared/log/create-api-logger.d.ts.map +0 -1
- package/dist/shared/log/create-api-logger.js +0 -15
- package/dist/shared/log/create-api-logger.js.map +0 -1
- package/dist/shared/log/log-manager.js +0 -218
- package/dist/shared/log/log-manager.js.map +0 -1
- package/dist/shared/utils/config-path.utils.js +0 -85
- package/dist/shared/utils/config-path.utils.js.map +0 -1
- package/dist/shared/utils/error.utils.js +0 -15
- package/dist/shared/utils/error.utils.js.map +0 -1
- package/dist/shared/utils/id.utils.js +0 -5
- package/dist/shared/utils/id.utils.js.map +0 -1
- package/dist/supabase.js +0 -100
- package/dist/supabase.js.map +0 -1
- package/dist/task/local-task-registry.js +0 -153
- package/dist/task/local-task-registry.js.map +0 -1
- package/dist/task/task-manager.js +0 -217
- package/dist/task/task-manager.js.map +0 -1
- package/dist/task/task-repo-context.js +0 -12
- package/dist/task/task-repo-context.js.map +0 -1
- package/dist/task/task.api.js +0 -351
- package/dist/task/task.api.js.map +0 -1
- package/dist/task/task.interface.js +0 -36
- package/dist/task/task.interface.js.map +0 -1
- package/dist/task/task.utils.js +0 -2
- package/dist/task/task.utils.js.map +0 -1
- package/dist/word/word.api.js +0 -30
- package/dist/word/word.api.js.map +0 -1
- package/dist/word/word.interface.js +0 -6
- package/dist/word/word.interface.js.map +0 -1
- package/src/auth/auth.api.ts +0 -87
- package/src/feed/feed.interface.ts +0 -33
- package/src/file/file-manager.ts +0 -145
- package/src/file/file.api.ts +0 -43
- package/src/file/file.interface.ts +0 -30
- package/src/file-list/file-list.api.ts +0 -64
- package/src/file-list/file-list.interface.ts +0 -24
- package/src/node/node-manager.ts +0 -673
- package/src/node/node-task.preset.ts +0 -13
- package/src/question-list/question-list.api.ts +0 -42
- package/src/question-list/question-list.interface.ts +0 -21
- package/src/review/review.api.ts +0 -145
- package/src/review/review.interface.ts +0 -26
- package/src/review-v2/apis/post-review-setting.api.ts +0 -35
- package/src/review-v2/apis/post-review.api.ts +0 -59
- package/src/review-v2/review-setting.interface.ts +0 -26
- package/src/review-v2/review.interface.ts +0 -23
- package/src/service/api.interface.ts +0 -47
- package/src/shared/log/create-api-logger.ts +0 -25
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { getPollCommandList } from "../command/command.api";
|
|
2
|
+
import { CommandType } from "../command/command.interface";
|
|
3
|
+
import { MAX_POLL_TARGET_LIST_SIZE } from "../core.api";
|
|
4
|
+
import {
|
|
5
|
+
createLogger,
|
|
6
|
+
createScope,
|
|
7
|
+
type LoggerWithScope,
|
|
8
|
+
LogLevel,
|
|
9
|
+
type LogScope,
|
|
10
|
+
logManager,
|
|
11
|
+
patchScope,
|
|
12
|
+
} from "../shared/log";
|
|
13
|
+
import { getErrorMessage } from "../shared/utils/error.utils";
|
|
14
|
+
import { patchChangeNodeStatus, patchNodeHeartBeat, patchStopNode, postRegisterNode } from "./node.api";
|
|
15
|
+
import { NodeStatus } from "./node.interface";
|
|
16
|
+
import { formatHeartbeat, getRandomInterval } from "./node.utils";
|
|
17
|
+
|
|
18
|
+
/** 主循环单轮运行时上下文 — 由 start() 创建并向下传递 */
|
|
19
|
+
export interface NodeLoopContext {
|
|
20
|
+
loopTraceId: string;
|
|
21
|
+
nodeId: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const LOG_TOPIC_NODE = "node";
|
|
25
|
+
const LOG_TOPIC_COMMAND = "command";
|
|
26
|
+
const LOG_TOPIC_PROCESS = "process";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Shared node process runtime: bootstrap, main-loop frame, heartbeat, commands, shutdown.
|
|
30
|
+
* Subclasses implement {@link onBeforeRegisterNode} and {@link runLoopSteps}.
|
|
31
|
+
*/
|
|
32
|
+
abstract class BaseNodeRuntime {
|
|
33
|
+
protected static readonly HEARTBEAT_FAILURE_THRESHOLD = 3;
|
|
34
|
+
/** Log `nodeId` label while startup has not yet received an assigned id from Supabase. */
|
|
35
|
+
private static readonly NODE_ID_PENDING_ASSIGNMENT = "pending-node-id";
|
|
36
|
+
|
|
37
|
+
protected readonly runtimeModule: string;
|
|
38
|
+
|
|
39
|
+
private _localNodeId: string | null = null;
|
|
40
|
+
private _isNodeIdLocked = false;
|
|
41
|
+
|
|
42
|
+
private isRunning: boolean;
|
|
43
|
+
private loopCount: number;
|
|
44
|
+
private consecutiveHeartbeatFailures = 0;
|
|
45
|
+
private readonly startupTraceId: string;
|
|
46
|
+
private readonly startupScope: LogScope;
|
|
47
|
+
private shutdownPromise: Promise<void> | null = null;
|
|
48
|
+
private startPromise: Promise<void> | null = null;
|
|
49
|
+
|
|
50
|
+
get localNodeId(): string | null {
|
|
51
|
+
return this._localNodeId;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
protected set localNodeId(value: string) {
|
|
55
|
+
if (this._isNodeIdLocked) {
|
|
56
|
+
throw new Error("Node ID cannot be modified after initial assignment");
|
|
57
|
+
}
|
|
58
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
59
|
+
throw new Error("Invalid node ID");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this._localNodeId = value;
|
|
63
|
+
this._isNodeIdLocked = true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
protected constructor(runtimeModule: string) {
|
|
67
|
+
this.runtimeModule = runtimeModule;
|
|
68
|
+
this.isRunning = false;
|
|
69
|
+
this.loopCount = 0;
|
|
70
|
+
this.startupTraceId = logManager.generateTraceId();
|
|
71
|
+
this.startupScope = createScope({ module: runtimeModule, traceId: this.startupTraceId });
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Hook: task registration, trigger config load, etc. Throw to abort bootstrap. */
|
|
75
|
+
protected abstract onBeforeRegisterNode(logger: LoggerWithScope): Promise<void>;
|
|
76
|
+
|
|
77
|
+
/** Hook: one iteration body after commands + heartbeat gate. */
|
|
78
|
+
protected abstract runLoopSteps(ctx: NodeLoopContext, heartbeatOk: boolean): Promise<void>;
|
|
79
|
+
|
|
80
|
+
/** Hook: minimum log level for main-loop scoped loggers (heartbeat, batchCommand, iteration). */
|
|
81
|
+
protected loopLoggerMinLevel(): LogLevel {
|
|
82
|
+
return LogLevel.INFO;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Hook: ms to wait between loop iterations. Default: random 15–60s. */
|
|
86
|
+
protected getLoopIntervalMs(): number {
|
|
87
|
+
return getRandomInterval();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private getLogNodeId(): string {
|
|
91
|
+
return this.localNodeId ?? BaseNodeRuntime.NODE_ID_PENDING_ASSIGNMENT;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
protected isShuttingDown(): boolean {
|
|
95
|
+
return this.shutdownPromise != null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected requestShutdown(trigger: string): void {
|
|
99
|
+
void this.shutdown({ trigger });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private registerProcessLifecycle(logger: LoggerWithScope): void {
|
|
103
|
+
process.on("SIGTERM", () => {
|
|
104
|
+
logger.warn("收到 SIGTERM 信號,準備關閉節點", { topic: LOG_TOPIC_PROCESS });
|
|
105
|
+
this.requestShutdown("SIGTERM");
|
|
106
|
+
});
|
|
107
|
+
process.on("SIGINT", () => {
|
|
108
|
+
logger.warn("收到 SIGINT 信號,準備關閉節點", { topic: LOG_TOPIC_PROCESS });
|
|
109
|
+
this.requestShutdown("SIGINT");
|
|
110
|
+
});
|
|
111
|
+
process.on("uncaughtException", (error) => {
|
|
112
|
+
if (this.shutdownPromise != null) {
|
|
113
|
+
logger.critical("shutdown 進行中發生未捕獲異常,立即關閉節點", {
|
|
114
|
+
topic: LOG_TOPIC_PROCESS,
|
|
115
|
+
data: {
|
|
116
|
+
name: error.name,
|
|
117
|
+
message: error.message,
|
|
118
|
+
stack: error.stack,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
process.exit(1);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
logger.critical("未捕獲的異常,準備關閉節點", {
|
|
125
|
+
topic: LOG_TOPIC_PROCESS,
|
|
126
|
+
data: {
|
|
127
|
+
name: error.name,
|
|
128
|
+
message: error.message,
|
|
129
|
+
stack: error.stack,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
this.requestShutdown("uncaughtException");
|
|
133
|
+
});
|
|
134
|
+
process.on("unhandledRejection", (reason) => {
|
|
135
|
+
if (this.shutdownPromise != null) {
|
|
136
|
+
logger.error("shutdown 進行中發生未處理的 Promise 拒絕", {
|
|
137
|
+
topic: LOG_TOPIC_PROCESS,
|
|
138
|
+
data: {
|
|
139
|
+
reason: getErrorMessage(reason),
|
|
140
|
+
stack: reason instanceof Error ? reason.stack : undefined,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
logger.error("未處理的 Promise 拒絕,準備關閉節點", {
|
|
146
|
+
topic: LOG_TOPIC_PROCESS,
|
|
147
|
+
data: {
|
|
148
|
+
reason: getErrorMessage(reason),
|
|
149
|
+
stack: reason instanceof Error ? reason.stack : undefined,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
this.requestShutdown("unhandledRejection");
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async start(): Promise<void> {
|
|
157
|
+
if (this.startPromise != null) {
|
|
158
|
+
return this.startPromise;
|
|
159
|
+
}
|
|
160
|
+
this.startPromise = this.runStart();
|
|
161
|
+
return this.startPromise;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private async runStart(): Promise<void> {
|
|
165
|
+
const logger = createLogger({
|
|
166
|
+
scope: patchScope({ scope: this.startupScope, patch: { labels: { nodeId: this.getLogNodeId() } } }),
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
logger.debug("節點進程啟動中", {
|
|
170
|
+
topic: LOG_TOPIC_NODE,
|
|
171
|
+
data: {
|
|
172
|
+
pid: process.pid,
|
|
173
|
+
env: process.env.NODE_ENV ?? "development",
|
|
174
|
+
runtime: this.runtimeModule,
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
this.registerProcessLifecycle(logger);
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
await this.onBeforeRegisterNode(logger);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
logger.error("節點啟動前置步驟失敗", {
|
|
183
|
+
topic: LOG_TOPIC_NODE,
|
|
184
|
+
data: { error: getErrorMessage(error) },
|
|
185
|
+
});
|
|
186
|
+
this.requestShutdown("bootstrap:pre-register");
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
logger.debug("開始向 Supabase 註冊節點", { topic: LOG_TOPIC_NODE });
|
|
191
|
+
try {
|
|
192
|
+
const { data, error } = await postRegisterNode({ traceId: this.startupTraceId });
|
|
193
|
+
if (data == null || error) {
|
|
194
|
+
throw error ?? new Error("postRegisterNode 失敗");
|
|
195
|
+
}
|
|
196
|
+
this.localNodeId = data.id;
|
|
197
|
+
logger.resetScope({ labels: { nodeId: data.id } });
|
|
198
|
+
logger.success("節點註冊成功", {
|
|
199
|
+
topic: LOG_TOPIC_NODE,
|
|
200
|
+
data: {
|
|
201
|
+
nodeId: data.id,
|
|
202
|
+
details: data.details,
|
|
203
|
+
},
|
|
204
|
+
});
|
|
205
|
+
} catch (error) {
|
|
206
|
+
logger.error("節點註冊失敗", {
|
|
207
|
+
topic: LOG_TOPIC_NODE,
|
|
208
|
+
data: { error: getErrorMessage(error) },
|
|
209
|
+
});
|
|
210
|
+
this.requestShutdown("bootstrap:register-node");
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const nodeId = this.localNodeId!;
|
|
215
|
+
logger.debug("節點準備進入主循環", { topic: LOG_TOPIC_NODE });
|
|
216
|
+
const { error: enterBusyError } = await patchChangeNodeStatus({
|
|
217
|
+
nodeId,
|
|
218
|
+
status: NodeStatus.BUSY,
|
|
219
|
+
fromStatus: NodeStatus.READY,
|
|
220
|
+
traceId: this.startupTraceId,
|
|
221
|
+
});
|
|
222
|
+
if (enterBusyError) {
|
|
223
|
+
logger.error("節點進入主循環失敗,無法更新節點狀態為 BUSY", {
|
|
224
|
+
topic: LOG_TOPIC_NODE,
|
|
225
|
+
data: { error: enterBusyError.message },
|
|
226
|
+
});
|
|
227
|
+
this.requestShutdown("bootstrap:enter-busy");
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
logger.debug("節點狀態已設為 BUSY 進入主循環", { topic: LOG_TOPIC_NODE, data: { nodeId } });
|
|
231
|
+
await this.runLoop(nodeId);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private async runLoop(nodeId: string): Promise<void> {
|
|
235
|
+
this.isRunning = true;
|
|
236
|
+
|
|
237
|
+
while (this.isRunning) {
|
|
238
|
+
this.loopCount++;
|
|
239
|
+
const loopTraceId = logManager.generateTraceId();
|
|
240
|
+
const loopScope = createScope({
|
|
241
|
+
module: `${this.runtimeModule}-loop-iteration`,
|
|
242
|
+
traceId: loopTraceId,
|
|
243
|
+
labels: { nodeId },
|
|
244
|
+
});
|
|
245
|
+
const loopCtx: NodeLoopContext = { loopTraceId, nodeId };
|
|
246
|
+
const iterLogger = createLogger({
|
|
247
|
+
scope: loopScope,
|
|
248
|
+
minLevel: this.loopLoggerMinLevel(),
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
iterLogger.debug(`主循環第 ${this.loopCount} 輪開始`, {
|
|
252
|
+
topic: LOG_TOPIC_NODE,
|
|
253
|
+
data: { nodeId, loopCount: this.loopCount },
|
|
254
|
+
});
|
|
255
|
+
try {
|
|
256
|
+
await this.batchCommand(loopCtx);
|
|
257
|
+
if (this.isShuttingDown()) {
|
|
258
|
+
iterLogger.debug("節點關閉中,跳過本輪剩餘步驟", { topic: LOG_TOPIC_NODE });
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
const heartbeatOk = await this.heartbeat(loopCtx);
|
|
262
|
+
if (this.isShuttingDown()) {
|
|
263
|
+
iterLogger.debug("節點關閉中,跳過本輪剩餘步驟", { topic: LOG_TOPIC_NODE });
|
|
264
|
+
break;
|
|
265
|
+
}
|
|
266
|
+
await this.runLoopSteps(loopCtx, heartbeatOk);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
iterLogger.critical(`主循環第 ${this.loopCount} 輪遇到未知錯誤`, {
|
|
269
|
+
topic: LOG_TOPIC_NODE,
|
|
270
|
+
data: { error: getErrorMessage(error) },
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
if (this.isShuttingDown()) {
|
|
274
|
+
iterLogger.debug("節點關閉中,跳過等待間隔", { topic: LOG_TOPIC_NODE });
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
const interval = this.getLoopIntervalMs();
|
|
278
|
+
iterLogger.debug(`主循環第 ${this.loopCount} 輪完成,等待下一輪`, {
|
|
279
|
+
topic: LOG_TOPIC_NODE,
|
|
280
|
+
data: { intervalMs: interval },
|
|
281
|
+
});
|
|
282
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
async shutdown(options?: { trigger?: string }): Promise<void> {
|
|
287
|
+
if (this.shutdownPromise != null) {
|
|
288
|
+
const logger = createLogger({
|
|
289
|
+
scope: patchScope({ scope: this.startupScope, patch: { labels: { nodeId: this.getLogNodeId() } } }),
|
|
290
|
+
});
|
|
291
|
+
logger.debug("shutdown 已在進行,跳過重複調用", {
|
|
292
|
+
topic: LOG_TOPIC_NODE,
|
|
293
|
+
data: { trigger: options?.trigger ?? "unknown" },
|
|
294
|
+
});
|
|
295
|
+
return this.shutdownPromise;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
this.isRunning = false;
|
|
299
|
+
this.shutdownPromise = this.runShutdown(options?.trigger).catch((error) => {
|
|
300
|
+
const logger = createLogger({
|
|
301
|
+
scope: patchScope({ scope: this.startupScope, patch: { labels: { nodeId: this.getLogNodeId() } } }),
|
|
302
|
+
});
|
|
303
|
+
logger.error("shutdown 流程異常", {
|
|
304
|
+
topic: LOG_TOPIC_NODE,
|
|
305
|
+
data: {
|
|
306
|
+
trigger: options?.trigger ?? "explicit",
|
|
307
|
+
error: getErrorMessage(error),
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
process.exit(1);
|
|
311
|
+
});
|
|
312
|
+
return this.shutdownPromise;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
private async runShutdown(trigger?: string): Promise<void> {
|
|
316
|
+
const logger = createLogger({
|
|
317
|
+
scope: patchScope({ scope: this.startupScope, patch: { labels: { nodeId: this.getLogNodeId() } } }),
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
logger.debug("正在關閉節點進程", {
|
|
321
|
+
topic: LOG_TOPIC_NODE,
|
|
322
|
+
data: { trigger: trigger ?? "explicit" },
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
if (this.localNodeId == null) {
|
|
326
|
+
logger.warn("本地節點未註冊,進程退出", { topic: LOG_TOPIC_NODE });
|
|
327
|
+
process.exit(0);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
logger.debug("正在登出節點", { topic: LOG_TOPIC_NODE, data: { nodeId: this.localNodeId } });
|
|
332
|
+
try {
|
|
333
|
+
const { error } = await patchStopNode({
|
|
334
|
+
nodeId: this.localNodeId,
|
|
335
|
+
traceId: this.startupTraceId,
|
|
336
|
+
});
|
|
337
|
+
if (error) {
|
|
338
|
+
throw new Error(`patchStopNode 失敗: ${error.message}`);
|
|
339
|
+
}
|
|
340
|
+
logger.success("節點正常關閉,進程退出", { topic: LOG_TOPIC_NODE });
|
|
341
|
+
} catch (error) {
|
|
342
|
+
logger.critical("登出節點失敗,進程退出", {
|
|
343
|
+
topic: LOG_TOPIC_NODE,
|
|
344
|
+
data: { error: getErrorMessage(error) },
|
|
345
|
+
});
|
|
346
|
+
} finally {
|
|
347
|
+
process.exit(0);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async heartbeat(ctx: NodeLoopContext): Promise<boolean> {
|
|
352
|
+
const { loopTraceId, nodeId } = ctx;
|
|
353
|
+
const logger = createLogger({
|
|
354
|
+
scope: createScope({
|
|
355
|
+
module: "heartbeat",
|
|
356
|
+
traceId: loopTraceId,
|
|
357
|
+
labels: { nodeId },
|
|
358
|
+
}),
|
|
359
|
+
minLevel: this.loopLoggerMinLevel(),
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
logger.debug("開始發送心跳", { topic: LOG_TOPIC_NODE });
|
|
363
|
+
let error: { message: string } | undefined;
|
|
364
|
+
let lastHeartBeat: number | null | undefined;
|
|
365
|
+
try {
|
|
366
|
+
const response = await patchNodeHeartBeat({ nodeId, traceId: loopTraceId });
|
|
367
|
+
error = response.error;
|
|
368
|
+
lastHeartBeat = response.data;
|
|
369
|
+
} catch (caught) {
|
|
370
|
+
error = { message: getErrorMessage(caught) };
|
|
371
|
+
lastHeartBeat = null;
|
|
372
|
+
}
|
|
373
|
+
if (error || lastHeartBeat == null) {
|
|
374
|
+
this.consecutiveHeartbeatFailures++;
|
|
375
|
+
const failureCount = this.consecutiveHeartbeatFailures;
|
|
376
|
+
const logData = {
|
|
377
|
+
error: getErrorMessage(error),
|
|
378
|
+
consecutiveFailures: failureCount,
|
|
379
|
+
threshold: BaseNodeRuntime.HEARTBEAT_FAILURE_THRESHOLD,
|
|
380
|
+
};
|
|
381
|
+
if (failureCount >= BaseNodeRuntime.HEARTBEAT_FAILURE_THRESHOLD) {
|
|
382
|
+
logger.critical("連續心跳失敗達上限,準備關閉節點", {
|
|
383
|
+
topic: LOG_TOPIC_NODE,
|
|
384
|
+
data: logData,
|
|
385
|
+
});
|
|
386
|
+
this.requestShutdown("heartbeat:consecutive-failures");
|
|
387
|
+
} else {
|
|
388
|
+
logger.warn("心跳更新失敗", { topic: LOG_TOPIC_NODE, data: logData });
|
|
389
|
+
}
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
this.consecutiveHeartbeatFailures = 0;
|
|
394
|
+
logger.success("心跳更新成功", {
|
|
395
|
+
topic: LOG_TOPIC_NODE,
|
|
396
|
+
data: { lastHeartBeat: formatHeartbeat(lastHeartBeat) },
|
|
397
|
+
});
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
async batchCommand(ctx: NodeLoopContext): Promise<void> {
|
|
402
|
+
const { loopTraceId, nodeId } = ctx;
|
|
403
|
+
const cmdLogger = createLogger({
|
|
404
|
+
scope: createScope({
|
|
405
|
+
module: "batchCommand",
|
|
406
|
+
traceId: loopTraceId,
|
|
407
|
+
labels: { nodeId },
|
|
408
|
+
}),
|
|
409
|
+
minLevel: this.loopLoggerMinLevel(),
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
cmdLogger.debug("開始檢查控制指令", { topic: LOG_TOPIC_COMMAND });
|
|
413
|
+
const { data: commandList = [], error: pollError } = await getPollCommandList({
|
|
414
|
+
nodeId,
|
|
415
|
+
traceId: loopTraceId,
|
|
416
|
+
size: MAX_POLL_TARGET_LIST_SIZE,
|
|
417
|
+
});
|
|
418
|
+
if (pollError) {
|
|
419
|
+
cmdLogger.warn("獲取指令失敗", {
|
|
420
|
+
topic: LOG_TOPIC_COMMAND,
|
|
421
|
+
data: { error: pollError.message },
|
|
422
|
+
});
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (commandList.length === 0) {
|
|
426
|
+
cmdLogger.debug("獲取指令數量為0 無需執行", { topic: LOG_TOPIC_COMMAND });
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
cmdLogger.debug(`獲取到控制指令數量為${commandList.length}`, {
|
|
430
|
+
topic: LOG_TOPIC_COMMAND,
|
|
431
|
+
data: { count: commandList.length, commandList: commandList.map((command) => command.name) },
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
for (const command of commandList) {
|
|
435
|
+
const cmd = command.name;
|
|
436
|
+
cmdLogger.info("執行控制指令", {
|
|
437
|
+
topic: LOG_TOPIC_COMMAND,
|
|
438
|
+
data: { commandId: command.id, cmd },
|
|
439
|
+
});
|
|
440
|
+
try {
|
|
441
|
+
await this.executeCommand(cmd, ctx);
|
|
442
|
+
cmdLogger.success("控制指令執行成功", {
|
|
443
|
+
topic: LOG_TOPIC_COMMAND,
|
|
444
|
+
data: { commandId: command.id, cmd },
|
|
445
|
+
});
|
|
446
|
+
} catch (error) {
|
|
447
|
+
cmdLogger.warn("控制指令執行失敗", {
|
|
448
|
+
topic: LOG_TOPIC_COMMAND,
|
|
449
|
+
data: {
|
|
450
|
+
commandId: command.id,
|
|
451
|
+
cmd,
|
|
452
|
+
error: getErrorMessage(error),
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
cmdLogger.debug("控制指令批次處理完成", {
|
|
459
|
+
topic: LOG_TOPIC_COMMAND,
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/** Shared commands, then {@link resolveNodeCommand} for subclass-specific handling. */
|
|
464
|
+
protected async executeCommand(cmd: CommandType, ctx: NodeLoopContext): Promise<void> {
|
|
465
|
+
if (cmd === CommandType.STOP_NODE) {
|
|
466
|
+
this.requestShutdown("cmd:STOP_NODE");
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
await this.resolveNodeCommand(cmd, ctx);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Hook: handle node-type-specific {@link CommandType} values.
|
|
474
|
+
* Default rejects anything not handled in {@link executeCommand}.
|
|
475
|
+
*/
|
|
476
|
+
protected async resolveNodeCommand(cmd: CommandType, _ctx: NodeLoopContext): Promise<void> {
|
|
477
|
+
throw new Error(`無法解析的 cmd: ${cmd}`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export { BaseNodeRuntime };
|
package/src/node/node.api.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { createTarget, QueryFilter, updateTargetDetails, validateWithSchema } from "../core.api";
|
|
2
|
-
import { generateResponse } from "../core.interface";
|
|
3
|
-
import { createApiLogger } from "../shared/log/log-manager";
|
|
4
1
|
import { z } from "zod";
|
|
5
|
-
import {
|
|
2
|
+
import { createTarget, type QueryFilter, updateTargetDetails, validateWithSchema } from "../core.api";
|
|
3
|
+
import { generateResponse } from "../core.interface";
|
|
4
|
+
import { createLogger } from "../shared/log";
|
|
5
|
+
import { CategoryNode, type Node, type NodeDetails, NodeStatus } from "./node.interface";
|
|
6
6
|
|
|
7
7
|
const NODE_STATUS_FIELD = "details->>status" as const;
|
|
8
|
+
const LOG_TOPIC_NODE = "node";
|
|
8
9
|
|
|
9
10
|
const nodeIdSchema = z.string().trim().min(1);
|
|
10
11
|
const traceIdSchema = z.string().trim().min(1).optional();
|
|
@@ -51,7 +52,7 @@ function lockOnNodeStatus(status: NodeStatus): QueryFilter[] {
|
|
|
51
52
|
|
|
52
53
|
export const postRegisterNode = validateWithSchema(
|
|
53
54
|
postRegisterNodeSchema,
|
|
54
|
-
"postRegisterNodeSchema"
|
|
55
|
+
"postRegisterNodeSchema",
|
|
55
56
|
)(async (payload) => {
|
|
56
57
|
return createTarget<Node, PostRegisterNodePayload>({
|
|
57
58
|
payload,
|
|
@@ -76,7 +77,7 @@ export const postRegisterNode = validateWithSchema(
|
|
|
76
77
|
|
|
77
78
|
export const patchNodeHeartBeat = validateWithSchema(
|
|
78
79
|
patchNodeHeartBeatSchema,
|
|
79
|
-
"patchNodeHeartBeatSchema"
|
|
80
|
+
"patchNodeHeartBeatSchema",
|
|
80
81
|
)(async ({ nodeId }) => {
|
|
81
82
|
const lastHeartBeat = Date.now();
|
|
82
83
|
await updateTargetDetails<Node, NodeDetails>({
|
|
@@ -93,7 +94,7 @@ export const patchNodeHeartBeat = validateWithSchema(
|
|
|
93
94
|
|
|
94
95
|
export const patchStopNode = validateWithSchema(
|
|
95
96
|
patchStopNodeSchema,
|
|
96
|
-
"patchStopNodeSchema"
|
|
97
|
+
"patchStopNodeSchema",
|
|
97
98
|
)(async ({ nodeId }) => {
|
|
98
99
|
const lastHeartBeat = Date.now();
|
|
99
100
|
// TODO 等待任務全部完成才下綫 應該先使用NodeStatus.DRAINING
|
|
@@ -112,9 +113,9 @@ export const patchStopNode = validateWithSchema(
|
|
|
112
113
|
|
|
113
114
|
export const patchChangeNodeStatus = validateWithSchema(
|
|
114
115
|
patchChangeNodeStatusSchema,
|
|
115
|
-
"patchChangeNodeStatusSchema"
|
|
116
|
+
"patchChangeNodeStatusSchema",
|
|
116
117
|
)(async ({ nodeId, status, fromStatus, traceId }) => {
|
|
117
|
-
const logger =
|
|
118
|
+
const logger = createLogger({ module: "patchChangeNodeStatus", traceId, labels: { nodeId } });
|
|
118
119
|
|
|
119
120
|
const data = await updateTargetDetails<Node, NodeDetails>({
|
|
120
121
|
id: nodeId,
|
|
@@ -127,8 +128,8 @@ export const patchChangeNodeStatus = validateWithSchema(
|
|
|
127
128
|
});
|
|
128
129
|
|
|
129
130
|
logger.info("节点状态更新成功", {
|
|
130
|
-
topic:
|
|
131
|
-
|
|
131
|
+
topic: LOG_TOPIC_NODE,
|
|
132
|
+
data: {
|
|
132
133
|
nodeId,
|
|
133
134
|
status,
|
|
134
135
|
fromStatus,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Target } from "../core.interface";
|
|
1
|
+
import type { Target } from "../core.interface";
|
|
2
2
|
|
|
3
3
|
export enum NodeStatus {
|
|
4
4
|
/** Registered, not yet in worker loop. */
|
|
@@ -30,11 +30,4 @@ export interface NodeDetails {
|
|
|
30
30
|
manifestVersion: number;
|
|
31
31
|
status: NodeStatus;
|
|
32
32
|
lastHeartBeat: number;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
/** 主循环单轮运行时上下文 — 由 start() 创建并向下传递 */
|
|
36
|
-
export interface NodeLoopContext {
|
|
37
|
-
loopTraceId: string;
|
|
38
|
-
nodeId: string;
|
|
39
33
|
}
|
|
40
|
-
|
package/src/node/node.utils.ts
CHANGED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import { validateLogPersistPreloadEnv } from "../../shared/log/enable-log-persist";
|
|
3
|
+
import { logPersistEnabledFromEnv } from "../../shared/log/log-persist.config";
|
|
4
|
+
import { loadEnvFiles } from "../env/load-env";
|
|
5
|
+
import { resolveProjectRootByPackageName } from "../env/project-root";
|
|
6
|
+
import type { ServicePreloadOptions } from "./service-preload.interface";
|
|
7
|
+
|
|
8
|
+
function applyServiceEnvDefaults(projectRoot: string, options: ServicePreloadOptions): void {
|
|
9
|
+
if (!logPersistEnabledFromEnv()) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const service = process.env.LOG_PERSIST_SERVICE?.trim();
|
|
14
|
+
if (service == null || service === "") {
|
|
15
|
+
process.env.LOG_PERSIST_SERVICE = options.serviceValue;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const runtimeDir = process.env.RUNTIME_DATA_DIR?.trim();
|
|
19
|
+
if (runtimeDir == null || runtimeDir === "") {
|
|
20
|
+
const relative = options.runtimeDataDirRelative ?? "data/runtime";
|
|
21
|
+
process.env.RUNTIME_DATA_DIR = resolve(projectRoot, relative);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Unified Node `--import` preload runner (sync only).
|
|
27
|
+
*
|
|
28
|
+
* Phase 1 — Resolve project root from service package name
|
|
29
|
+
* Phase 2 — Load `.env.local` / `.env`
|
|
30
|
+
* Phase 3 — Apply SDK service env defaults + optional L3 hook
|
|
31
|
+
* Phase 4 — Validate log-persist env when enabled
|
|
32
|
+
* Phase 5 — Process diagnostics (TODO)
|
|
33
|
+
*
|
|
34
|
+
* Supabase init and log-persist enable stay in app `main()` (async).
|
|
35
|
+
*/
|
|
36
|
+
export function runServicePreload(options: ServicePreloadOptions): void {
|
|
37
|
+
const projectRoot = resolveProjectRootByPackageName(options.callerImportMetaUrl, options.packageName);
|
|
38
|
+
|
|
39
|
+
loadEnvFiles(projectRoot, { afterLoad: options.afterLoadEnv });
|
|
40
|
+
|
|
41
|
+
applyServiceEnvDefaults(projectRoot, options);
|
|
42
|
+
options.applyEnvDefaults?.(projectRoot);
|
|
43
|
+
|
|
44
|
+
validateLogPersistPreloadEnv();
|
|
45
|
+
|
|
46
|
+
// TODO: Phase 5 — optional unhandledRejection / uncaughtException formatters
|
|
47
|
+
// (formerly watch-service preload-diagnostics.mjs)
|
|
48
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ServicePreloadOptions {
|
|
2
|
+
/** `import.meta.url` from the service `scripts/preload.mjs`. */
|
|
3
|
+
callerImportMetaUrl: string;
|
|
4
|
+
/** package.json `name` — for resolveProjectRootByPackageName. */
|
|
5
|
+
packageName: string;
|
|
6
|
+
/** LOG_PERSIST_SERVICE default when persistence enabled. */
|
|
7
|
+
serviceValue: string;
|
|
8
|
+
/** Relative to project root; default `data/runtime`. */
|
|
9
|
+
runtimeDataDirRelative?: string;
|
|
10
|
+
/** Passed to loadEnvFiles `afterLoad`. */
|
|
11
|
+
afterLoadEnv?: () => void;
|
|
12
|
+
/** L3 hook after SDK defaults (legacy aliases, etc.). */
|
|
13
|
+
applyEnvDefaults?: (projectRoot: string) => void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type {
|
|
2
|
+
ManagedChildProcessesOptions,
|
|
3
|
+
SpawnChildResult,
|
|
4
|
+
StopAllChildrenOptions,
|
|
5
|
+
} from "./managed-child-processes";
|
|
6
|
+
export { ManagedChildProcesses } from "./managed-child-processes";
|
|
7
|
+
export type { BuildNodeImportArgsInput, SpawnTsxChildOptions } from "./process-spawn";
|
|
8
|
+
export { buildNodeImportArgs, isChildProcessRunning, spawnTsxChild } from "./process-spawn";
|