target-supabase-sdk 0.2.17 → 0.2.19

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 (57) hide show
  1. package/README.md +28 -0
  2. package/dist/browser.d.ts +2 -0
  3. package/dist/browser.d.ts.map +1 -1
  4. package/dist/browser.js +1 -1
  5. package/dist/chunks/{task-queue-DufG7PlX.js → task-queue-CUa40Vb5.js} +117 -2
  6. package/dist/chunks/task-queue-CUa40Vb5.js.map +1 -0
  7. package/dist/node/telegram/api-client.d.ts +12 -0
  8. package/dist/node/telegram/api-client.d.ts.map +1 -0
  9. package/dist/node/telegram/chunk-locator.d.ts +10 -0
  10. package/dist/node/telegram/chunk-locator.d.ts.map +1 -0
  11. package/dist/node/telegram/chunk.d.ts +4 -0
  12. package/dist/node/telegram/chunk.d.ts.map +1 -0
  13. package/dist/node/telegram/index.d.ts +8 -0
  14. package/dist/node/telegram/index.d.ts.map +1 -0
  15. package/dist/node/telegram/storage-provider.d.ts +32 -0
  16. package/dist/node/telegram/storage-provider.d.ts.map +1 -0
  17. package/dist/node/telegram/types.d.ts +53 -0
  18. package/dist/node/telegram/types.d.ts.map +1 -0
  19. package/dist/node.d.ts +4 -0
  20. package/dist/node.d.ts.map +1 -1
  21. package/dist/node.js +538 -7
  22. package/dist/node.js.map +1 -1
  23. package/dist/shared/feed/feed.build.d.ts +33 -0
  24. package/dist/shared/feed/feed.build.d.ts.map +1 -0
  25. package/dist/shared/feed/feed.interface.d.ts +35 -0
  26. package/dist/shared/feed/feed.interface.d.ts.map +1 -0
  27. package/dist/shared/feed/feed.name.d.ts +8 -0
  28. package/dist/shared/feed/feed.name.d.ts.map +1 -0
  29. package/dist/shared/feed/feed.query.d.ts +8 -0
  30. package/dist/shared/feed/feed.query.d.ts.map +1 -0
  31. package/dist/shared/feed/index.d.ts +13 -0
  32. package/dist/shared/feed/index.d.ts.map +1 -0
  33. package/dist/shared/feed/node/feed.access.d.ts +34 -0
  34. package/dist/shared/feed/node/feed.access.d.ts.map +1 -0
  35. package/dist/shared/feed/node/feed.service.d.ts +23 -0
  36. package/dist/shared/feed/node/feed.service.d.ts.map +1 -0
  37. package/dist/shared/feed/node/index.d.ts +11 -0
  38. package/dist/shared/feed/node/index.d.ts.map +1 -0
  39. package/package.json +8 -1
  40. package/src/browser.ts +8 -1
  41. package/src/node/telegram/api-client.ts +146 -0
  42. package/src/node/telegram/chunk-locator.ts +23 -0
  43. package/src/node/telegram/chunk.ts +33 -0
  44. package/src/node/telegram/index.ts +20 -0
  45. package/src/node/telegram/storage-provider.ts +182 -0
  46. package/src/node/telegram/types.ts +82 -0
  47. package/src/node.ts +37 -0
  48. package/src/shared/feed/README.md +163 -0
  49. package/src/shared/feed/feed.build.ts +101 -0
  50. package/src/shared/feed/feed.interface.ts +50 -0
  51. package/src/shared/feed/feed.name.ts +20 -0
  52. package/src/shared/feed/feed.query.ts +13 -0
  53. package/src/shared/feed/index.ts +13 -0
  54. package/src/shared/feed/node/feed.access.ts +134 -0
  55. package/src/shared/feed/node/feed.service.ts +183 -0
  56. package/src/shared/feed/node/index.ts +11 -0
  57. package/dist/chunks/task-queue-DufG7PlX.js.map +0 -1
package/dist/node.js CHANGED
@@ -1,14 +1,15 @@
1
1
  import { z } from 'zod';
2
- import { M as MAX_POLL_TARGET_LIST_SIZE, V as validateWithSchema, g as createLogger, z as pollTargetList, k as generateResponse, h as createTarget, K as supabase, w as logManager, X as createScope, d as LogLevel, Y as patchScope, J as scanTargetList, Z as withModule, l as getPossibleTarget, E as postTarget, q as isCreateTargetAlreadyExistsError, t as isOptimisticLockResponse, R as updateTargetDetails } from './chunks/list.api-BzbTJBsM.js';
3
- export { B as BaseValidator, C as CREATE_TARGET_ALREADY_EXISTS_MESSAGE, a as CategoryList, L as LOG_BATCH_LOADER_KEY, b as LOG_MIN_LEVEL_ENV_KEY, c as LOG_PERSIST_LOADER_KEY, e as MAX_TARGET_LIST_PAGE_SIZE, O as OPTIMISTIC_LOCK_ERROR_CODE, f as OPTIMISTIC_LOCK_FAILED_MESSAGE, P as PostListValidator, S as StatusCode, U as UPDATE_TARGET_NOT_FOUND_MESSAGE, i as deleteTarget, j as formatZodError, m as getTarget, n as getTargetList, o as getTargetTotalCount, p as handleSupabaseError, r as isDevEnvironment, s as isOptimisticLockError, u as logDev, v as logDevGroup, x as logMinLevelFromEnv, y as patchTarget, A as postListCreate, D as postLogListCreate, F as postTargetPayloadSchema, G as queryFilterSchema, H as resolveLogMinLevel, I as safeParseWithSchema, N as targetDraftSchema, Q as updateTarget, T as validateWith } from './chunks/list.api-BzbTJBsM.js';
2
+ import { M as MAX_POLL_TARGET_LIST_SIZE, V as validateWithSchema, g as createLogger, z as pollTargetList, k as generateResponse, h as createTarget, K as supabase, w as logManager, X as createScope, d as LogLevel, Y as patchScope, J as scanTargetList, Z as withModule, l as getPossibleTarget, m as getTarget, Q as updateTarget, E as postTarget, q as isCreateTargetAlreadyExistsError, t as isOptimisticLockResponse, R as updateTargetDetails } from './chunks/list.api-BzbTJBsM.js';
3
+ export { B as BaseValidator, C as CREATE_TARGET_ALREADY_EXISTS_MESSAGE, a as CategoryList, L as LOG_BATCH_LOADER_KEY, b as LOG_MIN_LEVEL_ENV_KEY, c as LOG_PERSIST_LOADER_KEY, e as MAX_TARGET_LIST_PAGE_SIZE, O as OPTIMISTIC_LOCK_ERROR_CODE, f as OPTIMISTIC_LOCK_FAILED_MESSAGE, P as PostListValidator, S as StatusCode, U as UPDATE_TARGET_NOT_FOUND_MESSAGE, i as deleteTarget, j as formatZodError, n as getTargetList, o as getTargetTotalCount, p as handleSupabaseError, r as isDevEnvironment, s as isOptimisticLockError, u as logDev, v as logDevGroup, x as logMinLevelFromEnv, y as patchTarget, A as postListCreate, D as postLogListCreate, F as postTargetPayloadSchema, G as queryFilterSchema, H as resolveLogMinLevel, I as safeParseWithSchema, N as targetDraftSchema, T as validateWith } from './chunks/list.api-BzbTJBsM.js';
4
4
  import { l as loadEnvFiles, b as readEnv, c as requireEnv, d as resolveLogSpoolSpawnEnvForLabel, e as resolveLogSpoolConfig, f as resolveLogSpoolRoot, g as resolveAllLogSpoolProcessRoles, h as logSpoolProcessDir, s as spoolLogger, i as parseLogSpoolBatchFilename, j as computeLogBatchIdempotencyKey, k as buildLogListDraft, n as postLogBatch, a as logSpoolEnabledFromEnv, o as logSpoolConfigFromEnv, L as LOG_SPOOL_SERVICE_ID_ENV, q as ensureLogSpoolFromEnv, t as shutdownLogSpoolFromEnv, u as getLogSpoolStats } from './chunks/enable-C7lFooTG.js';
