stitchkit 0.107.0 → 0.108.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.
Files changed (102) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +2 -0
  3. package/darwin-native.cjs +1 -0
  4. package/dist/agent-runtime/sandbox-process-owner.d.ts +3 -3
  5. package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
  6. package/dist/agent-runtime/sandbox-process.d.ts +2 -2
  7. package/dist/agent-runtime/sandbox-process.d.ts.map +1 -1
  8. package/dist/agent-runtime/store-conformance-support.d.ts +5 -5
  9. package/dist/browser/stream.d.ts +38 -12
  10. package/dist/browser/stream.d.ts.map +1 -1
  11. package/dist/entrypoints/agent-runtime/coding-tools.js +2 -2
  12. package/dist/entrypoints/agent-runtime/sandbox.js +2 -2
  13. package/dist/entrypoints/application/diagnostic-journal.js +2 -2
  14. package/dist/entrypoints/application/directory-inbox.js +4 -4
  15. package/dist/entrypoints/bin/upgrade-cli.d.ts +32 -0
  16. package/dist/entrypoints/bin/upgrade-cli.d.ts.map +1 -1
  17. package/dist/entrypoints/bin/upgrade-cli.js +451 -8
  18. package/dist/entrypoints/cli/publish.js +3 -3
  19. package/dist/entrypoints/files/packaging.d.ts +3 -1
  20. package/dist/entrypoints/files/packaging.d.ts.map +1 -1
  21. package/dist/entrypoints/files/packaging.js +105 -41
  22. package/dist/entrypoints/files.js +3 -3
  23. package/dist/entrypoints/index.d.ts +1 -1
  24. package/dist/entrypoints/index.d.ts.map +1 -1
  25. package/dist/entrypoints/index.js +7 -1
  26. package/dist/entrypoints/process.js +2 -2
  27. package/dist/entrypoints/remote.js +1 -1
  28. package/dist/entrypoints/server.js +4 -4
  29. package/dist/entrypoints/telegram/screens.js +1 -1
  30. package/dist/entrypoints/telegram.d.ts +2 -0
  31. package/dist/entrypoints/telegram.d.ts.map +1 -1
  32. package/dist/entrypoints/telegram.js +337 -3
  33. package/dist/entrypoints/testing.d.ts +1 -0
  34. package/dist/entrypoints/testing.d.ts.map +1 -1
  35. package/dist/entrypoints/testing.js +131 -1
  36. package/dist/files/native-artifact.d.ts +14 -0
  37. package/dist/files/native-artifact.d.ts.map +1 -0
  38. package/dist/files/native-packaging-layout.d.ts +5 -0
  39. package/dist/files/native-packaging-layout.d.ts.map +1 -1
  40. package/dist/files/native-packaging-plugin.d.ts +53 -0
  41. package/dist/files/native-packaging-plugin.d.ts.map +1 -0
  42. package/dist/files/native-packaging.d.ts +1 -35
  43. package/dist/files/native-packaging.d.ts.map +1 -1
  44. package/dist/index-a5qr2rj6.js +26 -0
  45. package/dist/{index-7r74re56.js → index-bh2ht9y5.js} +12 -6
  46. package/dist/{index-dwf0gymy.js → index-e35py42g.js} +1 -1
  47. package/dist/{index-4q9jvqg7.js → index-epg514ys.js} +182 -13
  48. package/dist/{index-mbf4h8kp.js → index-nx49x0tw.js} +1 -1
  49. package/dist/{index-zsqt5q98.js → index-p5kx5vqd.js} +209 -54
  50. package/dist/{index-bnf8s6v3.js → index-t2bsd0hm.js} +1 -1
  51. package/dist/{index-4f37d3bg.js → index-w9mqgnz9.js} +1 -1
  52. package/dist/{index-e05cjgtf.js → index-xvj9h8yh.js} +28 -1
  53. package/dist/internal/bounded-lines.d.ts +46 -2
  54. package/dist/internal/bounded-lines.d.ts.map +1 -1
  55. package/dist/internal/process-identity.d.ts.map +1 -1
  56. package/dist/internal/until-aborted.d.ts +9 -0
  57. package/dist/internal/until-aborted.d.ts.map +1 -0
  58. package/dist/internal/upgrade-affects.d.ts +58 -0
  59. package/dist/internal/upgrade-affects.d.ts.map +1 -0
  60. package/dist/internal/upgrade-plan.d.ts +20 -0
  61. package/dist/internal/upgrade-plan.d.ts.map +1 -1
  62. package/dist/internal/upgrade-usage.d.ts +61 -0
  63. package/dist/internal/upgrade-usage.d.ts.map +1 -0
  64. package/dist/process/bun-child.d.ts +38 -0
  65. package/dist/process/bun-child.d.ts.map +1 -0
  66. package/dist/process/command-owner.d.ts +2 -2
  67. package/dist/process/command-owner.d.ts.map +1 -1
  68. package/dist/process/launch.d.ts +2 -2
  69. package/dist/process/launch.d.ts.map +1 -1
  70. package/dist/process/owned-child.d.ts +2 -1
  71. package/dist/process/owned-child.d.ts.map +1 -1
  72. package/dist/telegram/bot-api.d.ts +10 -4
  73. package/dist/telegram/bot-api.d.ts.map +1 -1
  74. package/dist/telegram/broadcast.d.ts +2 -1
  75. package/dist/telegram/broadcast.d.ts.map +1 -1
  76. package/dist/telegram/not-dispatched.d.ts +26 -0
  77. package/dist/telegram/not-dispatched.d.ts.map +1 -0
  78. package/dist/telegram/operator-channel.d.ts +2 -1
  79. package/dist/telegram/operator-channel.d.ts.map +1 -1
  80. package/dist/telegram/send-failure.d.ts +4 -3
  81. package/dist/telegram/send-failure.d.ts.map +1 -1
  82. package/dist/telegram/transport-connect.d.ts +38 -0
  83. package/dist/telegram/transport-connect.d.ts.map +1 -0
  84. package/dist/telegram/transport.d.ts +43 -0
  85. package/dist/telegram/transport.d.ts.map +1 -0
  86. package/dist/telegram/webhook.d.ts +2 -1
  87. package/dist/telegram/webhook.d.ts.map +1 -1
  88. package/dist/testing/manual-clock.d.ts +82 -0
  89. package/dist/testing/manual-clock.d.ts.map +1 -0
  90. package/llms/files-packaging.txt +4 -1
  91. package/llms/process.txt +19 -5
  92. package/llms/stitchkit.2.txt +211 -628
  93. package/llms/stitchkit.txt +635 -10
  94. package/llms/telegram.txt +36 -3
  95. package/llms/testing.txt +47 -0
  96. package/llms/{upgrading-0.98.0-0.107.0.txt → upgrading-0.100.0-0.108.0.txt} +59 -64
  97. package/llms/{upgrading-0.72.0-0.97.0.txt → upgrading-0.72.0-0.99.0.txt} +64 -3
  98. package/llms/upgrading.txt +34 -2
  99. package/llms-full.txt +246 -17
  100. package/llms.txt +8 -8
  101. package/package.json +1 -1
  102. package/llms/stitchkit.3.txt +0 -177
