target-supabase-sdk 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/README.md +66 -0
  2. package/dist/browser.d.ts +52 -0
  3. package/dist/browser.d.ts.map +1 -0
  4. package/dist/browser.js +45 -0
  5. package/dist/browser.js.map +1 -0
  6. package/dist/command/command.api.js +5 -5
  7. package/dist/command/command.api.js.map +1 -1
  8. package/dist/index.d.ts +2 -48
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -41
  11. package/dist/index.js.map +1 -1
  12. package/dist/link/link.interface.d.ts +1 -1
  13. package/dist/link/link.interface.d.ts.map +1 -1
  14. package/dist/node/node-log-scope.d.ts +11 -0
  15. package/dist/node/node-log-scope.d.ts.map +1 -0
  16. package/dist/node/node-log-scope.js +7 -0
  17. package/dist/node/node-log-scope.js.map +1 -0
  18. package/dist/node/node-runtime.base.d.ts +42 -0
  19. package/dist/node/node-runtime.base.d.ts.map +1 -0
  20. package/dist/node/node-runtime.base.js +397 -0
  21. package/dist/node/node-runtime.base.js.map +1 -0
  22. package/dist/node/node.api.d.ts +3 -3
  23. package/dist/node/node.api.js +3 -3
  24. package/dist/node/node.api.js.map +1 -1
  25. package/dist/node/task-node.d.ts +20 -0
  26. package/dist/node/task-node.d.ts.map +1 -0
  27. package/dist/node/task-node.js +245 -0
  28. package/dist/node/task-node.js.map +1 -0
  29. package/dist/node/trigger-node.d.ts +18 -0
  30. package/dist/node/trigger-node.d.ts.map +1 -0
  31. package/dist/node/trigger-node.js +150 -0
  32. package/dist/node/trigger-node.js.map +1 -0
  33. package/dist/node.d.ts +22 -0
  34. package/dist/node.d.ts.map +1 -0
  35. package/dist/node.js +19 -0
  36. package/dist/node.js.map +1 -0
  37. package/dist/repo/repo-manager.d.ts +14 -3
  38. package/dist/repo/repo-manager.d.ts.map +1 -1
  39. package/dist/repo/repo-manager.js +27 -17
  40. package/dist/repo/repo-manager.js.map +1 -1
  41. package/dist/repo/repo.script-loader.d.ts +3 -3
  42. package/dist/repo/repo.script-loader.d.ts.map +1 -1
  43. package/dist/repo/repo.script-loader.js +10 -10
  44. package/dist/repo/repo.script-loader.js.map +1 -1
  45. package/dist/shared/log/create-api-logger.d.ts +10 -6
  46. package/dist/shared/log/create-api-logger.d.ts.map +1 -1
  47. package/dist/shared/log/create-api-logger.js +10 -6
  48. package/dist/shared/log/create-api-logger.js.map +1 -1
  49. package/dist/shared/log/index.d.ts +10 -0
  50. package/dist/shared/log/index.d.ts.map +1 -0
  51. package/dist/shared/log/index.js +10 -0
  52. package/dist/shared/log/index.js.map +1 -0
  53. package/dist/shared/log/log-manager.d.ts +25 -46
  54. package/dist/shared/log/log-manager.d.ts.map +1 -1
  55. package/dist/shared/log/log-manager.js +59 -40
  56. package/dist/shared/log/log-manager.js.map +1 -1
  57. package/dist/shared/log/log-scope.d.ts +49 -0
  58. package/dist/shared/log/log-scope.d.ts.map +1 -0
  59. package/dist/shared/log/log-scope.js +70 -0
  60. package/dist/shared/log/log-scope.js.map +1 -0
  61. package/dist/task/index.d.ts +15 -0
  62. package/dist/task/index.d.ts.map +1 -0
  63. package/dist/task/index.js +14 -0
  64. package/dist/task/index.js.map +1 -0
  65. package/dist/task/local-task-registry.d.ts +10 -0
  66. package/dist/task/local-task-registry.d.ts.map +1 -1
  67. package/dist/task/local-task-registry.js +83 -22
  68. package/dist/task/local-task-registry.js.map +1 -1
  69. package/dist/task/task-manager.d.ts +18 -6
  70. package/dist/task/task-manager.d.ts.map +1 -1
  71. package/dist/task/task-manager.js +46 -67
  72. package/dist/task/task-manager.js.map +1 -1
  73. package/dist/task/task-post.api.d.ts +49 -0
  74. package/dist/task/task-post.api.d.ts.map +1 -0
  75. package/dist/task/task-post.api.js +91 -0
  76. package/dist/task/task-post.api.js.map +1 -0
  77. package/dist/task/task-repo-context.d.ts +2 -0
  78. package/dist/task/task-repo-context.d.ts.map +1 -1
  79. package/dist/task/task-repo-context.js.map +1 -1
  80. package/dist/task/task-repo-validation.d.ts +46 -0
  81. package/dist/task/task-repo-validation.d.ts.map +1 -0
  82. package/dist/task/task-repo-validation.js +96 -0
  83. package/dist/task/task-repo-validation.js.map +1 -0
  84. package/dist/task/task.api.d.ts +11 -53
  85. package/dist/task/task.api.d.ts.map +1 -1
  86. package/dist/task/task.api.js +13 -61
  87. package/dist/task/task.api.js.map +1 -1
  88. package/dist/task/task.interface.d.ts +2 -0
  89. package/dist/task/task.interface.d.ts.map +1 -1
  90. package/dist/task/task.interface.js.map +1 -1
  91. package/dist/trigger/trigger.api.d.ts +140 -0
  92. package/dist/trigger/trigger.api.d.ts.map +1 -0
  93. package/dist/trigger/trigger.api.js +125 -0
  94. package/dist/trigger/trigger.api.js.map +1 -0
  95. package/dist/trigger/trigger.interface.d.ts +43 -0
  96. package/dist/trigger/trigger.interface.d.ts.map +1 -0
  97. package/dist/trigger/trigger.interface.js +11 -0
  98. package/dist/trigger/trigger.interface.js.map +1 -0
  99. package/dist/trigger/trigger.utils.d.ts +6 -0
  100. package/dist/trigger/trigger.utils.d.ts.map +1 -0
  101. package/dist/trigger/trigger.utils.js +39 -0
  102. package/dist/trigger/trigger.utils.js.map +1 -0
  103. package/package.json +21 -6
  104. package/src/browser.ts +100 -0
  105. package/src/command/command.api.ts +5 -5
  106. package/src/index.ts +2 -79
  107. package/src/link/link.interface.ts +1 -1
  108. package/src/node/node-log-scope.ts +15 -0
  109. package/src/node/node-runtime.base.ts +450 -0
  110. package/src/node/node.api.ts +3 -3
  111. package/src/node/task-node.ts +284 -0
  112. package/src/node/trigger-node.ts +180 -0
  113. package/src/node.ts +62 -0
  114. package/src/repo/repo-manager.ts +49 -21
  115. package/src/repo/repo.script-loader.ts +13 -13
  116. package/src/shared/log/create-api-logger.ts +23 -12
  117. package/src/shared/log/index.ts +23 -0
  118. package/src/shared/log/log-manager.ts +85 -90
  119. package/src/shared/log/log-scope.ts +123 -0
  120. package/src/task/index.ts +48 -0
  121. package/src/task/local-task-registry.ts +110 -23
  122. package/src/task/task-manager.ts +73 -84
  123. package/src/task/task-post.api.ts +116 -0
  124. package/src/task/task-repo-context.ts +2 -0
  125. package/src/task/task-repo-validation.ts +171 -0
  126. package/src/task/task.api.ts +13 -73
  127. package/src/task/task.interface.ts +2 -0
  128. package/src/trigger/trigger.api.ts +166 -0
  129. package/src/trigger/trigger.interface.ts +50 -0
  130. package/src/trigger/trigger.utils.ts +56 -0
  131. package/dist/node/node-manager.d.ts +0 -48
  132. package/dist/node/node-manager.d.ts.map +0 -1
  133. package/dist/node/node-manager.js +0 -619
  134. package/dist/node/node-manager.js.map +0 -1
  135. package/src/node/node-manager.ts +0 -673