5
5
  export { C as CLI_PROD_FLAG, S as SERVICE_ENV_PROFILE_ENV_KEY, w as SERVICE_ENV_PROFILE_PROD, x as buildLogSpoolSpawnEnv, y as envBool, z as envInt, A as envMs, B as envNumber, D as envPort, E as envProfileFromProcess, F as resolveDefaultEnvFiles, r as resolveProjectRootByPackageName, G as resolveProjectRootFromModule, v as validateLogSpoolPreloadEnv } from './chunks/enable-C7lFooTG.js';
6
6
  import { randomBytes, createHash } from 'node:crypto';
7
7
  import { readFile, unlink, mkdir, writeFile, rename, access, stat, readdir, constants } from 'node:fs/promises';
8
8
  import { dirname, resolve, join, isAbsolute } from 'node:path';
9
- import { bq as sha256Hex, bw as getErrorMessage, bx as LOG_TOPIC_NODE, aU as postRegisterNode, ay as patchChangeNodeStatus, N as NodeStatus, aJ as patchStopNode, aG as patchNodeHeartBeat, E as EMPTY_REGISTRY_SLOT_RUNTIME_STATE, bg as runRegistrySlotGuardCheck, b6 as registrySlotRuntimePatchFromGuardResult, c as CategoryNode, Z as evaluateBusyNodeLiveness, aI as patchServiceRuntime, an as isLogEntry, F as claimServiceRegistrySlot, m as ServiceRegistryError, e as CategoryRepo, ai as guessMediaMime, M as MEDIA_CONTENT_HASH_ALGORITHM, ao as isMediaValue, as as mediaLinkDedupFilters, y as buildMediaLinkDraft, R as ResultCode, by as LOG_TOPIC_TASK, o as TASK_REPO_USAGE, ac as getScanRemoteRepoValues, aC as patchClaimTask, bz as CRITICAL_UNKNOWN_TASK_TRACE_ID, aA as patchChangeTaskStatus, q as TaskStatusAction, bA as toError, b0 as postTaskSchema, bB as createTaskRow, p as TaskStatus } from './chunks/task-queue-DufG7PlX.js';
10
- export { A as ApiMethod, C as CategoryConfig, a as CategoryExtraction, b as CategoryLink, d as CategoryParcel, f as CategoryService, g as CategoryTask, D as DEFAULT_SYSTEM_REGISTRY_SEED_SLOTS, L as LINK_MANIFEST_VERSION, h as LIST_MANIFEST_VERSION, i as MEDIA_CONTENT_HASH_PREFIX_LENGTH, j as MEDIA_VALUES, P as POST_TASK_DEFAULT_MAX_ATTEMPTS, k as ParcelManager, l as PostLinkValidator, S as ServiceLifecycleStatus, n as ServiceSlotStatus, T as TARGET_SYSTEM_REGISTRY_KEY, r as apiDetailsSchema, s as appendSystemRegistryEmptySlots, t as assertRegistrySlotAvailable, u as assertRegistrySlotOwner, v as buildEmptyServiceSlots, w as buildLinkTargetDraft, x as buildListTargetDraft, z as buildMediaNameFromLocator, B as buildSystemRegistryConfigDetails, G as classifyNetworkError, H as countTasksByType, I as createActiveServiceLifecycle, J as createClaimedRegistrySlotRuntimeState, K as createStorageProviderRegistry, O as createUploadTracker, Q as decodeLogBatch, U as decodeLogBatchList, V as defaultL3ServiceDetails, W as deleteParcel, X as deleteParcelSchema, Y as escapeIlikePattern, _ as fetchBinaryWithRetry, $ as fetchWithRetry, a0 as fieldDefinitionSchema, a1 as flattenLogBatch, a2 as flattenLogBatches, a3 as formatNetworkError, a4 as getApi, a5 as getApiSchema, a6 as getConfig, a7 as getConfigSchema, a8 as getExtraction, a9 as getExtractionSchema, aa as getParcel, ab as getParcelSchema, ad as getScanRemoteRepoValuesSchema, ae as getService, af as getServiceSchema, ag as getTargetSystemRegistry, ah as getValueAtPath, aj as installChunkFetchRegistry, ak as isHttpUrl, al as isLocalFilesystemPath, am as isLogBatchList, ap as isOpaqueChunkUrl, aq as isRetryableHttpStatus, ar as linkTargetDraftBuildInputSchema, at as parcelDetailsSchema, au as parseLogBatchMeta, av as parseProviderPrefixedUrl, aw as parseServiceSlot, ax as parseServiceSlots, az as patchChangeNodeStatusSchema, aB as patchChangeTaskStatusSchema, aD as patchClaimTaskSchema, aE as patchExtractionObjects, aF as patchExtractionObjectsSchema, aH as patchNodeHeartBeatSchema, aK as patchStopNodeSchema, aL as patchTaskProgress, aM as patchTaskProgressSchema, aN as postApi, aO as postApiSchema, aP as postExtraction, aQ as postExtractionSchema, aR as postLinkCreate, aS as postParcel, aT as postParcelSchema, aV as postRegisterNodeSchema, aW as postService, aX as postServiceInstance, aY as postServiceSchema, aZ as postSystemRegistryConfig, a_ as postSystemRegistryConfigSchema, a$ as postTask, b1 as postTaskWithRetry, b2 as publishParcel, b3 as registerProviderChunkResolver, b4 as registerService, b5 as registerServiceAtStartup, b7 as releaseSystemRegistrySlots, b8 as releaseSystemRegistrySlotsByServiceId, b9 as requestHasBody, ba as resetSystemRegistryConfig, bb as resetSystemRegistryConfigSchema, bc as resolveActiveRegistryServiceId, bd as resolveFetchUrl, be as restoreParcel, bf as restoreParcelById, bh as sanitizeFileName, bi as sanitizeParcelFileName, bj as scanExtractionList, bk as scanExtractionListSchema, bl as schemaDefinitionSchema, bm as serviceDetailsSchema, bn as serviceLifecycleSchema, bo as serviceNodeSnapshotSchema, bp as serviceRuntimeSchema, br as summarizeTaskQueue, bs as systemRegistrySeedSlotSchema, bt as toPostgrestTextArrayLiteral, bu as unregisterService, bv as unregisterServiceAtShutdown } from './chunks/task-queue-DufG7PlX.js';
9
+ import { bv as sha256Hex, bB as getErrorMessage, bC as LOG_TOPIC_NODE, aZ as postRegisterNode, aD as patchChangeNodeStatus, N as NodeStatus, aO as patchStopNode, aL as patchNodeHeartBeat, E as EMPTY_REGISTRY_SLOT_RUNTIME_STATE, bl as runRegistrySlotGuardCheck, bb as registrySlotRuntimePatchFromGuardResult, c as CategoryNode, a0 as evaluateBusyNodeLiveness, aN as patchServiceRuntime, as as isLogEntry, I as claimServiceRegistrySlot, m as ServiceRegistryError, a3 as fetchWithRetry, av as isRetryableHttpStatus, a2 as fetchBinaryWithRetry, au as isOpaqueChunkUrl, e as CategoryRepo, ap as isHttpUrl, bD as isFeedIngestSource, bE as resolveFeedOriginalStorageProvider, b as CategoryLink, bF as buildFeedTagList, ao as isFeedValue, am as guessMediaMime, M as MEDIA_CONTENT_HASH_ALGORITHM, at as isMediaValue, ax as mediaLinkDedupFilters, B as buildMediaLinkDraft, R as ResultCode, bG as LOG_TOPIC_TASK, o as TASK_REPO_USAGE, ag as getScanRemoteRepoValues, aH as patchClaimTask, bH as CRITICAL_UNKNOWN_TASK_TRACE_ID, aF as patchChangeTaskStatus, q as TaskStatusAction, bI as toError, b5 as postTaskSchema, bJ as createTaskRow, p as TaskStatus } from './chunks/task-queue-CUa40Vb5.js';
10
+ export { A as ApiMethod, C as CategoryConfig, a as CategoryExtraction, d as CategoryParcel, f as CategoryService, g as CategoryTask, D as DEFAULT_SYSTEM_REGISTRY_SEED_SLOTS, bK as FEED_INGEST_SOURCES, F as FEED_VALUES, L as LINK_MANIFEST_VERSION, h as LIST_MANIFEST_VERSION, i as MEDIA_CONTENT_HASH_PREFIX_LENGTH, j as MEDIA_VALUES, P as POST_TASK_DEFAULT_MAX_ATTEMPTS, k as ParcelManager, l as PostLinkValidator, S as ServiceLifecycleStatus, n as ServiceSlotStatus, T as TARGET_SYSTEM_REGISTRY_KEY, r as apiDetailsSchema, s as appendSystemRegistryEmptySlots, t as assertRegistrySlotAvailable, u as assertRegistrySlotOwner, v as buildEmptyServiceSlots, w as buildFeedLinkDraft, x as buildFeedLinkName, y as buildLinkTargetDraft, z as buildListTargetDraft, G as buildMediaNameFromLocator, H as buildSystemRegistryConfigDetails, J as classifyNetworkError, K as countTasksByType, O as createActiveServiceLifecycle, Q as createClaimedRegistrySlotRuntimeState, U as createStorageProviderRegistry, V as createUploadTracker, W as decodeLogBatch, X as decodeLogBatchList, Y as defaultL3ServiceDetails, Z as deleteParcel, _ as deleteParcelSchema, $ as escapeIlikePattern, a1 as feedLinkDedupFilters, a4 as fieldDefinitionSchema, a5 as flattenLogBatch, a6 as flattenLogBatches, a7 as formatNetworkError, a8 as getApi, a9 as getApiSchema, aa as getConfig, ab as getConfigSchema, ac as getExtraction, ad as getExtractionSchema, ae as getParcel, af as getParcelSchema, ah as getScanRemoteRepoValuesSchema, ai as getService, aj as getServiceSchema, ak as getTargetSystemRegistry, al as getValueAtPath, an as installChunkFetchRegistry, aq as isLocalFilesystemPath, ar as isLogBatchList, aw as linkTargetDraftBuildInputSchema, ay as parcelDetailsSchema, az as parseLogBatchMeta, aA as parseProviderPrefixedUrl, aB as parseServiceSlot, aC as parseServiceSlots, aE as patchChangeNodeStatusSchema, aG as patchChangeTaskStatusSchema, aI as patchClaimTaskSchema, aJ as patchExtractionObjects, aK as patchExtractionObjectsSchema, aM as patchNodeHeartBeatSchema, aP as patchStopNodeSchema, aQ as patchTaskProgress, aR as patchTaskProgressSchema, aS as postApi, aT as postApiSchema, aU as postExtraction, aV as postExtractionSchema, aW as postLinkCreate, aX as postParcel, aY as postParcelSchema, a_ as postRegisterNodeSchema, a$ as postService, b0 as postServiceInstance, b1 as postServiceSchema, b2 as postSystemRegistryConfig, b3 as postSystemRegistryConfigSchema, b4 as postTask, b6 as postTaskWithRetry, b7 as publishParcel, b8 as registerProviderChunkResolver, b9 as registerService, ba as registerServiceAtStartup, bc as releaseSystemRegistrySlots, bd as releaseSystemRegistrySlotsByServiceId, be as requestHasBody, bf as resetSystemRegistryConfig, bg as resetSystemRegistryConfigSchema, bh as resolveActiveRegistryServiceId, bi as resolveFetchUrl, bj as restoreParcel, bk as restoreParcelById, bm as sanitizeFileName, bn as sanitizeParcelFileName, bo as scanExtractionList, bp as scanExtractionListSchema, bq as schemaDefinitionSchema, br as serviceDetailsSchema, bs as serviceLifecycleSchema, bt as serviceNodeSnapshotSchema, bu as serviceRuntimeSchema, bw as summarizeTaskQueue, bx as systemRegistrySeedSlotSchema, by as toPostgrestTextArrayLiteral, bz as unregisterService, bA as unregisterServiceAtShutdown } from './chunks/task-queue-CUa40Vb5.js';
11
11
  import { spawn } from 'node:child_process';