@@ -0,0 +1,38 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { Readable, Writable } from 'node:stream';
3
+ /** What a spawned command exposes to its owner: the subset of a Node child the package uses. */
4
+ export interface OwnedChild extends EventEmitter {
5
+ readonly pid?: number;
6
+ readonly exitCode: number | null;
7
+ readonly signalCode: NodeJS.Signals | null;
8
+ readonly stdin: Writable;
9
+ readonly stdout: Readable;
10
+ readonly stderr: Readable;
11
+ kill(signal: NodeJS.Signals): boolean;
12
+ }
13
+ /** A child spawned with the caller's stdio: it carries no pipes. */
14
+ export interface ObservableChild extends EventEmitter {
15
+ readonly pid?: number;
16
+ readonly exitCode: number | null;
17
+ readonly signalCode: NodeJS.Signals | null;
18
+ kill(signal: NodeJS.Signals): boolean;
19
+ }
20
+ interface BunSpawnInput {
21
+ executable: string;
22
+ args: readonly string[];
23
+ cwd?: string;
24
+ env?: NodeJS.ProcessEnv;
25
+ group: boolean;
26
+ }
27
+ /**
28
+ * Whether the host is Bun. Bun's `node:child_process` can lose a child's `exit` event under
29
+ * host load inside `bun test`; `Bun.spawn` observes the same exit reliably, so under Bun a
30
+ * command is launched through it and presented with the Node child's events and streams.
31
+ */
32
+ export declare function hostIsBun(): boolean;
33
+ /** `spawnOwnedCommand` for Bun: a command with piped stdio. */
34
+ export declare function spawnBunChild(input: BunSpawnInput): OwnedChild;
35
+ /** `spawnInheritedCommand` for Bun: a command with the caller's stdio. */
36
+ export declare function spawnBunInheritedChild(input: BunSpawnInput): ObservableChild;
37
+ export {};
38
+ //# sourceMappingURL=bun-child.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun-child.d.ts","sourceRoot":"","sources":["../../src/process/bun-child.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,gGAAgG;AAChG,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAoKD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CA4B9D;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CAmB5E"}
@@ -1,8 +1,8 @@
1
- import type { ChildProcessWithoutNullStreams } from 'node:child_process';
1
+ import type { OwnedChild } from './bun-child.js';
2
2
  import { type NativeCommandOptions } from './contract.js';
3
3
  import { type NativeCommandLaunchDriver } from './launch.js';
4
4
  /** One-shot native execution; sandbox policy/admission is composed above this owner. */