@@ -3,7 +3,7 @@ import { mkdir, writeFile } from "node:fs/promises";
3
3
  import { join, resolve } from "node:path";
4
4
  import { tmpdir } from "node:os";
5
5
 
6
- import { LoggerWithContext } from "../shared/log/log-manager";
6
+ import { LoggerWithScope } from "../shared/log";
7
7
  import { resolvePathFromCwd, toFileImportHref } from "../shared/utils/config-path.utils";
8
8
  import { TaskRepoScriptRecord } from "../task/task-repo-context";
9
9
  import {
@@ -41,7 +41,7 @@ export async function loadRepoContextFromScript({
41
41
  script,
42
42
  taskTypeKey,
43
43
  }: {
44
- logger: LoggerWithContext;
44
+ logger: LoggerWithScope;
45
45
  script: TaskRepoScriptRecord;
46
46
  taskTypeKey: string;
47
47
  }): Promise<LoadedRepoContext | null> {
@@ -49,7 +49,7 @@ export async function loadRepoContextFromScript({
49
49
  const cacheKey = `${taskTypeKey}@${loadKey}`;
50
50
  const cached = importedModuleCache.get(cacheKey);
51
51
  if (cached != null) {
52
- logger.info("命中 Repo 脚本模块缓存", { topic: "repo", context: { cacheKey } });
52
+ logger.info("命中 Repo 脚本模块缓存", { topic: "repo", data: { cacheKey } });
53
53
  return cached;
54
54
  }
55
55
 
@@ -58,16 +58,16 @@ export async function loadRepoContextFromScript({
58
58
  try {
59
59
  let moduleExports: unknown;
60
60
  if (source != null && source.trim() !== "") {
61
- logger.info("从 source 动态加载 Repo 脚本", { topic: "repo", context: { scriptId: script.id } });
61
+ logger.info("从 source 动态加载 Repo 脚本", { topic: "repo", data: { scriptId: script.id } });
62
62
  moduleExports = await importFromSource(source, cacheKey);
63
63
  } else if (modulePath != null && modulePath.trim() !== "") {
64
64
  logger.info("从 modulePath 动态加载 Repo 脚本", {
65
65
  topic: "repo",
66
- context: { scriptId: script.id, modulePath },
66
+ data: { scriptId: script.id, modulePath },
67
67
  });
68
68
  moduleExports = await importFromFilePath(modulePath);
69
69
  } else {
70
- logger.warn("脚本缺少 source 或 modulePath", { topic: "repo", context: { scriptId: script.id } });
70
+ logger.warn("脚本缺少 source 或 modulePath", { topic: "repo", data: { scriptId: script.id } });
71
71
  return null;
72
72
  }
73
73
 
@@ -75,7 +75,7 @@ export async function loadRepoContextFromScript({
75
75
  if (context == null) {
76
76
  logger.warn("脚本模块未导出合法的 TaskRepoContext", {
77
77
  topic: "repo",
78
- context: { scriptId: script.id, exportName: exportName ?? "default" },
78
+ data: { scriptId: script.id, exportName: exportName ?? "default" },
79
79
  });
80
80
  return null;
81
81
  }
@@ -86,7 +86,7 @@ export async function loadRepoContextFromScript({
86
86
  } catch (error) {
87
87
  logger.error("动态加载 Repo 脚本失败", {
88
88
  topic: "repo",
89
- context: { scriptId: script.id, error: error instanceof Error ? error.message : error },
89
+ data: { scriptId: script.id, error: error instanceof Error ? error.message : error },
90
90
  });
91
91
  return null;
92
92
  }
@@ -98,7 +98,7 @@ export async function loadRepoContextFromUrl({
98
98
  taskTypeKey,
99
99
  exportName,
100
100
  }: {
101
- logger: LoggerWithContext;
101
+ logger: LoggerWithScope;
102
102
  url: string;
103
103
  taskTypeKey: string;
104
104
  exportName?: string;
@@ -107,18 +107,18 @@ export async function loadRepoContextFromUrl({
107
107
  const cacheKey = `${taskTypeKey}@url:${href}`;
108
108
  const cached = importedModuleCache.get(cacheKey);
109
109
  if (cached != null) {
110
- logger.info("命中 Repo URL 模块缓存", { topic: "repo", context: { cacheKey } });
110
+ logger.info("命中 Repo URL 模块缓存", { topic: "repo", data: { cacheKey } });
111
111
  return cached;
112
112
  }
113
113
 
114
114
  try {
115
- logger.info("从 Repo URL 动态加载脚本", { topic: "repo", context: { url, href } });
115
+ logger.info("从 Repo URL 动态加载脚本", { topic: "repo", data: { url, href } });
116
116
  const moduleExports = await import(href);
117
117
  const context = normalizeRepoContextModule(moduleExports, taskTypeKey, exportName);
118
118
  if (context == null) {
119
119
  logger.warn("Repo URL 模块未导出合法的 TaskRepoContext", {
120
120
  topic: "repo",
121
- context: { url, exportName: exportName ?? "default" },
121
+ data: { url, exportName: exportName ?? "default" },
122
122
  });
123
123
  return null;
124
124
  }
@@ -128,7 +128,7 @@ export async function loadRepoContextFromUrl({
128
128
  } catch (error) {
129
129
  logger.error("从 Repo URL 动态加载失败", {
130
130
  topic: "repo",
131
- context: { url, error: error instanceof Error ? error.message : error },
131
+ data: { url, error: error instanceof Error ? error.message : error },
132
132
  });
133
133
  return null;
134
134
  }
@@ -1,25 +1,36 @@
1
- import { logManager, type LogContext, type LoggerWithContext } from "./log-manager";
1
+ import { logManager, type LoggerWithScope } from "./log-manager";
2
+ import { normalizeScope, type LogScope, type LogScopePatch } from "./log-scope";
2
3
 
3
4
  /**
4
5
  * Options for {@link createApiLogger}.
5
6
  *
6
- * - **Core:** optional `traceId` (generated when omitted)
7
- * - **Business:** any other {@link LogContext} field (e.g. `nodeId`)
7
+ * - **Trace:** optional `traceId` / `traceParentId` (generated root when traceId omitted)
8
+ * - **Labels:** optional `labels` (e.g. `{ nodeId }`)
8
9
  */
9
10
  export type CreateApiLoggerOptions = {
10
11
  traceId?: string;
11
- } & Partial<Omit<LogContext, "module" | "traceId">>;
12
+ traceParentId?: string | null;
13
+ labels?: Record<string, string>;
14
+ } & Partial<Omit<LogScope, "module" | "traceId" | "traceParentId" | "labels">>;
12
15
 
13
16
  /**
14
17
  * Logger for one SDK API invocation.
15
18
  *
16
- * Binds required `module` + optional caller `traceId`; business fields (e.g. `nodeId`) are optional.
19
+ * Binds `module` + normalized {@link LogScope}.
17
20
  */
18
- export function createApiLogger(module: string, options?: CreateApiLoggerOptions): LoggerWithContext {
19
- const { traceId, ...businessFields } = options ?? {};
20
- return logManager.withContext({
21
- module,
22
- traceId: traceId ?? logManager.generateTraceId(),
23
- ...businessFields,
24
- }).logger;
21
+ export function createApiLogger(module: string, options?: CreateApiLoggerOptions): LoggerWithScope {
22
+ const { traceId, traceParentId, labels, ...rest } = options ?? {};
23
+ const scope = normalizeScope(
24
+ {
25
+ module,
26
+ traceId,
27
+ traceParentId: traceParentId ?? null,
28
+ labels,
29
+ ...rest,
30
+ },
31
+ { generateTraceId: true }
32
+ );
33
+ return logManager.withScope(scope).logger;
25
34
  }
35
+
36
+ export type { LogScopePatch };
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Log domain public API — curated re-exports only.
3
+ */
4
+
5
+ // log-manager
6
+ export { logManager, LogManager, LogLevel } from "./log-manager";
7
+ export type { LogEntry, LogOptions, LoggerWithScope, LogRestParams } from "./log-manager";
8
+
9
+ // create-api-logger
10
+ export { createApiLogger } from "./create-api-logger";
11
+ export type { CreateApiLoggerOptions } from "./create-api-logger";
12
+
13
+ // log-scope
14
+ export {
15
+ applyScopePatch,
16
+ createChildScope,
17
+ createRootScope,
18
+ formatScopeLabels,
19
+ normalizeScope,
20
+ resolveLogData,
21
+ withModule,
22
+ } from "./log-scope";
23
+ export type { LogScope, LogScopeInput, LogScopePatch, CreateRootScopeInput, CreateChildScopeInput } from "./log-scope";
@@ -1,5 +1,12 @@
1
1
  import { isDevEnvironment } from "../../core.utils";
2
2
  import { generateUniqueId } from "../utils/id.utils";
3
+ import {
4
+ applyScopePatch,
5
+ formatScopeLabels,
6
+ resolveLogData,
7
+ type LogScope,
8
+ type LogScopePatch,
9
+ } from "./log-scope";
3
10
 
4
11
  /**
5
12
  * Log severity and semantics (low → high). `minLevel` filters by {@link LOG_LEVEL_RANK}.
@@ -31,44 +38,32 @@ const LOG_LEVEL_RANK: Record<LogLevel, number> = {
31
38
  [LogLevel.CRITICAL]: 5,
32
39
  };
33
40
 
34
- interface LogEntry {
41
+ interface LogEntry extends LogScope {
35
42
  timestamp: number;
36
43
  level: LogLevel;
37
- /** Tell people what happened, but more structured */
38
44
  message: string;
39
- /** Category of a kind of log */
40
45
  topic: string | null;
41
- /** Where the log comes from */
42
- module: string;
43
- /** Specific process — correlates one logical chain (loop, request). */
44
- traceId: string;
45
- /** Worker node id when the log is node-scoped; omit for scheduler / admin / API-only paths. */
46
- nodeId?: string;
47
46
  extra?: string;
48
- context?: unknown;
47
+ /** Per-line structured business payload. */
48
+ data?: unknown;
49
49
  }
50
50
 
51
- interface LogContext {
52
- module: LogEntry["module"];
53
- traceId: LogEntry["traceId"];
54
- nodeId?: LogEntry["nodeId"];
55
- }
51
+ type LogRestParams = {
52
+ topic?: LogEntry["topic"];
53
+ extra?: LogEntry["extra"];
54
+ data?: unknown;
55
+ };
56
56
 
57
- type LogRestParams = Omit<LogParams, "message">;
57
+ type LogParams = { message: LogEntry["message"] } & LogRestParams;
58
58
 
59
- interface LogEntryPayload {
59
+ interface LogEntryPayload extends LogScope {
60
60
  message: LogEntry["message"];
61
61
  topic?: LogEntry["topic"];
62
62
  extra?: LogEntry["extra"];
63
- context?: LogEntry["context"];
63
+ data?: LogEntry["data"];
64
64
  level: LogEntry["level"];
65
- module: LogEntry["module"];
66
- traceId: LogEntry["traceId"];
67
- nodeId?: LogEntry["nodeId"];
68
65
  }
69
66
 
70
- type LogParams = Pick<LogEntryPayload, "message" | "topic" | "extra" | "context">;
71
-
72
67
  interface LogOptions {
73
68
  defaultTopic: LogEntry["topic"];
74
69
  formatTimestamp: boolean;
@@ -89,28 +84,24 @@ const DEFAULT_OPTIONS: LogOptions = {
89
84
  minLevel: isDevEnvironment() ? LogLevel.DEBUG : LogLevel.INFO,
90
85
  };
91
86
 
92
- interface LoggerWithContext {
93
- /** Rank 0 — diagnostic detail; dev/troubleshooting only. */
87
+ interface LoggerWithScope {
94
88
  debug: (message: LogParams["message"], restParams?: LogRestParams) => void;
95
- /** Rank 1 — normal operational flow. */
96
89
  info: (message: LogParams["message"], restParams?: LogRestParams) => void;
97
- /** Rank 2 — positive milestone (semantic INFO, not higher severity). */
98
90
  success: (message: LogParams["message"], restParams?: LogRestParams) => void;
99
- /** Rank 3 — recoverable anomaly; system continues. */
100
91
  warn: (message: LogParams["message"], restParams?: LogRestParams) => void;
101
- /** Rank 4 — a concrete operation failed; needs investigation. */
102
92
  error: (message: LogParams["message"], restParams?: LogRestParams) => void;
103
- /** Rank 5 — invariant / design / integrity breach; escalate immediately. */
104
93
  critical: (message: LogParams["message"], restParams?: LogRestParams) => void;
105
- /** Merge partial fields into this logger's bound context (e.g. nodeId after register). */
106
- resetContext: (fields: Partial<LogContext>) => void;
94
+ /** Merge partial fields into this logger's bound scope. */
95
+ resetScope: (fields: LogScopePatch) => void;
96
+ /** @deprecated use {@link LoggerWithScope.resetScope} */
97
+ resetContext: (fields: LogScopePatch) => void;
107
98
  }
108
99
 
109
100
  function mergeLogOptions(options?: Partial<LogOptions>): LogOptions {
110
101
  return { ...DEFAULT_OPTIONS, ...options };
111
102
  }
112
103
 
113
- function formatContextValue(value: unknown): string {
104
+ function formatDataValue(value: unknown): string {
114
105
  if (value === undefined) {
115
106
  return "";
116
107
  }
@@ -124,16 +115,19 @@ function formatContextValue(value: unknown): string {
124
115
  }
125
116
  }
126
117
 
127
- function validateLogContext(logContext: LogContext): void {
118
+ function validateLogScope(logScope: LogScope): void {
128
119
  const missing: string[] = [];
129
- if (!logContext.module?.trim()) {
120
+ if (!logScope.module?.trim()) {
130
121
  missing.push("module");
131
122
  }
132
- if (!logContext.traceId?.trim()) {
123
+ if (!logScope.traceId?.trim()) {
133
124
  missing.push("traceId");
134
125
  }
126
+ if (logScope.traceParentId !== null && typeof logScope.traceParentId !== "string") {
127
+ missing.push("traceParentId");
128
+ }
135
129
  if (missing.length > 0) {
136
- console.warn(`[LogManager] LogContext missing or empty: ${missing.join(", ")}`, logContext);
130
+ console.warn(`[LogManager] LogScope missing or invalid: ${missing.join(", ")}`, logScope);
137
131
  }
138
132
  }
139
133
 
@@ -183,16 +177,8 @@ class LogManager {
183
177
  return LOG_LEVEL_RANK[level] >= LOG_LEVEL_RANK[this.getMinLevel()];
184
178
  }
185
179
 
186
- private createLogEntry({
187
- level,
188
- message,
189
- topic,
190
- module,
191
- traceId,
192
- nodeId,
193
- extra,
194
- context,
195
- }: LogEntryPayload): LogEntry {
180
+ private createLogEntry(payload: LogEntryPayload): LogEntry {
181
+ const { level, message, topic, extra, data, module, traceId, traceParentId, labels } = payload;
196
182
  return {
197
183
  timestamp: Date.now(),
198
184
  level,
@@ -200,9 +186,10 @@ class LogManager {
200
186
  topic: topic === undefined ? this.options.defaultTopic : topic,
201
187
  module,
202
188
  traceId,
203
- nodeId,
189
+ traceParentId,
190
+ labels,
204
191
  extra,
205
- context,
192
+ data,
206
193
  };
207
194
  }
208
195
 
@@ -223,7 +210,7 @@ class LogManager {
223
210
 
224
211
  parts.push(this.formatLevelTag(entry));
225
212
  parts.push(
226
- `traceId=${entry.traceId} nodeId=${entry.nodeId ?? "--"} module=${entry.module} topic=${entry.topic ?? "--"}`
213
+ `traceId=${entry.traceId} parent=${entry.traceParentId ?? "null"} labels=${formatScopeLabels(entry.labels)} module=${entry.module} topic=${entry.topic ?? "--"}`
227
214
  );
228
215
 
229
216
  if (this.options.formatPrefix) {
@@ -238,9 +225,9 @@ class LogManager {
238
225
  parts.push(`| extra=${entry.extra}`);
239
226
  }
240
227
 
241
- const contextText = formatContextValue(entry.context);
242
- if (contextText) {
243
- parts.push(`| context=${contextText}`);
228
+ const dataText = formatDataValue(entry.data);
229
+ if (dataText) {
230
+ parts.push(`| data=${dataText}`);
244
231
  }
245
232
 
246
233
  return parts.join(" ");
@@ -260,21 +247,23 @@ class LogManager {
260
247
  }
261
248
  }
262
249
 
263
- private log(
264
- level: LogLevel,
265
- message: LogParams["message"],
266
- logContext: LogContext,
267
- restParams?: LogRestParams
268
- ) {
250
+ private log(level: LogLevel, message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
269
251
  if (!this.shouldLog(level)) {
270
252
  return;
271
253
  }
272
254
 
273
- validateLogContext(logContext);
255
+ validateLogScope(logScope);
274
256
 
275
- const { topic, extra, context } = restParams ?? {};
276
- const { module, traceId, nodeId } = logContext;
277
- const entry = this.createLogEntry({ level, message, topic, extra, context, module, traceId, nodeId });
257
+ const { topic, extra } = restParams ?? {};
258
+ const data = resolveLogData(restParams);
259
+ const entry = this.createLogEntry({
260
+ level,
261
+ message,
262
+ topic,
263
+ extra,
264
+ data,
265
+ ...logScope,
266
+ });
278
267
 
279
268
  this.history.push(entry);
280
269
  if (this.history.length > this.options.maxHistoryLength) {
@@ -290,51 +279,57 @@ class LogManager {
290
279
  return generateUniqueId();
291
280
  }
292
281
 
293
- public debug(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
294
- this.log(LogLevel.DEBUG, message, logContext, restParams);
282
+ public debug(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
283
+ this.log(LogLevel.DEBUG, message, logScope, restParams);
295
284
  }
296
285
 
297
- public info(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
298
- this.log(LogLevel.INFO, message, logContext, restParams);
286
+ public info(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
287
+ this.log(LogLevel.INFO, message, logScope, restParams);
299
288
  }
300
289
 
301
- public success(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
302
- this.log(LogLevel.SUCCESS, message, logContext, restParams);
290
+ public success(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
291
+ this.log(LogLevel.SUCCESS, message, logScope, restParams);
303
292
  }
304
293
 
305
- public warn(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
306
- this.log(LogLevel.WARN, message, logContext, restParams);
294
+ public warn(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
295
+ this.log(LogLevel.WARN, message, logScope, restParams);
307
296
  }
308
297
 
309
- public error(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
310
- this.log(LogLevel.ERROR, message, logContext, restParams);
298
+ public error(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
299
+ this.log(LogLevel.ERROR, message, logScope, restParams);
311
300
  }
312
301
 
313
- public critical(message: LogParams["message"], logContext: LogContext, restParams?: LogRestParams) {
314
- this.log(LogLevel.CRITICAL, message, logContext, restParams);
302
+ public critical(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
303
+ this.log(LogLevel.CRITICAL, message, logScope, restParams);
315
304
  }
316
305
 
317
- public withContext(context: LogContext): { logger: LoggerWithContext; context: LogContext } {
318
- const boundContext: LogContext = { ...context };
319
-
320
- const logger: LoggerWithContext = {
321
- debug: (message, restParams) => this.debug(message, boundContext, restParams),
322
- info: (message, restParams) => this.info(message, boundContext, restParams),
323
- success: (message, restParams) => this.success(message, boundContext, restParams),
324
- warn: (message, restParams) => this.warn(message, boundContext, restParams),
325
- error: (message, restParams) => this.error(message, boundContext, restParams),
326
- critical: (message, restParams) => this.critical(message, boundContext, restParams),
306
+ public withScope(scope: LogScope): { logger: LoggerWithScope; scope: LogScope } {
307
+ const boundScope: LogScope = { ...scope, labels: scope.labels ? { ...scope.labels } : undefined };
308
+
309
+ const logger: LoggerWithScope = {
310
+ debug: (message, restParams) => this.debug(message, boundScope, restParams),
311
+ info: (message, restParams) => this.info(message, boundScope, restParams),
312
+ success: (message, restParams) => this.success(message, boundScope, restParams),
313
+ warn: (message, restParams) => this.warn(message, boundScope, restParams),
314
+ error: (message, restParams) => this.error(message, boundScope, restParams),
315
+ critical: (message, restParams) => this.critical(message, boundScope, restParams),
316
+ resetScope: (fields) => {
317
+ const next = applyScopePatch(boundScope, fields);
318
+ boundScope.module = next.module;
319
+ boundScope.traceId = next.traceId;
320
+ boundScope.traceParentId = next.traceParentId;
321
+ boundScope.labels = next.labels;
322
+ },
327
323
  resetContext: (fields) => {
328
- Object.assign(boundContext, fields);
324
+ logger.resetScope(fields);
329
325
  },
330
326
  };
331
327
 
332
- return { logger, context: boundContext };
328
+ return { logger, scope: boundScope };
333
329
  }
330
+
334
331
  }
335
332
 
336
333
  export const logManager = LogManager.getInstance();
337
334
  export { LogManager, LogLevel };
338
- export { createApiLogger } from "./create-api-logger";
339
- export type { CreateApiLoggerOptions } from "./create-api-logger";
340
- export type { LogOptions, LogEntry, LogContext, LoggerWithContext, LogRestParams };
335
+ export type { LogOptions, LogEntry, LoggerWithScope, LogRestParams };
@@ -0,0 +1,123 @@
1
+ import { generateUniqueId } from "../utils/id.utils";
2
+
3
+ /** Logger-bound scope: module + trace chain + optional labels. */
4
+ export interface LogScope {
5
+ module: string;
6
+ traceId: string;
7
+ traceParentId: string | null;
8
+ labels?: Readonly<Record<string, string>>;
9
+ }
10
+
11
+ /** Partial update for {@link LogScope} / {@link applyScopePatch}. */
12
+ export type LogScopePatch = Partial<Omit<LogScope, "labels">> & {
13
+ labels?: Record<string, string>;
14
+ };
15
+
16
+ export type LogScopeInput = LogScopePatch & Pick<LogScope, "module">;
17
+
18
+ interface NormalizeScopeOptions {
19
+ /** When true and traceId is missing, generate a new id. */
20
+ generateTraceId?: boolean;
21
+ }
22
+
23
+ function mergeLabels(
24
+ base?: Readonly<Record<string, string>>,
25
+ patch?: Record<string, string>
26
+ ): Record<string, string> | undefined {
27
+ const merged: Record<string, string> = { ...base, ...patch };
28
+ return Object.keys(merged).length > 0 ? merged : undefined;
29
+ }
30
+
31
+ /** Coerce partial input into a {@link LogScope}. */
32
+ export function normalizeScope(input: LogScopeInput, options?: NormalizeScopeOptions): LogScope {
33
+ const generateTraceId = options?.generateTraceId ?? false;
34
+ const traceId = input.traceId?.trim() || (generateTraceId ? generateUniqueId() : "");
35
+ if (!traceId) {
36
+ throw new Error("[LogScope] traceId is required (or enable generateTraceId)");
37
+ }
38
+
39
+ return {
40
+ module: input.module,
41
+ traceId,
42
+ traceParentId: input.traceParentId ?? null,
43
+ labels: mergeLabels(undefined, input.labels),
44
+ };
45
+ }
46
+
47
+ /** Input for {@link createRootScope}. */
48
+ export type CreateRootScopeInput = {
49
+ module: string;
50
+ traceId?: string;
51
+ labels?: Record<string, string>;
52
+ traceParentId?: string | null;
53
+ };
54
+
55
+ /** Root scope: traceParentId defaults to null. */
56
+ export function createRootScope(input: CreateRootScopeInput): LogScope {
57
+ return normalizeScope(
58
+ {
59
+ module: input.module,
60
+ traceId: input.traceId,
61
+ traceParentId: input.traceParentId ?? null,
62
+ labels: input.labels,
63
+ },
64
+ { generateTraceId: true }
65
+ );
66
+ }
67
+
68
+ /** Input for {@link createChildScope}. */
69
+ export type CreateChildScopeInput = {
70
+ module: string;
71
+ parent: LogScope;
72
+ traceId?: string;
73
+ traceParentId?: string | null;
74
+ labels?: Record<string, string>;
75
+ };
76
+
77
+ /** Child scope: parent link defaults to parent.traceId; labels merge with parent. */
78
+ export function createChildScope(input: CreateChildScopeInput): LogScope {
79
+ const { module, parent, traceId, traceParentId, labels } = input;
80
+ return normalizeScope(
81
+ {
82
+ module,
83
+ traceId,
84
+ traceParentId: traceParentId ?? parent.traceId,
85
+ labels: mergeLabels(parent.labels, labels),
86
+ },
87
+ { generateTraceId: true }
88
+ );
89
+ }
90
+
91
+ /** Same trace chain, different module (e.g. prepareTask vs executeTask). */
92
+ export function withModule(scope: LogScope, module: string): LogScope {
93
+ return { ...scope, module };
94
+ }
95
+
96
+ /** Merge patch into scope (labels deep-merge). */
97
+ export function applyScopePatch(scope: LogScope, patch: LogScopePatch): LogScope {
98
+ return normalizeScope({
99
+ module: patch.module ?? scope.module,
100
+ traceId: patch.traceId ?? scope.traceId,
101
+ traceParentId: patch.traceParentId !== undefined ? patch.traceParentId : scope.traceParentId,
102
+ labels: mergeLabels(scope.labels, patch.labels),
103
+ });
104
+ }
105
+ export function formatScopeLabels(labels?: Readonly<Record<string, string>>): string {
106
+ if (labels == null || Object.keys(labels).length === 0) {
107
+ return "--";
108
+ }
109
+ return Object.entries(labels)
110
+ .map(([key, value]) => `${key}:${value}`)
111
+ .join(",");
112
+ }
113
+
114
+ /** Prefer `data`; fall back to deprecated `context` on log rest params. */
115
+ export function resolveLogData(rest?: { data?: unknown; context?: unknown }): unknown | undefined {
116
+ if (rest?.data !== undefined) {
117
+ return rest.data;
118
+ }
119
+ if (rest?.context !== undefined) {
120
+ return rest.context;
121
+ }
122
+ return undefined;
123
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Task domain public API — curated re-exports only.
3
+ * Internal modules (local-task-registry, task-repo-context, task.utils) stay private.
4
+ */
5
+
6
+ // task.interface
7
+ export {
8
+ CategoryTask,
9
+ ResultCode,
10
+ TaskStatus,
11
+ TaskStatusAction,
12
+ } from "./task.interface";
13
+ export type { Task, TaskDetails, TaskFlow } from "./task.interface";
14
+
15
+ // task.api
16
+ export {
17
+ patchChangeTaskStatus,
18
+ patchChangeTaskStatusSchema,
19
+ patchClaimTask,
20
+ patchClaimTaskSchema,
21
+ patchTaskProgress,
22
+ patchTaskProgressSchema,
23
+ } from "./task.api";
24
+ export type {
25
+ PatchChangeTaskStatusPayload,
26
+ PatchClaimTaskPayload,
27
+ PatchTaskProgressPayload,
28
+ } from "./task.api";
29
+ export { postTask, postTaskSchema } from "./task-post.api";
30
+ export type { PostTaskPayload } from "./task-post.api";
31
+
32
+ // task-manager
33
+ export { TaskManager } from "./task-manager";
34
+ export type {
35
+ PrepareTaskFailureReason,
36
+ PrepareTaskParams,
37
+ PrepareTaskResponse,
38
+ RegisterTasksOptions,
39
+ RegisterTasksResult,
40
+ } from "./task-manager";
41
+
42
+ // task-repo-validation
43
+ export { TaskRepoValidation } from "./task-repo-validation";
44
+ export type {
45
+ TaskRepoValidationFailureReason,
46
+ ValidateTaskRepoAndParamsInput,
47
+ ValidateTaskRepoAndParamsResult,
48
+ } from "./task-repo-validation";