12
+ import { ProxyAgent } from 'undici';
12
13
  import { tmpdir } from 'node:os';
13
14
  import { pathToFileURL } from 'node:url';
14
15
  import { createReadStream } from 'node:fs';
@@ -923,7 +924,7 @@ function createManagedChildProcesses(options) {
923
924
  });
924
925
  }
925
926
 
926
- function sleep(ms) {
927
+ function sleep$1(ms) {
927
928
  return new Promise((resolve) => setTimeout(resolve, ms));
928
929
  }
929
930
  /**
@@ -937,7 +938,7 @@ async function pollUntil(options) {
937
938
  if (await options.until()) {
938
939
  return;
939
940
  }
940
- await sleep(intervalMs);
941
+ await sleep$1(intervalMs);
941
942
  }
942
943
  throw new Error(`pollUntil timeout after ${options.timeoutMs}ms`);
943
944
  }
@@ -2611,6 +2612,295 @@ async function runSingleProcessService(options) {
2611
2612
  }
2612
2613
  }
2613
2614
 
2615
+ const logger$2 = createLogger({ module: "telegram" });
2616
+ let cachedDispatcher;
2617
+ let cachedProxyUrl;
2618
+ /** Per-request undici dispatcher when proxyUrl is set (Supabase stays direct). */
2619
+ function telegramFetchDispatcher(proxyUrl) {
2620
+ if (proxyUrl == null) {
2621
+ return undefined;
2622
+ }
2623
+ if (cachedDispatcher != null && cachedProxyUrl === proxyUrl) {
2624
+ return cachedDispatcher;
2625
+ }
2626
+ cachedDispatcher = new ProxyAgent(proxyUrl);
2627
+ cachedProxyUrl = proxyUrl;
2628
+ return cachedDispatcher;
2629
+ }
2630
+ function telegramNetworkHint(proxyUrl) {
2631
+ return proxyUrl
2632
+ ? ` (proxy=${proxyUrl}, ensure Clash/V2Ray is running)`
2633
+ : " (set proxyUrl / TELEGRAM_PROXY if api.telegram.org is blocked)";
2634
+ }
2635
+ function botApiUrl(options, method) {
2636
+ return `${options.apiBaseUrl}/bot${options.botToken}/${method}`;
2637
+ }
2638
+ function telegramFileDownloadUrl(options, filePath) {
2639
+ const normalized = filePath.replace(/^\/+/, "");
2640
+ return `${options.apiBaseUrl}/file/bot${options.botToken}/${normalized}`;
2641
+ }
2642
+ function sleep(ms) {
2643
+ return new Promise((resolve) => setTimeout(resolve, ms));
2644
+ }
2645
+ function telegramBackoff(attempt, retryBaseMs) {
2646
+ return sleep(retryBaseMs * 2 ** (attempt - 1));
2647
+ }
2648
+ /** Bot API JSON call — transport retry via SDK fetch; outer loop retries Telegram `{ ok: false }`. */
2649
+ async function callTelegramApi(options, method, initOrFactory, callOptions = {}) {
2650
+ const timeoutMs = callOptions.timeoutMs ?? options.fetchTimeoutMs;
2651
+ const maxAttempts = callOptions.retryAttempts ?? 1;
2652
+ const retryBaseMs = callOptions.retryBaseMs ?? options.uploadRetryBaseMs;
2653
+ const url = botApiUrl(options, method);
2654
+ const label = `Telegram ${method}`;
2655
+ const dispatcher = telegramFetchDispatcher(options.proxyUrl);
2656
+ const hint = telegramNetworkHint(options.proxyUrl);
2657
+ let lastError = null;
2658
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
2659
+ const response = await fetchWithRetry(url, initOrFactory, {
2660
+ label,
2661
+ timeoutMs,
2662
+ maxAttempts: attempt === 1 ? maxAttempts : 1,
2663
+ retryBaseMs,
2664
+ dispatcher,
2665
+ hint,
2666
+ logger: logger$2,
2667
+ });
2668
+ let payload;
2669
+ try {
2670
+ payload = (await response.json());
2671
+ }
2672
+ catch {
2673
+ lastError = new Error(`${label}: invalid JSON response (HTTP ${response.status})`);
2674
+ if (attempt < maxAttempts && isRetryableHttpStatus(response.status)) {
2675
+ await telegramBackoff(attempt, retryBaseMs);
2676
+ continue;
2677
+ }
2678
+ throw lastError;
2679
+ }
2680
+ if (!payload.ok) {
2681
+ const description = payload.description ?? `HTTP ${response.status}`;
2682
+ lastError = new Error(`${label}: ${description}`);
2683
+ if (attempt < maxAttempts && isRetryableHttpStatus(response.status)) {
2684
+ logger$2.warn("retrying after API error", {
2685
+ topic: "telegram",
2686
+ data: { method, attempt, description },
2687
+ });
2688
+ await telegramBackoff(attempt, retryBaseMs);
2689
+ continue;
2690
+ }
2691
+ throw lastError;
2692
+ }
2693
+ if (payload.result == null) {
2694
+ throw new Error(`${label}: empty result in response`);
2695
+ }
2696
+ if (attempt > 1) {
2697
+ logger$2.info("request succeeded after retry", { topic: "telegram", data: { method, attempt } });
2698
+ }
2699
+ return payload.result;
2700
+ }
2701
+ throw lastError ?? new Error(`${label}: request failed`);
2702
+ }
2703
+ async function telegramDownloadBinary(options, url, label, callOptions = {}) {
2704
+ const dispatcher = telegramFetchDispatcher(options.proxyUrl);
2705
+ return fetchBinaryWithRetry(url, { method: "GET" }, {
2706
+ label: `Telegram ${label}`,
2707
+ timeoutMs: callOptions.timeoutMs ?? options.fetchTimeoutMs,
2708
+ maxAttempts: callOptions.retryAttempts ?? 1,
2709
+ retryBaseMs: callOptions.retryBaseMs ?? options.uploadRetryBaseMs,
2710
+ dispatcher,
2711
+ hint: telegramNetworkHint(options.proxyUrl),
2712
+ logger: logger$2,
2713
+ });
2714
+ }
2715
+
2716
+ /** Download chunk bytes by Telegram `file_id` stored in Chunk.url. */
2717
+ async function downloadTelegramChunk(options, fileId) {
2718
+ const file = await callTelegramApi(options, `getFile?file_id=${encodeURIComponent(fileId)}`, { method: "GET" }, {
2719
+ retryAttempts: options.uploadRetryAttempts,
2720
+ retryBaseMs: options.uploadRetryBaseMs,
2721
+ });
2722
+ if (file.file_path == null || file.file_path === "") {
2723
+ throw new Error(`Telegram getFile: missing file_path for file_id ${fileId}`);
2724
+ }
2725
+ return telegramDownloadBinary(options, telegramFileDownloadUrl(options, file.file_path), `download:${fileId.slice(0, 12)}…`, {
2726
+ timeoutMs: options.uploadTimeoutMs,
2727
+ retryAttempts: options.uploadRetryAttempts,
2728
+ retryBaseMs: options.uploadRetryBaseMs,
2729
+ });
2730
+ }
2731
+
2732
+ /**
2733
+ * Telegram chunk URL encoding: `${messageId}|${fileId}`.
2734
+ * Legacy parcels store bare `file_id` (no messageId → cannot deleteMessage).
2735
+ */
2736
+ const SEPARATOR = "|";
2737
+ function encodeTelegramChunkUrl(messageId, fileId) {
2738
+ return `${messageId}${SEPARATOR}${fileId}`;
2739
+ }
2740
+ function parseTelegramChunkUrl(locator) {
2741
+ const idx = locator.indexOf(SEPARATOR);
2742
+ if (idx <= 0) {
2743
+ return { messageId: null, fileId: locator };
2744
+ }
2745
+ const mid = Number(locator.slice(0, idx));
2746
+ const fileId = locator.slice(idx + 1);
2747
+ if (!Number.isInteger(mid) || mid <= 0 || fileId === "") {
2748
+ return { messageId: null, fileId: locator };
2749
+ }
2750
+ return { messageId: mid, fileId };
2751
+ }
2752
+
2753
+ function resolveTelegramStorageOptions(options) {
2754
+ const botToken = options.botToken.trim();
2755
+ const chatId = options.chatId.trim();
2756
+ if (botToken === "") {
2757
+ throw new Error("TelegramStorageProviderOptions.botToken is required");
2758
+ }
2759
+ if (chatId === "") {
2760
+ throw new Error("TelegramStorageProviderOptions.chatId is required");
2761
+ }
2762
+ const apiBaseUrl = (options.apiBaseUrl?.trim() || "https://api.telegram.org").replace(/\/$/, "");
2763
+ const proxyUrl = options.proxyUrl?.trim() || undefined;
2764
+ return {
2765
+ botToken,
2766
+ chatId,
2767
+ apiBaseUrl,
2768
+ proxyUrl: proxyUrl !== "" ? proxyUrl : undefined,
2769
+ fetchTimeoutMs: options.fetchTimeoutMs ?? 30_000,
2770
+ uploadTimeoutMs: options.uploadTimeoutMs ?? 120_000,
2771
+ uploadRetryAttempts: options.uploadRetryAttempts ?? 3,
2772
+ uploadRetryBaseMs: options.uploadRetryBaseMs ?? 2_000,
2773
+ };
2774
+ }
2775
+
2776
+ const PROVIDER_TELEGRAM = "telegram";
2777
+ async function uploadChunkToTelegram(options, data, filename) {
2778
+ const sizeMb = (data.byteLength / (1024 * 1024)).toFixed(2);
2779
+ const message = await callTelegramApi(options, "sendDocument", () => {
2780
+ const form = new FormData();
2781
+ form.append("chat_id", options.chatId);
2782
+ form.append("document", new Blob([data]), filename);
2783
+ return { method: "POST", body: form };
2784
+ }, {
2785
+ timeoutMs: options.uploadTimeoutMs,
2786
+ retryAttempts: options.uploadRetryAttempts,
2787
+ retryBaseMs: options.uploadRetryBaseMs,
2788
+ });
2789
+ const fileId = message.document?.file_id;
2790
+ if (fileId == null || fileId === "") {
2791
+ throw new Error(`Telegram sendDocument: missing file_id (chunk ${filename}, ${sizeMb} MB)`);
2792
+ }
2793
+ return { fileId, messageId: message.message_id };
2794
+ }
2795
+ async function deleteTelegramMessage(options, messageId) {
2796
+ await callTelegramApi(options, "deleteMessage", () => {
2797
+ const form = new FormData();
2798
+ form.append("chat_id", options.chatId);
2799
+ form.append("message_id", String(messageId));
2800
+ return { method: "POST", body: form };
2801
+ }, {
2802
+ retryAttempts: 3,
2803
+ retryBaseMs: 1_000,
2804
+ });
2805
+ }
2806
+ async function rollbackTelegramUploads(options, handles) {
2807
+ for (const item of handles) {
2808
+ const upload = item;
2809
+ if (upload?.messageId == null) {
2810
+ continue;
2811
+ }
2812
+ try {
2813
+ await deleteTelegramMessage(options, upload.messageId);
2814
+ }
2815
+ catch {
2816
+ // Best-effort cleanup
2817
+ }
2818
+ }
2819
+ }
2820
+ function assertTelegramParcel(parcel) {
2821
+ const chunks = parcel.details.chunkList;
2822
+ if (chunks.length === 0) {
2823
+ throw new Error("Parcel has no chunks");
2824
+ }
2825
+ const nonTelegram = chunks.filter((chunk) => chunk.provider != null && chunk.provider !== PROVIDER_TELEGRAM);
2826
+ if (nonTelegram.length > 0) {
2827
+ const providers = [...new Set(nonTelegram.map((chunk) => chunk.provider))];
2828
+ throw new Error(`Parcel is not telegram-only (found providers: ${providers.join(", ")}). ` +
2829
+ "Multi-provider restore is not yet supported for this parcel.");
2830
+ }
2831
+ }
2832
+ /**
2833
+ * Build a Telegram {@link StorageProviderModule}. Caller registers it — no side effects.
2834
+ *
2835
+ * @example
2836
+ * ```ts
2837
+ * import { createStorageProviderRegistry, createTelegramStorageProvider } from "target-supabase-sdk/node";
2838
+ * const registry = createStorageProviderRegistry();
2839
+ * registry.register(createTelegramStorageProvider({ botToken, chatId, proxyUrl }));
2840
+ * ```
2841
+ */
2842
+ function createTelegramStorageProvider(input) {
2843
+ const options = resolveTelegramStorageOptions(input);
2844
+ return {
2845
+ provider: PROVIDER_TELEGRAM,
2846
+ uploadChunk: (data, filename) => uploadChunkToTelegram(options, data, filename),
2847
+ deleteMessage: (messageId) => deleteTelegramMessage(options, messageId),
2848
+ async deleteChunkBlobs(parcel) {
2849
+ let deleted = 0;
2850
+ let failed = 0;
2851
+ let skipped = 0;
2852
+ for (const chunk of parcel.details.chunkList) {
2853
+ if (chunk.provider != null && chunk.provider !== PROVIDER_TELEGRAM) {
2854
+ skipped += 1;
2855
+ continue;
2856
+ }
2857
+ const { messageId } = parseTelegramChunkUrl(chunk.url);
2858
+ if (messageId == null) {
2859
+ skipped += 1;
2860
+ continue;
2861
+ }
2862
+ try {
2863
+ await deleteTelegramMessage(options, messageId);
2864
+ deleted += 1;
2865
+ }
2866
+ catch {
2867
+ failed += 1;
2868
+ }
2869
+ }
2870
+ return { deleted, failed, skipped };
2871
+ },
2872
+ createUploadAdapter(adapterOptions) {
2873
+ const tracker = adapterOptions?.tracker;
2874
+ return {
2875
+ provider: PROVIDER_TELEGRAM,
2876
+ async upload(data, pathOrKey) {
2877
+ const result = await uploadChunkToTelegram(options, data, pathOrKey);
2878
+ tracker?.push(result);
2879
+ // Persist messageId so later deleteParcel can call deleteMessage.
2880
+ return { url: encodeTelegramChunkUrl(result.messageId, result.fileId) };
2881
+ },
2882
+ };
2883
+ },
2884
+ resolveChunk: (locator) => {
2885
+ const { fileId } = parseTelegramChunkUrl(locator);
2886
+ return downloadTelegramChunk(options, fileId);
2887
+ },
2888
+ matchesOpaqueUrl: isOpaqueChunkUrl,
2889
+ async probe() {
2890
+ try {
2891
+ const me = await callTelegramApi(options, "getMe", { method: "GET" });
2892
+ return { ok: true, detail: { username: me.username ?? "unknown" } };
2893
+ }
2894
+ catch (error) {
2895
+ const message = error instanceof Error ? error.message : String(error);
2896
+ return { ok: false, error: message };
2897
+ }
2898
+ },
2899
+ rollbackUpload: (handles) => rollbackTelegramUploads(options, handles),
2900
+ assertParcelRestorable: assertTelegramParcel,
2901
+ };
2902
+ }
2903
+
2614
2904
  /** Supabase `target.category` for rows that store task script payloads */