5
- export declare function startNativeCommand(input: NativeCommandOptions, onSpawn?: (child: ChildProcessWithoutNullStreams) => void, driver?: NativeCommandLaunchDriver): {
5
+ export declare function startNativeCommand(input: NativeCommandOptions, onSpawn?: (child: OwnedChild) => void, driver?: NativeCommandLaunchDriver): {
6
6
  result: Promise<{
7
7
  exitCode: number | null;
8
8
  signal: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAIzE,OAAO,EAEL,KAAK,oBAAoB,EAI1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,UAAU,CAAC;AAOlB,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,IAAI,EACzD,MAAM,CAAC,EAAE,yBAAyB;;;;;;;;;;EAkKnC"}
1
+ {"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAEL,KAAK,oBAAoB,EAI1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,UAAU,CAAC;AAOlB,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,yBAAyB;;;;;;;;;;EAkKnC"}
@@ -1,5 +1,5 @@
1
- import type { ChildProcessWithoutNullStreams } from 'node:child_process';
2
1
  import { Readable } from 'node:stream';
2
+ import type { OwnedChild } from './bun-child.js';
3
3
  import { type ParsedNativeCommandOptions } from './contract.js';
4
4
  import { type NativeCommandTransport } from './transport.js';
5
5
  /** A structural host launcher may supply pipes without importing Node ambient types. */
@@ -46,7 +46,7 @@ export declare function launchNativeCommand({ options, driver, onSpawn, onFailur
46
46
  options: ParsedNativeCommandOptions;
47
47
  driver: NativeCommandLaunchDriver | undefined;
48
48
  /** Called once the real child exists, when the command starts. */
49
- onSpawn?: (child: ChildProcessWithoutNullStreams) => void;
49
+ onSpawn?: (child: OwnedChild) => void;
50
50
  /** The process failed to start or reported an error. */
51
51
  onFailure: (error: Error) => void;
52
52
  /** Writing stdin failed for a reason other than a closed pipe. */
@@ -1 +1 @@
1
- {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/process/launch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/process/launch.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type OwnedChild } from './bun-child.js';
1
2
  import type { NativeCommandLaunchedProcess } from './launch.js';
2
3
  /** Only this native spawn can establish group ownership; structural PIDs cannot. */
3
4
  export declare function spawnOwnedCommand(input: {
@@ -6,7 +7,7 @@ export declare function spawnOwnedCommand(input: {
6
7
  cwd?: string;
7
8
  env?: NodeJS.ProcessEnv;
8
9
  group: boolean;
9
- }): import("node:child_process").ChildProcessWithoutNullStreams;
10
+ }): OwnedChild;
10
11
  /** The same ownership rule as {@link spawnOwnedCommand}, for a child that inherits stdio. */
11
12
  export declare function spawnInheritedCommand(input: {
12
13
  executable: string;
@@ -1 +1 @@
1
- {"version":3,"file":"owned-child.d.ts","sourceRoot":"","sources":["../../src/process/owned-child.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAI1F,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,+DASA;AAmDD,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,4BAA4B,CAW/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
1
+ {"version":3,"file":"owned-child.d.ts","sourceRoot":"","sources":["../../src/process/owned-child.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAA+B,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAI1F,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,UAAU,CAIb;AAkED,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,4BAA4B,CAa/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
@@ -7,6 +7,7 @@
7
7
  * Telegram's own structured answer, because `classifyTelegramSendFailure`
8
8
  * reads `error_code` and `parameters.retry_after` before it ever reads prose.
9
9
  */
10
+ import type { TelegramFetch } from './transport.js';
10
11
  /**
11
12
  * The secret half of a bot token — what follows the bot's numeric id and the
12
13
  * colon. The id stays readable: it is the bot's public user id, and the only
@@ -40,14 +41,19 @@ export interface TelegramBotApiCall {
40
41
  /** A local Bot API server, e.g. `http://127.0.0.1:8081`. Default: Telegram's. */
41
42
  readonly apiRoot?: string;
42
43
  readonly signal?: AbortSignal;
43
- readonly fetch?: typeof fetch;
44
+ /**
45
+ * Default: the global `fetch`. `createTelegramBotTransport()` separates a request that never
46
+ * left (`TelegramNotDispatchedError`, safe to repeat) from one whose outcome is unknown.
47
+ */
48
+ readonly fetch?: TelegramFetch;
44
49
  }
45
50
  /**
46
51
  * Call one Bot API method and return its `result`.
47
52
  *
48
- * A refusal throws `TelegramBotApiError`; a transport failure throws an error
49
- * whose message names the method and never the URL, since the URL holds the
50
- * token.
53
+ * A refusal throws `TelegramBotApiError`; a request that never left throws the
54
+ * transport's `TelegramNotDispatchedError` unchanged; any other transport failure
55
+ * throws an error whose message names the method and never the URL, since the URL
56
+ * holds the token.
51
57
  */
52
58
  export declare function callTelegramBotApi(call: TelegramBotApiCall): Promise<unknown>;
53
59
  //# sourceMappingURL=bot-api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bot-api.d.ts","sourceRoot":"","sources":["../../src/telegram/bot-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAyB,CAAC;AAEnE,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AAID,gFAAgF;AAChF,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7F,YACE,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC;KAChD,EAQF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,iFAAiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CAC/B;AAQD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAuCnF"}
1
+ {"version":3,"file":"bot-api.d.ts","sourceRoot":"","sources":["../../src/telegram/bot-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAyB,CAAC;AAEnE,kFAAkF;AAClF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE3D;AAID,gFAAgF;AAChF,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE7F,YACE,MAAM,EAAE,MAAM,EACd,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,mBAAmB,CAAC,YAAY,CAAC,CAAC;KAChD,EAQF;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,iFAAiF;IACjF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC;CAChC;AAQD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAyCnF"}
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import type { TelegramBroadcastFailure } from './broadcast-failure.js';
17
17
  import { type TelegramBroadcastRecipient } from './broadcast-state.js';
18
+ import type { TelegramFetch } from './transport.js';
18
19
  export type { TelegramBroadcastOutcome, TelegramBroadcastRecipient } from './broadcast-state.js';
19
20
  export interface TelegramBroadcastSend {
20
21
  readonly recipient: TelegramBroadcastRecipient;
@@ -91,7 +92,7 @@ export interface TelegramBroadcastSenderConfig {
91
92
  readonly token: string;
92
93
  readonly message: TelegramBroadcastMessage;
93
94
  readonly apiRoot?: string;
94
- readonly fetch?: typeof fetch;
95
+ readonly fetch?: TelegramFetch;
95
96
  }
96
97
  /** The standard `send`: `sendMessage` or `copyMessage` through the Bot API, no bot library. */
97
98
  export declare function telegramBroadcastSender(config: TelegramBroadcastSenderConfig): TelegramBroadcastConfig['send'];
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/telegram/broadcast.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/telegram/broadcast.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Where a Bot API request stopped before any byte of it was written: the address lookup, the
3
+ * connection, or the request itself (a body that could not be read).
4
+ */
5
+ export type TelegramNotDispatchedStage = 'lookup' | 'connect' | 'request';
6
+ /**
7
+ * The request provably never reached Telegram, so sending it again cannot duplicate a message.
8
+ * Thrown only before the first byte is written; any failure after that is an ordinary error,
9
+ * because the request may have arrived. Its message names no address that carries the token.
10
+ */
11
+ export declare class TelegramNotDispatchedError extends Error {
12
+ readonly stage: TelegramNotDispatchedStage;
13
+ readonly name = "TelegramNotDispatchedError";
14
+ readonly code = "TELEGRAM_NOT_DISPATCHED";
15
+ constructor(stage: TelegramNotDispatchedStage, message: string, options?: {
16
+ cause?: unknown;
17
+ });
18
+ }
19
+ /**
20
+ * This error, whichever copy of the package made it: its name and code identify it. Only this
21
+ * error is known to carry no address, so it is the one a sender passes through unchanged.
22
+ */
23
+ export declare function isTelegramNotDispatchedError(error: unknown): error is TelegramNotDispatchedError;
24
+ /** Whether `error`, or an error it wraps, is a request that never left. */
25
+ export declare function isTelegramNotDispatched(error: unknown, depth?: number): boolean;
26
+ //# sourceMappingURL=not-dispatched.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-dispatched.d.ts","sourceRoot":"","sources":["../../src/telegram/not-dispatched.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;AAE1E;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IAIjD,QAAQ,CAAC,KAAK,EAAE,0BAA0B;IAH5C,SAAkB,IAAI,gCAAgC;IACtD,QAAQ,CAAC,IAAI,6BAA6B;IAC1C,YACW,KAAK,EAAE,0BAA0B,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAG9B;CACF;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,0BAA0B,CAOrC;AAED,2EAA2E;AAC3E,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAO1E"}
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { type TelegramOperatorDedupe } from './operator-dedupe.js';
17
17
  import { type TelegramSendFailure } from './send-failure.js';
18
+ import type { TelegramFetch } from './transport.js';
18
19
  export type TelegramChatId = number | string;
19
20
  export interface TelegramOperatorMessage {
20
21
  readonly chatId: TelegramChatId;
@@ -83,7 +84,7 @@ export interface TelegramOperatorSenderConfig {
83
84
  readonly apiRoot?: string;
84
85
  /** Default: plain text, so an operator message never fails on entity parsing. */
85
86
  readonly parseMode?: 'HTML' | 'MarkdownV2';
86
- readonly fetch?: typeof fetch;
87
+ readonly fetch?: TelegramFetch;
87
88
  }
88
89
  /**
89
90
  * The standard `send`: `sendMessage` through the Bot API, no bot library. With
@@ -1 +1 @@
1
- {"version":3,"file":"operator-channel.d.ts","sourceRoot":"","sources":["../../src/telegram/operator-channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"operator-channel.d.ts","sourceRoot":"","sources":["../../src/telegram/operator-channel.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@
31
31
  * chat Telegram does not know is usually a bad identifier on our side — a
32
32
  * defect in our data, not a fact about a person.
33
33
  */
34
- export type TelegramSendFailureReason = 'blocked-by-user' | 'user-deactivated' | 'chat-not-found' | 'not-started' | 'rate-limited' | 'message-invalid' | 'server-error' | 'unknown';
34
+ export type TelegramSendFailureReason = 'blocked-by-user' | 'user-deactivated' | 'chat-not-found' | 'not-started' | 'rate-limited' | 'message-invalid' | 'server-error' | 'not-dispatched' | 'unknown';
35
35
  export interface TelegramSendFailure {
36
36
  reason: TelegramSendFailureReason;
37
37
  /** Telegram's `error_code`, when the failure carried one. */
@@ -59,9 +59,10 @@ export interface TelegramSendFailure {
59
59
  /**
60
60
  * How the reason was reached. `parameters` and `status` are Telegram stating
61
61
  * its own answer in a structured field; `description` is us reading its
62
- * prose, which changes without notice.
62
+ * prose, which changes without notice; `transport` is the transport stating
63
+ * that the request never left (`TelegramNotDispatchedError`).
63
64
  */
64
- evidence: 'parameters' | 'status' | 'description' | 'none';
65
+ evidence: 'parameters' | 'status' | 'description' | 'transport' | 'none';
65
66
  }
66
67
  /**
67
68
  * Every reason, for a consumer that maps each one to its own code or text. A
@@ -1 +1 @@
1
- {"version":3,"file":"send-failure.d.ts","sourceRoot":"","sources":["../../src/telegram/send-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,yBAAyB,CAAC;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;CAC5D;AA6CD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,yBAAyB,EAC7B,CAAC;AAyClD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAyD/E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,mBAAmB,GAC3B,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,OAAO,CAAC;AAeZ,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAM/E"}
1
+ {"version":3,"file":"send-failure.d.ts","sourceRoot":"","sources":["../../src/telegram/send-failure.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH;;;;;;;;;GASG;AACH,MAAM,MAAM,yBAAyB,GACjC,iBAAiB,GACjB,kBAAkB,GAClB,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,gBAAgB,GAChB,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,yBAAyB,CAAC;IAClC,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,MAAM,CAAC;CAC1E;AA+CD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,SAAS,yBAAyB,EAC7B,CAAC;AAyClD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA4D/E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,mBAAmB,GAC3B,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,OAAO,CAAC;AAeZ,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAM/E"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The part of a Node `net.Socket` / `tls.TLSSocket` the transport uses, so its declarations need
3
+ * no Node types. A socket emits `connect` (or `secureConnect` when `encrypted`), `data`, `end`,
4
+ * `close` and `error`.
5
+ */
6
+ export interface TelegramBotTransportSocket {
7
+ readonly encrypted?: boolean;
8
+ once(event: 'connect' | 'secureConnect' | 'end' | 'close', listener: () => void): unknown;
9
+ once(event: 'error', listener: (error: Error) => void): unknown;
10
+ on(event: 'data', listener: (chunk: Uint8Array) => void): unknown;
11
+ write(data: Uint8Array): unknown;
12
+ destroy(): unknown;
13
+ }
14
+ /** Opens one socket to one address; `servername` is set for TLS to a host name. */
15
+ export type TelegramBotTransportOpen = (target: {
16
+ readonly address: string;
17
+ readonly port: number;
18
+ readonly tls: boolean;
19
+ readonly servername: string | undefined;
20
+ }) => TelegramBotTransportSocket;
21
+ /** Every address of a host, in the system resolver's order. */
22
+ export type TelegramBotTransportResolve = (host: string) => Promise<readonly string[]>;
23
+ export interface TelegramConnectPolicy {
24
+ readonly resolve: TelegramBotTransportResolve;
25
+ readonly open: TelegramBotTransportOpen;
26
+ /** Real milliseconds one round waits for a connection. */
27
+ readonly attemptMs: number;
28
+ /** Real milliseconds after which no new connection round starts. */
29
+ readonly budgetMs: number;
30
+ }
31
+ export declare const resolveAll: TelegramBotTransportResolve;
32
+ export declare const openSocket: TelegramBotTransportOpen;
33
+ /**
34
+ * A connected socket to `host`, or `TelegramNotDispatchedError`: nothing has been written yet,
35
+ * so every failure here leaves the request unsent. An abort rejects with the signal's reason.
36
+ */
37
+ export declare function establish(host: string, port: number, tls: boolean, policy: TelegramConnectPolicy, signal: AbortSignal | undefined): Promise<TelegramBotTransportSocket>;
38
+ //# sourceMappingURL=transport-connect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-connect.d.ts","sourceRoot":"","sources":["../../src/telegram/transport-connect.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,eAAe,GAAG,KAAK,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;IAC1F,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;IAChE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC;IAClE,KAAK,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;IACjC,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,mFAAmF;AACnF,MAAM,MAAM,wBAAwB,GAAG,CAAC,MAAM,EAAE;IAC9C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,KAAK,0BAA0B,CAAC;AAEjC,+DAA+D;AAC/D,MAAM,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;AAEvF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IACxC,0DAA0D;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAOD,eAAO,MAAM,UAAU,EAAE,2BAC0D,CAAC;AAEpF,eAAO,MAAM,UAAU,EAAE,wBAQgB,CAAC;AAkG1C;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,0BAA0B,CAAC,CAuCrC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * A Bot API transport that knows whether its request left.
3
+ *
4
+ * `fetch` folds establishing the connection and waiting for the answer into one failure, and
5
+ * from that failure nobody can say whether Telegram saw the message. A sender that must never
6
+ * duplicate a message then treats every network failure as "maybe delivered" and never repeats
7
+ * it, so a route that only sometimes fails to connect loses messages outright.
8
+ *
9
+ * This transport connects first and writes the request only on an established connection.
10
+ * Until the first byte is written, every failure is `TelegramNotDispatchedError`: the request
11
+ * certainly did not leave and repeating it is safe. After that, a failure is an ordinary error,
12
+ * because the request may have arrived. Addresses come in the system resolver's order with no
13
+ * family forced; the next address starts after a short delay (Happy Eyeballs), and a round with
14
+ * no connection is repeated with new sockets inside a bounded budget.
15
+ */
16
+ import { type TelegramBotTransportOpen, type TelegramBotTransportResolve } from './transport-connect.js';
17
+ export type { TelegramBotTransportOpen, TelegramBotTransportResolve, TelegramBotTransportSocket, } from './transport-connect.js';
18
+ /** What the Bot API senders call: a URL and a request, answered by a `Response`. */
19
+ export type TelegramFetch = (url: string, init: RequestInit) => Promise<Response>;
20
+ export interface TelegramBotTransportOptions {
21
+ /** Real milliseconds one connection round waits. Default 2000: one kernel SYN retry fits. */
22
+ readonly connectAttemptMs?: number;
23
+ /** Real milliseconds after which no new connection round starts. Default 5000. */
24
+ readonly connectBudgetMs?: number;
25
+ /** Real milliseconds from the written request to the end of the answer. Default 30 000. */
26
+ readonly responseTimeoutMs?: number;
27
+ /** Largest answer read, in bytes. Default 1 MiB. */
28
+ readonly maxResponseBytes?: number;
29
+ /** Address lookup. Default: the system resolver, every address in its order. */
30
+ readonly resolve?: TelegramBotTransportResolve;
31
+ /** Socket factory. Default: TLS (ALPN `http/1.1`) for `https:`, plain TCP for `http:`. */
32
+ readonly open?: TelegramBotTransportOpen;
33
+ }
34
+ /**
35
+ * A `fetch` for the Bot API senders (`callTelegramBotApi`, `telegramBroadcastSender`,
36
+ * `telegramOperatorSender`) that separates "not sent" from "unknown". Pass it as their `fetch`:
37
+ * a failure before the request is written throws `TelegramNotDispatchedError`, which
38
+ * `classifyTelegramSendFailure` reads as `not-dispatched` (retryable); any later failure stays
39
+ * an outcome nobody can know. Speaks HTTP/1.1 over `https:` (and `http:` for a local Bot API
40
+ * server); it does not use a proxy.
41
+ */
42
+ export declare function createTelegramBotTransport(options?: TelegramBotTransportOptions): TelegramFetch;
43
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/telegram/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAIL,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAEjC,MAAM,qBAAqB,CAAC;AAE7B,YAAY,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,oFAAoF;AACpF,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAElF,MAAM,WAAW,2BAA2B;IAC1C,6FAA6F;IAC7F,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,2FAA2F;IAC3F,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,oDAAoD;IACpD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC;IAC/C,0FAA0F;IAC1F,QAAQ,CAAC,IAAI,CAAC,EAAE,wBAAwB,CAAC;CAC1C;AA+MD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,2BAAgC,GACxC,aAAa,CAyCf"}
@@ -18,6 +18,7 @@
18
18
  * recovered from it. Errors and reports name hosts only — a foreign webhook's
19
19
  * path may itself be a secret.
20
20
  */
21
+ import type { TelegramFetch } from './transport.js';
21
22
  /** `takeoverFrom` when there is no webhook to take over — the bot polls, or is new. */
22
23
  export declare const TELEGRAM_WEBHOOK_NONE = "none";
23
24
  export interface TelegramWebhookConfig {
@@ -28,7 +29,7 @@ export interface TelegramWebhookConfig {
28
29
  readonly secret: string;
29
30
  /** A local Bot API server. Default: Telegram's. */
30
31
  readonly apiRoot?: string;
31
- readonly fetch?: typeof fetch;
32
+ readonly fetch?: TelegramFetch;
32
33
  readonly signal?: AbortSignal;
33
34
  }
34
35
  export interface ClaimTelegramWebhookConfig extends TelegramWebhookConfig {
@@ -1 +1 @@
1
- {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/telegram/webhook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,uFAAuF;AACvF,eAAO,MAAM,qBAAqB,SAAS,CAAC;AAE5C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA2B,SAAQ,qBAAqB;IACvE;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,2CAA2C;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,oFAAoF;IACpF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,MAAM,sBAAsB;AAChC,sCAAsC;AACpC,iBAAiB;AACnB,6DAA6D;GAC3D,cAAc;AAChB,2EAA2E;GACzE,eAAe,CAAC;AAEpB,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC;IACxC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,YAAY,MAAM,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,EAa5D;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,2DAA2D;IAC3D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAcD,mFAAmF;AACnF,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUrF;AA+BD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,oBAAoB,CAAC,CAS/B;AAED,+EAA+E;AAC/E,MAAM,MAAM,wBAAwB,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAE5E,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACtE;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAUnB"}
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/telegram/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Manual time for tests of schedules, retries and deadlines.
3
+ *
4
+ * Time stands still until the test moves it, and due timers fire strictly in deadline order
5
+ * (ties in scheduling order), so "retry after 5 s" runs in milliseconds and the same way every
6
+ * time. It satisfies every timer boundary Stitchkit accepts: `ManagedScheduleClock`,
7
+ * `DurabilityClock`, `RevisionSignalClock` and `BoundedAdmissionClock`.
8
+ *
9
+ * Between firings the clock yields to the **real event loop** (`setImmediate` turns), not just to
10
+ * microtasks: an async continuation that schedules the next timer often waits on I/O (a socket,
11
+ * a file), and without a real turn `advance(10_000)` would skip a retry the code meant to arm at
12
+ * the fifth second. When the work in flight has no bounded length (a request over a socket, a
13
+ * hash in a thread pool), the code under test `hold`s the clock for its duration; the clock does
14
+ * not move while a hold is open and waits for it in real time, up to `holdLimitMs`, then fails
15
+ * naming every open hold. A held operation that itself waits for the clock (a deadline it is
16
+ * timing out on) `park`s its hold, or the deadline it waits for would never come.
17
+ */
18
+ /** Cancels one scheduled callback; calling it again is harmless. */
19
+ export interface ManualClockTimer {
20
+ cancel(): void;
21
+ }
22
+ /** An open hold: the clock stays where it is until `release`, unless the hold is parked. */
23
+ export interface ManualClockHold {
24
+ /** Ends the hold. */
25
+ release(): void;
26
+ /** The held work now waits for the clock itself; returns the function that ends the park. */
27
+ park(): () => void;
28
+ }
29
+ export interface ManualClockOptions {
30
+ /** Monotonic start, in milliseconds. Default `0`. */
31
+ readonly startMs?: number;
32
+ /** Wall-clock instant at `startMs`. Default `2026-01-01T00:00:00.000Z`. */
33
+ readonly wallStart?: Date;
34
+ /** Real event-loop turns yielded after each firing. Default `8`. */
35
+ readonly yieldTurns?: number;
36
+ /** Real milliseconds the clock waits for open holds before failing. Default `5000`. */
37
+ readonly holdLimitMs?: number;
38
+ }
39
+ export interface ManualClockUntilOptions {
40
+ /** Manual milliseconds per step while no timer is pending. Default `100`. */
41
+ readonly stepMs?: number;
42
+ /** Manual milliseconds after which `until` fails. Default `600_000`. */
43
+ readonly limitMs?: number;
44
+ }
45
+ export interface ManualClock {
46
+ /** Monotonic milliseconds. */
47
+ now(): number;
48
+ /** The wall clock that moves with `now`. */
49
+ wallNow(): Date;
50
+ /** Runs `callback` once the clock reaches `now() + delayMs` (negative delays fire next). */
51
+ schedule(callback: () => void, delayMs: number): ManualClockTimer;
52
+ /**
53
+ * Moves time by `ms`, firing every timer due on the way in deadline order and yielding to the
54
+ * event loop after each, so a timer armed by a fired callback inside the window fires too.
55
+ * A callback that throws rejects `advance` with that error.
56
+ */
57
+ advance(ms: number): Promise<void>;
58
+ /**
59
+ * Moves time from deadline to deadline (by `stepMs` while nothing is pending) until `done()`
60
+ * holds; resolves with the manual milliseconds that took. Fails with `MANUAL_CLOCK_LIMIT`
61
+ * once `limitMs` of manual time pass, naming how many timers are pending.
62
+ */
63
+ until(done: () => boolean, options?: ManualClockUntilOptions): Promise<number>;
64
+ /** How many timers wait. A timer leaked past a component's `close()` shows here. */
65
+ pending(): number;
66
+ /** Holds time while unbounded real work runs; `reason` names it if the hold outlives the limit. */
67
+ hold(reason: string): ManualClockHold;
68
+ }
69
+ /** `MANUAL_CLOCK_HOLD_TIMEOUT`: open holds outlived `holdLimitMs`; `MANUAL_CLOCK_LIMIT`: `until` ran out. */
70
+ export type ManualClockErrorCode = 'MANUAL_CLOCK_HOLD_TIMEOUT' | 'MANUAL_CLOCK_LIMIT';
71
+ /** A manual clock refused to go on; the message and `holds` name what did not finish. */
72
+ export declare class ManualClockError extends Error {
73
+ readonly code: ManualClockErrorCode;
74
+ /** Reasons of the open, unparked holds (`MANUAL_CLOCK_HOLD_TIMEOUT` only). */
75
+ readonly holds: readonly string[];
76
+ readonly name = "ManualClockError";
77
+ constructor(code: ManualClockErrorCode, message: string,
78
+ /** Reasons of the open, unparked holds (`MANUAL_CLOCK_HOLD_TIMEOUT` only). */
79
+ holds?: readonly string[]);
80
+ }
81
+ export declare function createManualClock(options?: ManualClockOptions): ManualClock;
82
+ //# sourceMappingURL=manual-clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual-clock.d.ts","sourceRoot":"","sources":["../../src/testing/manual-clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,oEAAoE;AACpE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,IAAI,IAAI,CAAC;CAChB;AAED,4FAA4F;AAC5F,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,OAAO,IAAI,IAAI,CAAC;IAChB,6FAA6F;IAC7F,IAAI,IAAI,MAAM,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,GAAG,IAAI,MAAM,CAAC;IACd,4CAA4C;IAC5C,OAAO,IAAI,IAAI,CAAC;IAChB,4FAA4F;IAC5F,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAClE;;;;OAIG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,OAAO,EAAE,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/E,oFAAoF;IACpF,OAAO,IAAI,MAAM,CAAC;IAClB,mGAAmG;IACnG,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC;CACvC;AAED,6GAA6G;AAC7G,MAAM,MAAM,oBAAoB,GAAG,2BAA2B,GAAG,oBAAoB,CAAC;AAEtF,yFAAyF;AACzF,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,IAAI,EAAE,oBAAoB;IAEnC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE;IALnC,SAAkB,IAAI,sBAAsB;IAC5C,YACW,IAAI,EAAE,oBAAoB,EACnC,OAAO,EAAE,MAAM;IACf,8EAA8E;IACrE,KAAK,GAAE,SAAS,MAAM,EAAO,EAGvC;CACF;AAUD,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CA+H/E"}
@@ -17,7 +17,10 @@ Also read:
17
17
  `stitchkit/files/packaging` owns `createNativePackaging` and the types
18
18
  `NativePackagingOptions`, `NativePackagingAsset`, `NativePackagingPlugin`, `NativePackagingResult`,
19
19
  and for a standalone executable `NativePackagingEmbeddedOptions`, `NativePackagingEmbeddedAsset`,
20
- `NativePackagingEmbeddedResult`.
20
+ `NativePackagingEmbeddedResult`. `inspectNativeArtifact` classifies a built artifact's bytes by the
21
+ loader it carries as a `NativeArtifactLoader`: `packaged`, `unpackaged` or `no-loader`. The plugin
22
+ fails a build whose entry imports the default loader of another `stitchkit` installation, naming
23
+ both versions and roots.
21
24
  It resolves the installed package's target/version, reads each selected addon once and checks it
22
25
  against the `size` and `sha256` published in the package's `native-assets.json` (`formatVersion: 2`,
23
26
  written when Stitchkit is built). Call it once per build and reuse the result.
package/llms/process.txt CHANGED
@@ -464,11 +464,20 @@ spool never load it, on any operating system. The package is free of import side
464
464
 
465
465
  Check an artifact by its loader, never by whether it holds `.node` bytes: Bun can copy the addon
466
466
  into a compiled executable even without the plugin, and the unpackaged loader does not use it.
467
- Search the artifact for `STITCHKIT_NATIVE_NOT_PACKAGED` in both latin1 and UTF-16LE, because Bun
468
- stores source text with non-ASCII characters as UTF-16. Present: the unpackaged loader is inside,
469
- and every call above refuses on macOS. Absent in a plugin build: the static loader is inside
470
- (`/$bunfs/root/darwin-<arch>-<hash>.node` in an executable, the companion path in a JS build).
471
- Absent without the plugin: nothing in the artifact needs the addon.
467
+ `inspectNativeArtifact(bytes)` from `stitchkit/files/packaging` reads the marker every generated
468
+ loader carries and answers `packaged` (the plugin's static loader is inside), `unpackaged` (the
469
+ default loader is inside, and every call above refuses on macOS) or `no-loader` (nothing in the
470
+ artifact loads the addon). It reads both latin1 and UTF-16LE, because Bun stores source text with
471
+ non-ASCII characters as UTF-16, and it does not mistake the `STITCHKIT_NATIVE_NOT_PACKAGED` error
472
+ code, which every bundle with a lock carries, for a loader. Artifacts built by 0.107.0 or earlier
473
+ carry no marker and read `no-loader`.
474
+
475
+ ```ts
476
+ import { inspectNativeArtifact } from 'stitchkit/files/packaging'
477
+
478
+ const loader = inspectNativeArtifact(await Bun.file('dist/cli').bytes())
479
+ if (loader === 'unpackaged') throw new Error('dist/cli was built without native packaging')
480
+ ```
472
481
 
473
482
  ```sh
474
483
  bun build src/native.ts --target=bun --minify --outfile=dist/native.js
@@ -548,6 +557,11 @@ addon path accepts. `entryPath` is fixed, without
548
557
  Bun naming templates such as `[dir]` or `[name]`. Companion JS builds require one entry, no splitting,
549
558
  and `naming.entry` exactly matching `entryPath`; the plugin rejects a mismatching layout.
550
559
  Choose any application layout; the framework does not prescribe an app directory or installer.
560
+ The plugin packages the loader of the installation it was created from. A build whose entry
561
+ imports another `stitchkit` installation — another version, or the same version under another
562
+ path, as when a build tool carries its own copy — fails with an error naming both versions and
563
+ roots: that installation's loader would refuse the addon at run time, so the artifact is never
564
+ written. Call `createNativePackaging` from the `stitchkit` the entry imports.
551
565
  Keep every bundler output and write `asset.bytes`; never read the addon from `node_modules` a
552
566
  second time. An installed addon whose size or SHA256 differs from the published manifest refuses
553
567
  with `mismatch` / `NATIVE_ASSET_DIGEST_MISMATCH`, so a file substituted after installation never