2615
2905
  const TASK_REPO_SCRIPT_CATEGORY = "script";
2616
2906
  /** Host app config directory (relative to `cwd`) — recommended for library consumers */
@@ -3065,6 +3355,247 @@ const RepoManager = {
3065
3355
  clearRepoScriptModuleCache,
3066
3356
  };
3067
3357
 
3358
+ function sameStorageHost$1(storageProvider, localStorageProvider) {
3359
+ return storageProvider.trim() === localStorageProvider.trim();
3360
+ }
3361
+ function isFeedDirectoryValue(value) {
3362
+ return value === "feed.image-list";
3363
+ }
3364
+ /**
3365
+ * Local reachability for feed ingest (`.local` source).
3366
+ *
3367
+ * - Requires `storageProvider === localStorageProvider`.
3368
+ * - `locator` must be an absolute path.
3369
+ * - `feed.image-list`: directory exists.
3370
+ * - Other feed values: non-empty file.
3371
+ *
3372
+ * **Node-only**
3373
+ */
3374
+ async function checkFeedLocalAvailability(input) {
3375
+ const storageProvider = input.storageProvider.trim();
3376
+ const localStorageProvider = input.localStorageProvider.trim();
3377
+ const locator = input.locator.trim();
3378
+ if (storageProvider === "" || localStorageProvider === "") {
3379
+ return { ok: false, reason: "storageProvider and localStorageProvider are required" };
3380
+ }
3381
+ if (locator === "") {
3382
+ return { ok: false, reason: "locator is empty" };
3383
+ }
3384
+ if (!sameStorageHost$1(storageProvider, localStorageProvider)) {
3385
+ return {
3386
+ ok: false,
3387
+ reason: `storageProvider not on this host (${storageProvider} !== ${localStorageProvider})`,
3388
+ };
3389
+ }
3390
+ if (!isAbsolute(locator)) {
3391
+ return { ok: false, reason: `locator must be an absolute path: ${locator}` };
3392
+ }
3393
+ const absolutePath = resolve(locator);
3394
+ try {
3395
+ const info = await stat(absolutePath);
3396
+ if (isFeedDirectoryValue(input.value)) {
3397
+ if (!info.isDirectory()) {
3398
+ return { ok: false, reason: `feed.image-list locator is not a directory: ${absolutePath}` };
3399
+ }
3400
+ return { ok: true, absolutePath };
3401
+ }
3402
+ if (!info.isFile()) {
3403
+ return { ok: false, reason: `locator is not a file: ${absolutePath}` };
3404
+ }
3405
+ if (info.size <= 0) {
3406
+ return { ok: false, reason: `file is empty: ${absolutePath}` };
3407
+ }
3408
+ return { ok: true, absolutePath };
3409
+ }
3410
+ catch (error) {
3411
+ const message = error instanceof Error ? error.message : String(error);
3412
+ return { ok: false, reason: `locator not reachable: ${absolutePath} (${message})` };
3413
+ }
3414
+ }
3415
+ const OSS_CHECK_TIMEOUT_MS = 15_000;
3416
+ const OSS_CHECK_MAX_ATTEMPTS = 2;
3417
+ async function probeHttpLocator(locator, method) {
3418
+ return fetchWithRetry(locator, {
3419
+ method,
3420
+ ...(method === "GET" ? { headers: { Range: "bytes=0-0" } } : {}),
3421
+ }, {
3422
+ label: "feed-oss-check",
3423
+ timeoutMs: OSS_CHECK_TIMEOUT_MS,
3424
+ maxAttempts: OSS_CHECK_MAX_ATTEMPTS,
3425
+ });
3426
+ }
3427
+ /**
3428
+ * Remote reachability for feed ingest (`.oss` source) via HTTP(S).
3429
+ *
3430
+ * Tries `HEAD`, then `GET` with `Range: bytes=0-0` when `HEAD` is not allowed.
3431
+ *
3432
+ * **Node-only**
3433
+ */
3434
+ async function checkFeedOssAvailability(locator) {
3435
+ const trimmed = locator.trim();
3436
+ if (trimmed === "") {
3437
+ return { ok: false, reason: "locator is empty" };
3438
+ }
3439
+ if (!isHttpUrl(trimmed)) {
3440
+ return { ok: false, reason: `oss locator must be an http(s) URL: ${trimmed}` };
3441
+ }
3442
+ try {
3443
+ let response = await probeHttpLocator(trimmed, "HEAD");
3444
+ if (response.status === 405 || response.status === 501) {
3445
+ response = await probeHttpLocator(trimmed, "GET");
3446
+ }
3447
+ if (response.ok || (response.status >= 200 && response.status < 400)) {
3448
+ return { ok: true };
3449
+ }
3450
+ return { ok: false, reason: `oss locator HTTP ${response.status}: ${trimmed}` };
3451
+ }
3452
+ catch (error) {
3453
+ const message = error instanceof Error ? error.message : String(error);
3454
+ return { ok: false, reason: `oss locator request failed: ${trimmed} (${message})` };
3455
+ }
3456
+ }
3457
+
3458
+ const logger$1 = createLogger({ module: "feed" });
3459
+ function parseFeedOriginal(original) {
3460
+ if (original == null || typeof original !== "object") {
3461
+ return null;
3462
+ }
3463
+ const record = original;
3464
+ const storageProvider = typeof record.storageProvider === "string" ? record.storageProvider : null;
3465
+ const locator = typeof record.locator === "string" ? record.locator : null;
3466
+ if (storageProvider == null || locator == null) {
3467
+ return null;
3468
+ }
3469
+ const twinList = Array.isArray(record.twinList)
3470
+ ? record.twinList.filter((entry) => typeof entry === "string")
3471
+ : undefined;
3472
+ return {
3473
+ storageProvider,
3474
+ locator,
3475
+ ...(twinList !== undefined ? { twinList } : {}),
3476
+ };
3477
+ }
3478
+ function assertFeedLink(target) {
3479
+ if (target.category !== CategoryLink.LINK) {
3480
+ throw new Error(`registerFeed: target is not a link (category=${target.category})`);
3481
+ }
3482
+ if (!isFeedValue(target.value)) {
3483
+ throw new Error(`registerFeed: target value is not a feed loader: ${target.value}`);
3484
+ }
3485
+ const details = target.details;
3486
+ if (details == null || details.loaderKey !== target.value) {
3487
+ throw new Error("registerFeed: invalid feed link details (loaderKey must equal value)");
3488
+ }
3489
+ return target;
3490
+ }
3491
+ function hasIngestSourceTag(tagList) {
3492
+ return tagList.some((tag) => tag === ".local" || tag === ".oss");
3493
+ }
3494
+ function isSameIngestState(link, source, storageProvider, locator) {
3495
+ if (!link.tagList.includes(source)) {
3496
+ return false;
3497
+ }
3498
+ const original = parseFeedOriginal(link.details.original);
3499
+ if (original == null) {
3500
+ return false;
3501
+ }
3502
+ return original.storageProvider === storageProvider && original.locator === locator;
3503
+ }
3504
+ /**
3505
+ * Ingest a `.public` feed Link: validate locator, then promote `tagList` source to `.local` or `.oss`
3506
+ * and update `details.original.storageProvider` + `locator`.
3507
+ *
3508
+ * **Node-only** — under `shared/feed/node/`; do not import from the browser entry.
3509
+ */
3510
+ async function registerFeed(input) {
3511
+ const id = input.id.trim();
3512
+ if (id === "") {
3513
+ throw new Error("registerFeed: id is empty");
3514
+ }
3515
+ if (!isFeedIngestSource(input.source)) {
3516
+ throw new Error(`registerFeed: source must be .local or .oss, got ${String(input.source)}`);
3517
+ }
3518
+ const resolvedStorageProvider = resolveFeedOriginalStorageProvider(input.source, input.storageProvider);
3519
+ const locator = input.locator.trim();
3520
+ if (locator === "") {
3521
+ throw new Error("registerFeed: locator is empty");
3522
+ }
3523
+ const { data: target } = await getTarget({ id });
3524
+ if (target == null) {
3525
+ throw new Error(`registerFeed: target not found: ${id}`);
3526
+ }
3527
+ const link = assertFeedLink(target);
3528
+ const feedValue = link.value;
3529
+ if (!link.tagList.includes(".public")) {
3530
+ if (isSameIngestState(link, input.source, resolvedStorageProvider, locator)) {
3531
+ logger$1.info("feed already ingested", {
3532
+ topic: "dedup",
3533
+ data: { id, source: input.source, locator },
3534
+ });
3535
+ return { id, updated: false };
3536
+ }
3537
+ if (hasIngestSourceTag(link.tagList)) {
3538
+ throw new Error("registerFeed: feed already ingested with different source, storageProvider, or locator");
3539
+ }
3540
+ throw new Error("registerFeed: feed is not .public — cannot ingest");
3541
+ }
3542
+ if (input.source === ".local") {
3543
+ const localStorageProvider = input.localStorageProvider?.trim() ?? "";
3544
+ if (localStorageProvider === "") {
3545
+ throw new Error("registerFeed: localStorageProvider is required when source is .local");
3546
+ }
3547
+ const availability = await checkFeedLocalAvailability({
3548
+ value: feedValue,
3549
+ storageProvider: resolvedStorageProvider,
3550
+ locator,
3551
+ localStorageProvider,
3552
+ });
3553
+ if (!availability.ok) {
3554
+ throw new Error(`registerFeed: local locator unavailable — ${availability.reason ?? "unknown"}`);
3555
+ }
3556
+ }
3557
+ else {
3558
+ const availability = await checkFeedOssAvailability(locator);
3559
+ if (!availability.ok) {
3560
+ throw new Error(`registerFeed: oss locator unavailable — ${availability.reason ?? "unknown"}`);
3561
+ }
3562
+ }
3563
+ await updateTarget({
3564
+ id,
3565
+ optimisticLockFilterList: [
3566
+ { field: "category", operator: "eq", value: CategoryLink.LINK },
3567
+ { field: "details->original->>storageProvider", operator: "eq", value: "" },
3568
+ ],
3569
+ updateFn: (row) => {
3570
+ if (!row.tagList.includes(".public")) {
3571
+ throw new Error("registerFeed: optimistic lock failed — .public tag missing");
3572
+ }
3573
+ if (hasIngestSourceTag(row.tagList) && !row.tagList.includes(".public")) {
3574
+ throw new Error("registerFeed: feed already ingested");
3575
+ }
3576
+ const details = row.details;
3577
+ const prior = parseFeedOriginal(details.original);
3578
+ const nextOriginal = {
3579
+ storageProvider: resolvedStorageProvider,
3580
+ locator,
3581
+ ...(prior?.twinList !== undefined ? { twinList: prior.twinList } : {}),
3582
+ };
3583
+ return {
3584
+ tagList: buildFeedTagList(input.source, row.tagList),
3585
+ details: {
3586
+ ...details,
3587
+ original: nextOriginal,
3588
+ },
3589
+ };
3590
+ },
3591
+ });
3592
+ logger$1.info("feed ingested", {
3593
+ topic: "register",
3594
+ data: { id, source: input.source, storageProvider: resolvedStorageProvider, locator },
3595
+ });
3596
+ return { id, updated: true };
3597
+ }
3598
+
3068
3599
  function createLogSpoolCoordinator(options) {
3069
3600
  const { serviceValue, serviceId } = options;
3070
3601
  return {
@@ -4241,5 +4772,5 @@ const patchTriggerFired = validateWithSchema(patchTriggerFiredSchema, "patchTrig
4241
4772
  }
4242
4773
  });
4243
4774
 
4244
- export { BaseNodeRuntime, COLLECT_LOG_RUNNER_KEY, CategoryCommand, CategoryNode, CategoryRepo, CategoryTrigger, CommandType, EMPTY_REGISTRY_SLOT_RUNTIME_STATE, LOG_SPOOL_SERVICE_ID_ENV, LOG_TOPIC_TRIGGER, LogLevel, MAX_POLL_TARGET_LIST_SIZE, MEDIA_CONTENT_HASH_ALGORITHM, ManagedChildProcesses, NodeStatus, RepoManager, ResultCode, SERVICE_GUARD_RUNNER_KEY, ServiceGuardNode, ServiceRegistryError, TASK_LOCAL_PACKAGE_CONFIG_FILENAME, TASK_REPO_SCRIPT_CATEGORY, TASK_REPO_USAGE, TASK_RUNNER_CONFIG_DIR, TASK_RUNNER_ROOT_CONFIG_FILENAME, TASK_RUNNER_ROOT_CONFIG_LEGACY_RELATIVE_PATH, TASK_RUNNER_ROOT_CONFIG_RELATIVE_PATH, TRIGGER_LOOP_INTERVAL_MS, TRIGGER_RUNNER_DEFAULT_RETRY_COUNT, TRIGGER_RUNNER_DEFAULT_RETRY_DELAY_MS, TaskManager, TaskNode, TaskRepoValidation, TaskStatus, TaskStatusAction, TriggerManager, TriggerNode, TriggerStatus, applyRegistrySlotGuardStep, buildMediaLinkDraft, buildNodeImportArgs, checkMediaAvailability, claimServiceRegistrySlot, createJsonFileStateStore, createL3ChildLauncher, createLogSpoolCoordinator, createLogger, createManagedChildProcesses, createPathsExistCheck, createRequiredEnvCheck, createServiceHost, createServiceRuntimeStateStore, createSupabaseReachableCheck, createTarget, enableLogSpoolFromEnvInChild, ensureLogSpoolFromEnv, evaluateBusyNodeLiveness, findMediaLink, generateResponse, getConfigFileDir, getLogSpoolStats, getMainLogSpoolWriterStats, getPollCommandList, getPollCommandListSchema, getPossibleTarget, getScanRemoteRepoValues, guardRetryAfterSec, guessMediaMime, importJsConfigModule, initSupabaseFromStandardEnv, isChildProcessRunning, isCreateTargetAlreadyExistsError, isGuardAvailable, isLogEntry, isLogSpoolEnabled, isMediaValue, isOptimisticLockResponse, loadCachedJsConfigModule, loadEnvFiles, logManager, logSpoolEnabledFromEnv, markWorkerSpawned, mediaLinkDedupFilters, nodeBufferToArrayBuffer, patchChangeNodeStatus, patchChangeTaskStatus, patchClaimTask, patchNodeHeartBeat, patchServiceRuntime, patchStopNode, patchTriggerFired, patchTriggerFiredSchema, pathExists, pollTargetList, pollUntil, postCommand, postCommandSchema, postRegisterNode, postTarget, postTaskSchema, postTaskWithValidation, postTrigger, postTriggerSchema, probeMediaOriginal, publicBaseUrlFromEnv, readAndVerifySourceFile, readEnv, registerCollectLogRunner, registerMediaLink, registerServiceGuardRunner, registrySlotRuntimePatchFromGuardResult, requireEnv, resolveFirstExistingPath, resolveLogSpoolRoot, resolvePathFromBaseDir, resolvePathFromConfigFile, resolvePathFromCwd, runCollectLogTick, runReadinessChecks, runReadinessGate, runRegistrySlotGuardCheck, runServiceGuardTick, runSingleProcessService, scanEnabledTriggers, scanEnabledTriggersSchema, scanTargetList, sha256Hex, shutdownLogSpool, shutdownLogSpoolFromEnv, spawnTsxChild, supabase, toFileImportHref, updateTargetDetails, validateTaskRepoAndParams, validateWithSchema, waitForServiceReady };
4775
+ export { BaseNodeRuntime, COLLECT_LOG_RUNNER_KEY, CategoryCommand, CategoryLink, CategoryNode, CategoryRepo, CategoryTrigger, CommandType, EMPTY_REGISTRY_SLOT_RUNTIME_STATE, LOG_SPOOL_SERVICE_ID_ENV, LOG_TOPIC_TRIGGER, LogLevel, MAX_POLL_TARGET_LIST_SIZE, MEDIA_CONTENT_HASH_ALGORITHM, ManagedChildProcesses, NodeStatus, PROVIDER_TELEGRAM, RepoManager, ResultCode, SERVICE_GUARD_RUNNER_KEY, ServiceGuardNode, ServiceRegistryError, TASK_LOCAL_PACKAGE_CONFIG_FILENAME, TASK_REPO_SCRIPT_CATEGORY, TASK_REPO_USAGE, TASK_RUNNER_CONFIG_DIR, TASK_RUNNER_ROOT_CONFIG_FILENAME, TASK_RUNNER_ROOT_CONFIG_LEGACY_RELATIVE_PATH, TASK_RUNNER_ROOT_CONFIG_RELATIVE_PATH, TRIGGER_LOOP_INTERVAL_MS, TRIGGER_RUNNER_DEFAULT_RETRY_COUNT, TRIGGER_RUNNER_DEFAULT_RETRY_DELAY_MS, TaskManager, TaskNode, TaskRepoValidation, TaskStatus, TaskStatusAction, TriggerManager, TriggerNode, TriggerStatus, applyRegistrySlotGuardStep, buildMediaLinkDraft, buildNodeImportArgs, callTelegramApi, checkFeedLocalAvailability, checkFeedOssAvailability, checkMediaAvailability, claimServiceRegistrySlot, createJsonFileStateStore, createL3ChildLauncher, createLogSpoolCoordinator, createLogger, createManagedChildProcesses, createPathsExistCheck, createRequiredEnvCheck, createServiceHost, createServiceRuntimeStateStore, createSupabaseReachableCheck, createTarget, createTelegramStorageProvider, downloadTelegramChunk, enableLogSpoolFromEnvInChild, encodeTelegramChunkUrl, ensureLogSpoolFromEnv, evaluateBusyNodeLiveness, fetchBinaryWithRetry, fetchWithRetry, findMediaLink, generateResponse, getConfigFileDir, getLogSpoolStats, getMainLogSpoolWriterStats, getPollCommandList, getPollCommandListSchema, getPossibleTarget, getScanRemoteRepoValues, getTarget, guardRetryAfterSec, guessMediaMime, importJsConfigModule, initSupabaseFromStandardEnv, isChildProcessRunning, isCreateTargetAlreadyExistsError, isFeedIngestSource, isFeedValue, isGuardAvailable, isHttpUrl, isLogEntry, isLogSpoolEnabled, isMediaValue, isOpaqueChunkUrl, isOptimisticLockResponse, isRetryableHttpStatus, loadCachedJsConfigModule, loadEnvFiles, logManager, logSpoolEnabledFromEnv, markWorkerSpawned, mediaLinkDedupFilters, nodeBufferToArrayBuffer, parseTelegramChunkUrl, patchChangeNodeStatus, patchChangeTaskStatus, patchClaimTask, patchNodeHeartBeat, patchServiceRuntime, patchStopNode, patchTriggerFired, patchTriggerFiredSchema, pathExists, pollTargetList, pollUntil, postCommand, postCommandSchema, postRegisterNode, postTarget, postTaskSchema, postTaskWithValidation, postTrigger, postTriggerSchema, probeMediaOriginal, publicBaseUrlFromEnv, readAndVerifySourceFile, readEnv, registerCollectLogRunner, registerFeed, registerMediaLink, registerServiceGuardRunner, registrySlotRuntimePatchFromGuardResult, requireEnv, resolveFirstExistingPath, resolveLogSpoolRoot, resolvePathFromBaseDir, resolvePathFromConfigFile, resolvePathFromCwd, resolveTelegramStorageOptions, runCollectLogTick, runReadinessChecks, runReadinessGate, runRegistrySlotGuardCheck, runServiceGuardTick, runSingleProcessService, scanEnabledTriggers, scanEnabledTriggersSchema, scanTargetList, sha256Hex, shutdownLogSpool, shutdownLogSpoolFromEnv, spawnTsxChild, supabase, telegramDownloadBinary, telegramFileDownloadUrl, toFileImportHref, updateTarget, updateTargetDetails, validateTaskRepoAndParams, validateWithSchema, waitForServiceReady };
4245
4776
  //# sourceMappingURL=node.js.map