@molecule/api-deploy-rollout 0.0.0-stage → 0.0.1-stage

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,519 @@
1
- # Temporary Holding Version
1
+ <!--
2
+ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
+ Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
+ Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
+ To change this document, edit the module-level JSDoc in src/index.ts.
6
+ Generated: 2026-10-19T18:03:27.132Z
7
+ -->
2
8
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
9
+ # @molecule/api-deploy-rollout
10
+
11
+ Deploy-rollout core interface for molecule.dev.
12
+
13
+ Replaces the running instances of a deployment with new ones without taking the
14
+ deployment down — grow-then-shrink (create the new set, gate it ready, join it,
15
+ then retire the old one at a time) and in-place (change the same instances one at
16
+ a time, with a restore path). The package carries the contract only:
17
+ `@molecule/api-deploy-rollout-default` is the algorithm, `-fly` and `-sandbox`
18
+ adapt concrete instance providers.
19
+
20
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
21
+ > It is written to be read by coding agents as much as by people, and is generated from this
22
+ > package's source — edit `src/index.ts` JSDoc, not this file.
23
+
24
+ ## Quick Start
25
+
26
+ ```typescript
27
+ import { setProvider, runRollout } from '@molecule/api-deploy-rollout'
28
+ import { provider } from '@molecule/api-deploy-rollout-default'
29
+
30
+ setProvider(provider)
31
+
32
+ const outcome = await runRollout({
33
+ provider: myInstanceProvider,
34
+ current: oldInstances,
35
+ policy: { replicas: 2, soakMs: 30_000, drainMs: 25_000 },
36
+ })
37
+ // outcome.status === 'completed' when the new set is serving
38
+ ```
39
+
40
+ ## Type
41
+
42
+ `core`
43
+
44
+ ## Installation
45
+
46
+ ```bash
47
+ npm install @molecule/api-deploy-rollout @molecule/api-bond
48
+ ```
49
+
50
+ ## API
51
+
52
+ ### Interfaces
53
+
54
+ #### `RolloutInstance`
55
+
56
+ One instance a rollout can act on.
57
+
58
+ `id` is the provider's stable handle. `upstreamUrl` is the routable address the
59
+ deployment's edge dials, when the provider has one — a rollout that only
60
+ restarts instances in place does not need it.
61
+
62
+ ```typescript
63
+ interface RolloutInstance {
64
+ /** Provider instance id. */
65
+ id: string
66
+ /** The routable upstream URL, when the provider exposes one. */
67
+ upstreamUrl?: string
68
+ }
69
+ ```
70
+
71
+ #### `InstanceProvider`
72
+
73
+ What a grow-then-shrink rollout needs from whatever hosts the instances.
74
+
75
+ The caller implements this over its hosting provider; the `-sandbox` bond does it
76
+ over `@molecule/api-code-sandbox`, and tests drive it with a fake that records the
77
+ order and can fail any step.
78
+
79
+ ```typescript
80
+ interface InstanceProvider<I extends RolloutInstance = RolloutInstance> {
81
+ /** A human-readable provider name, for progress lines. */
82
+ readonly name?: string
83
+
84
+ /**
85
+ * Every instance the deployment currently owns, when the provider can enumerate
86
+ * them. Used to resume an interrupted rollout idempotently: an instance already
87
+ * ready and joined is not created twice.
88
+ */
89
+ list?(): Promise<I[]>
90
+
91
+ /**
92
+ * Create the instance at `index` (0-based, above any primary the caller created
93
+ * itself). It must not be routable until {@link InstanceProvider.join}.
94
+ *
95
+ * @param index - Which instance this is.
96
+ * @returns The created instance.
97
+ */
98
+ create(index: number): Promise<I>
99
+
100
+ /**
101
+ * Resolve once the instance may take traffic.
102
+ *
103
+ * @param instance - The instance to gate.
104
+ * @param timeoutMs - The policy's readiness budget, for providers whose probe
105
+ * accepts one.
106
+ * @returns `false` when it never became ready (the rollout aborts).
107
+ */
108
+ waitReady(instance: I, timeoutMs?: number): Promise<boolean>
109
+
110
+ /**
111
+ * A single, fast readiness probe, for the soak window. Optional: a caller that
112
+ * sets `soakMs` must provide it, because a blocking readiness wait cannot tell a
113
+ * warm instance from a recovering one.
114
+ *
115
+ * @param instance - The instance to probe.
116
+ * @returns Whether it is serving right now.
117
+ */
118
+ isServing?(instance: I): Promise<boolean>
119
+
120
+ /**
121
+ * Add the instance to the routable set, so the edge may send it new requests.
122
+ *
123
+ * @param instance - A ready instance.
124
+ */
125
+ join(instance: I): Promise<void>
126
+
127
+ /**
128
+ * Remove the instance from the routable set, so no NEW request is routed to it.
129
+ * Requests already in flight are untouched.
130
+ *
131
+ * @param instance - The instance being retired.
132
+ */
133
+ leave(instance: I): Promise<void>
134
+
135
+ /**
136
+ * Tell the instance to drain: finish in-flight work and stop accepting new
137
+ * connections. Resolve when it may be destroyed, and never later than `drainMs`.
138
+ *
139
+ * @param instance - The retired instance.
140
+ * @param drainMs - The bounded wait.
141
+ */
142
+ drain(instance: I, drainMs: number): Promise<void>
143
+
144
+ /**
145
+ * Destroy the instance, releasing whatever it costs.
146
+ *
147
+ * @param instance - The instance to remove.
148
+ */
149
+ destroy(instance: I): Promise<void>
150
+ }
151
+ ```
152
+
153
+ #### `InPlaceInstanceProvider`
154
+
155
+ What an in-place rollout needs from whatever hosts the instances.
156
+
157
+ Every instance keeps its identity; `replace` changes it to the new build and
158
+ `restore` puts it back on the old one. The caller supplies {@link list} so a
159
+ resumed rollout can see what is already there.
160
+
161
+ ```typescript
162
+ interface InPlaceInstanceProvider<I extends RolloutInstance = RolloutInstance> {
163
+ /** A human-readable provider name, for progress lines. */
164
+ readonly name?: string
165
+
166
+ /**
167
+ * Every instance the rollout may act on, in roll order.
168
+ *
169
+ * @returns The instances.
170
+ */
171
+ list(): Promise<I[]>
172
+
173
+ /**
174
+ * Whether the instance is serving requests right now.
175
+ *
176
+ * @param instance - The instance to probe.
177
+ * @returns `true` while it answers its readiness probe.
178
+ */
179
+ isServing(instance: I): Promise<boolean>
180
+
181
+ /**
182
+ * Change the instance to the new build and leave it serving.
183
+ *
184
+ * @param instance - The instance to change.
185
+ */
186
+ replace(instance: I): Promise<void>
187
+
188
+ /**
189
+ * Put the instance back on the old build. Called only for instances this run
190
+ * already replaced.
191
+ *
192
+ * @param instance - The instance to restore.
193
+ */
194
+ restore(instance: I): Promise<void>
195
+ }
196
+ ```
197
+
198
+ #### `RolloutPolicy`
199
+
200
+ How a rollout bounds itself.
201
+
202
+ Every field is optional on the caller's side; the bond fills in the defaults
203
+ documented here.
204
+
205
+ ```typescript
206
+ interface RolloutPolicy {
207
+ /**
208
+ * How many instances the NEW set holds, for a grow-then-shrink rollout. The
209
+ * caller's own primary instance is not created here, so the bond creates
210
+ * `replicas - 1`. Defaults to `current.length` (a like-for-like replacement).
211
+ */
212
+ replicas?: number
213
+
214
+ /**
215
+ * The most instances that may be unavailable at once. When set, the bond derives
216
+ * `minHealthy = max(1, instances - maxUnavailable)` and refuses a step that would
217
+ * go below it. Default: `minHealthy` is 1 — never blank the deployment.
218
+ */
219
+ maxUnavailable?: number
220
+
221
+ /**
222
+ * An absolute floor on healthy instances. Overrides the value derived from
223
+ * {@link RolloutPolicy.maxUnavailable}. Defaults to 1.
224
+ */
225
+ minHealthy?: number
226
+
227
+ /**
228
+ * How long a changed instance must keep answering without a gap before the next
229
+ * step starts. Passing one probe is not proof of a warm instance; a gap restarts
230
+ * the window. Defaults to 0 (no soak).
231
+ */
232
+ soakMs?: number
233
+
234
+ /** Probe cadence during the soak. Defaults to 2000 ms. */
235
+ soakProbeMs?: number
236
+
237
+ /**
238
+ * How long the soak may keep retrying before the rollout aborts. Defaults to
239
+ * `soakMs + 60 s`.
240
+ */
241
+ soakGraceMs?: number
242
+
243
+ /** How long a retired instance may take to drain. Defaults to 25 s. */
244
+ drainMs?: number
245
+
246
+ /** The readiness budget handed to `waitReady`. Defaults to 120 s. */
247
+ readinessTimeoutMs?: number
248
+
249
+ /**
250
+ * What an abort does to instances this run already changed: `reverse` restores
251
+ * them newest first (the default), `none` leaves them as they are.
252
+ */
253
+ rollback?: 'reverse' | 'none'
254
+
255
+ /**
256
+ * Whether a rollout reconciles against the provider's current instances instead
257
+ * of starting from the caller's list. Defaults to true; a provider without
258
+ * `list()` falls back to the caller's list.
259
+ */
260
+ resume?: boolean
261
+ }
262
+ ```
263
+
264
+ #### `RolloutFailure`
265
+
266
+ A step that failed but did not stop the rollout (a retirement or rollback step).
267
+
268
+ ```typescript
269
+ interface RolloutFailure<I extends RolloutInstance = RolloutInstance> {
270
+ /** The instance the step addressed. */
271
+ instance: I
272
+ /** The step that failed. */
273
+ step: RolloutStep
274
+ /** Whatever was thrown, for the caller's log. */
275
+ error: unknown
276
+ }
277
+ ```
278
+
279
+ #### `RolloutOutcome`
280
+
281
+ What a completed or aborted rollout did.
282
+
283
+ ```typescript
284
+ interface RolloutOutcome<I extends RolloutInstance = RolloutInstance> {
285
+ /** `completed` when the target set is serving; `aborted` otherwise. */
286
+ status: 'completed' | 'aborted'
287
+ /** Every instance this run created and joined, in creation order. */
288
+ created: I[]
289
+ /** Every new instance that is healthy and joined. */
290
+ upstreams: I[]
291
+ /** Old instances this run removed from the set and destroyed. */
292
+ retired: I[]
293
+ /** Steps that failed but did not stop the rollout. */
294
+ failures: RolloutFailure<I>[]
295
+ /** Instances this run restored, newest first (an in-place abort). */
296
+ rolledBack: string[]
297
+ /** Restores that themselves failed. */
298
+ rollbackFailures: RolloutFailure<I>[]
299
+ }
300
+ ```
301
+
302
+ #### `InPlaceRolloutOutcome`
303
+
304
+ What an in-place rollout did.
305
+
306
+ ```typescript
307
+ interface InPlaceRolloutOutcome<I extends RolloutInstance = RolloutInstance> {
308
+ /** The instances changed successfully, in roll order. */
309
+ applied: string[]
310
+ /** Every instance that passed its gate. */
311
+ instances: I[]
312
+ }
313
+ ```
314
+
315
+ #### `RolloutOptions`
316
+
317
+ What {@link InstanceProvider} needs for one grow-then-shrink rollout.
318
+
319
+ ```typescript
320
+ interface RolloutOptions<I extends RolloutInstance = RolloutInstance> {
321
+ /** The instance provider. */
322
+ provider: InstanceProvider<I>
323
+ /** The instances serving right now (empty on a first deploy). */
324
+ current?: readonly I[]
325
+ /** Rollout bounds; the bond fills the defaults. */
326
+ policy?: RolloutPolicy
327
+ /** Optional progress sink — plain sentences. */
328
+ log?: (line: string) => Promise<void> | void
329
+ /** Consulted between steps; `true` aborts and keeps the old set serving. */
330
+ isCancelled?: () => Promise<boolean> | boolean
331
+ /**
332
+ * Set when the caller has already created and joined ONE instance of the new
333
+ * set (the primary), outside this rollout. It counts toward healthy capacity.
334
+ */
335
+ primaryServing?: boolean
336
+ /** Injectable clock, for tests. Defaults to `Date.now`. */
337
+ now?: () => number
338
+ /** Injectable sleep, for tests. Defaults to a real timer. */
339
+ sleep?: (ms: number) => Promise<void>
340
+ }
341
+ ```
342
+
343
+ #### `DeployRolloutProvider`
344
+
345
+ The contract every deploy-rollout bond implements.
346
+
347
+ The two methods are the two real deployment topologies; a bond that supports
348
+ only one rejects the other with a clear error rather than silently doing
349
+ nothing.
350
+
351
+ ```typescript
352
+ interface DeployRolloutProvider {
353
+ /** A human-readable provider name, for diagnostics. */
354
+ readonly name: string
355
+
356
+ /**
357
+ * Run a grow-then-shrink replacement of a deployment's instances.
358
+ *
359
+ * @param options - The set to build, the old set, and the instance provider.
360
+ * @returns What the rollout did.
361
+ */
362
+ run<I extends RolloutInstance>(options: RolloutOptions<I>): Promise<RolloutOutcome<I>>
363
+
364
+ /**
365
+ * Run an in-place replacement (the same instances changed one at a time).
366
+ *
367
+ * @param options - The instances to roll and the provider or callbacks.
368
+ * @returns What the rollout did.
369
+ */
370
+ runInPlace<I extends RolloutInstance>(
371
+ options: InPlaceRolloutOptions<I>,
372
+ ): Promise<InPlaceRolloutOutcome<I>>
373
+ }
374
+ ```
375
+
376
+ #### `InPlaceRolloutOptions`
377
+
378
+ What an in-place rollout needs.
379
+
380
+ ```typescript
381
+ interface InPlaceRolloutOptions<I extends RolloutInstance = RolloutInstance> {
382
+ /**
383
+ * The instances to roll. When absent, the provider's own list is used.
384
+ */
385
+ machines?: readonly I[]
386
+ /**
387
+ * A provider that owns the operations. Alternatively pass `apply`/`rollback`/
388
+ * `probeServing` directly; the provider is a convenience for callers that
389
+ * already model their hosting this way.
390
+ */
391
+ provider?: InPlaceInstanceProvider<I>
392
+ /** Change one instance and leave it serving on the NEW build. */
393
+ apply?: (instance: I) => Promise<void>
394
+ /** Put one instance back on the OLD build. */
395
+ rollback?: (instance: I) => Promise<void>
396
+ /** Whether an instance is serving right now. */
397
+ probeServing?: (instanceId: string) => Promise<boolean>
398
+ /** Rollout bounds; the bond fills the defaults. */
399
+ policy?: RolloutPolicy
400
+ /** Pause between instances. Defaults to 0. */
401
+ betweenMs?: number
402
+ /** Optional progress sink — plain sentences. */
403
+ log?: (line: string) => Promise<void> | void
404
+ /** Consulted before each instance; `true` aborts and rolls back. */
405
+ isCancelled?: () => Promise<boolean> | boolean
406
+ /** Injectable clock, for tests. Defaults to `Date.now`. */
407
+ now?: () => number
408
+ /** Injectable sleep, for tests. Defaults to a real timer. */
409
+ sleep?: (ms: number) => Promise<void>
410
+ }
411
+ ```
412
+
413
+ ### Types
414
+
415
+ #### `RolloutStep`
416
+
417
+ The step of a rollout that produced a result or a failure.
418
+
419
+ ```typescript
420
+ type RolloutStep =
421
+ | 'create'
422
+ | 'ready'
423
+ | 'join'
424
+ | 'leave'
425
+ | 'drain'
426
+ | 'destroy'
427
+ | 'replace'
428
+ | 'restore'
429
+ | 'capacity'
430
+ | 'cancelled'
431
+ ```
432
+
433
+ ### Functions
434
+
435
+ #### `setProvider(provider)`
436
+
437
+ Registers a deploy-rollout provider as the active singleton. Called by a bond
438
+ package during application startup.
439
+
440
+ ```typescript
441
+ function setProvider(provider: DeployRolloutProvider): void
442
+ ```
443
+
444
+ - `provider` — The provider implementation to bond.
445
+
446
+ #### `getProvider()`
447
+
448
+ Retrieves the bonded deploy-rollout provider, throwing if none is wired.
449
+
450
+ ```typescript
451
+ function getProvider(): DeployRolloutProvider
452
+ ```
453
+
454
+ **Returns:** The bonded provider.
455
+
456
+ #### `hasProvider()`
457
+
458
+ Checks whether a deploy-rollout provider is currently bonded.
459
+
460
+ ```typescript
461
+ function hasProvider(): boolean
462
+ ```
463
+
464
+ **Returns:** `true` if a provider is bonded.
465
+
466
+ #### `runRollout(options)`
467
+
468
+ Runs a grow-then-shrink rollout through the bonded provider.
469
+
470
+ ```typescript
471
+ function runRollout(options: RolloutOptions<I>): Promise<RolloutOutcome<I>>
472
+ ```
473
+
474
+ - `options` — The set to build, the old set, and the instance provider.
475
+
476
+ **Returns:** What the rollout did.
477
+
478
+ #### `runInPlaceRollout(options)`
479
+
480
+ Runs an in-place rollout (the same instances changed one at a time) through the
481
+ bonded provider.
482
+
483
+ ```typescript
484
+ function runInPlaceRollout(options: InPlaceRolloutOptions<I>): Promise<InPlaceRolloutOutcome<I>>
485
+ ```
486
+
487
+ - `options` — The instances to roll and the provider or callbacks.
488
+
489
+ **Returns:** What the rollout did.
490
+
491
+ ## Available Providers
492
+
493
+ | Provider | Package |
494
+ | ------------ | -------------------------------------- |
495
+ | Default | `@molecule/api-deploy-rollout-default` |
496
+ | Fly Machines | `@molecule/api-deploy-rollout-fly` |
497
+ | Sandbox | `@molecule/api-deploy-rollout-sandbox` |
498
+
499
+ ## Injection Notes
500
+
501
+ ### Requirements
502
+
503
+ Peer dependencies:
504
+
505
+ - `@molecule/api-bond` ^1.0.1
506
+
507
+ ### Runtime Dependencies
508
+
509
+ - `@molecule/api-bond`
510
+
511
+ - **The core has no implementation.** The state machine, the soak, the capacity
512
+ floor and the reverse rollback live in a bond, so a caller can swap in a
513
+ provider whose rules differ without touching its own code.
514
+ - **Never reduces healthy capacity below the floor.** A step that would leave
515
+ fewer healthy instances than the policy allows is refused, not attempted.
516
+ - **An abort keeps the old set serving.** Every instance created or changed by
517
+ the run is undone, newest first, before the error is thrown.
518
+ - **Idempotent resume.** Re-running a rollout after an interruption reconciles
519
+ against the provider's current instances instead of creating duplicates.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=browser-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-guard.d.ts","sourceRoot":"","sources":["../src/browser-guard.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,CAAA"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Browser guard — `@molecule/api-deploy-rollout` is SERVER-ONLY.
3
+ *
4
+ * Generated by scripts/gen-browser-guards.mjs (workspace root) — edit THAT, not this.
5
+ * Evaluating a server package in a browser bundle is always an import-graph mistake
6
+ * (node APIs, secrets); without this guard it surfaces as a cryptic downstream crash
7
+ * ("Buffer is not defined") far from the culprit. Throwing here names the package and
8
+ * the fix at the exact moment the client bundle evaluates it. jsdom tests and SSR are
9
+ * unaffected: the throw requires browser globals AND the absence of a node runtime.
10
+ */
11
+ const g = globalThis;
12
+ if (g.window !== undefined && g.document !== undefined && !g.process?.versions?.node) {
13
+ throw new Error('@molecule/api-deploy-rollout is SERVER-ONLY: it was bundled into browser/client code. Import it only ' +
14
+ 'from server code (a server route/function or your API), or dynamic-import it inside ' +
15
+ 'the server handler — never from components or shared client modules, and never ' +
16
+ 'polyfill Buffer/process to silence this.');
17
+ }
18
+ export {};
19
+ //# sourceMappingURL=browser-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-guard.js","sourceRoot":"","sources":["../src/browser-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,GAAG,UAIT,CAAA;AACD,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACrF,MAAM,IAAI,KAAK,CACb,uGAAuG;QACrG,sFAAsF;QACtF,iFAAiF;QACjF,0CAA0C,CAC7C,CAAA;AACH,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Deploy-rollout core interface for molecule.dev.
3
+ *
4
+ * Replaces the running instances of a deployment with new ones without taking the
5
+ * deployment down — grow-then-shrink (create the new set, gate it ready, join it,
6
+ * then retire the old one at a time) and in-place (change the same instances one at
7
+ * a time, with a restore path). The package carries the contract only:
8
+ * `@molecule/api-deploy-rollout-default` is the algorithm, `-fly` and `-sandbox`
9
+ * adapt concrete instance providers.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { setProvider, runRollout } from '@molecule/api-deploy-rollout'
14
+ * import { provider } from '@molecule/api-deploy-rollout-default'
15
+ *
16
+ * setProvider(provider)
17
+ *
18
+ * const outcome = await runRollout({
19
+ * provider: myInstanceProvider,
20
+ * current: oldInstances,
21
+ * policy: { replicas: 2, soakMs: 30_000, drainMs: 25_000 },
22
+ * })
23
+ * // outcome.status === 'completed' when the new set is serving
24
+ * ```
25
+ *
26
+ * @remarks
27
+ * - **The core has no implementation.** The state machine, the soak, the capacity
28
+ * floor and the reverse rollback live in a bond, so a caller can swap in a
29
+ * provider whose rules differ without touching its own code.
30
+ * - **Never reduces healthy capacity below the floor.** A step that would leave
31
+ * fewer healthy instances than the policy allows is refused, not attempted.
32
+ * - **An abort keeps the old set serving.** Every instance created or changed by
33
+ * the run is undone, newest first, before the error is thrown.
34
+ * - **Idempotent resume.** Re-running a rollout after an interruption reconciles
35
+ * against the provider's current instances instead of creating duplicates.
36
+ *
37
+ * @module
38
+ */
39
+ export * from './browser-guard.js';
40
+ export * from './provider.js';
41
+ export * from './types.js';
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Deploy-rollout core interface for molecule.dev.
3
+ *
4
+ * Replaces the running instances of a deployment with new ones without taking the
5
+ * deployment down — grow-then-shrink (create the new set, gate it ready, join it,
6
+ * then retire the old one at a time) and in-place (change the same instances one at
7
+ * a time, with a restore path). The package carries the contract only:
8
+ * `@molecule/api-deploy-rollout-default` is the algorithm, `-fly` and `-sandbox`
9
+ * adapt concrete instance providers.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { setProvider, runRollout } from '@molecule/api-deploy-rollout'
14
+ * import { provider } from '@molecule/api-deploy-rollout-default'
15
+ *
16
+ * setProvider(provider)
17
+ *
18
+ * const outcome = await runRollout({
19
+ * provider: myInstanceProvider,
20
+ * current: oldInstances,
21
+ * policy: { replicas: 2, soakMs: 30_000, drainMs: 25_000 },
22
+ * })
23
+ * // outcome.status === 'completed' when the new set is serving
24
+ * ```
25
+ *
26
+ * @remarks
27
+ * - **The core has no implementation.** The state machine, the soak, the capacity
28
+ * floor and the reverse rollback live in a bond, so a caller can swap in a
29
+ * provider whose rules differ without touching its own code.
30
+ * - **Never reduces healthy capacity below the floor.** A step that would leave
31
+ * fewer healthy instances than the policy allows is refused, not attempted.
32
+ * - **An abort keeps the old set serving.** Every instance created or changed by
33
+ * the run is undone, newest first, before the error is thrown.
34
+ * - **Idempotent resume.** Re-running a rollout after an interruption reconciles
35
+ * against the provider's current instances instead of creating duplicates.
36
+ *
37
+ * @module
38
+ */
39
+ export * from './browser-guard.js';
40
+ export * from './provider.js';
41
+ export * from './types.js';
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,cAAc,oBAAoB,CAAA;AAClC,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Accessors for the bonded deploy-rollout provider.
3
+ *
4
+ * A provider bond (e.g. `@molecule/api-deploy-rollout-default`) calls
5
+ * `setProvider()` during application startup. Application code uses the
6
+ * convenience accessors (`runRollout`, `runInPlaceRollout`), which delegate to the
7
+ * bonded provider, so the hosting-specific algorithm is a wiring decision rather
8
+ * than an import.
9
+ *
10
+ * @module
11
+ */
12
+ import type { DeployRolloutProvider, InPlaceRolloutOptions, InPlaceRolloutOutcome, RolloutInstance, RolloutOptions, RolloutOutcome } from './types.js';
13
+ /**
14
+ * Registers a deploy-rollout provider as the active singleton. Called by a bond
15
+ * package during application startup.
16
+ *
17
+ * @param provider - The provider implementation to bond.
18
+ */
19
+ export declare const setProvider: (provider: DeployRolloutProvider) => void;
20
+ /**
21
+ * Retrieves the bonded deploy-rollout provider, throwing if none is wired.
22
+ *
23
+ * @returns The bonded provider.
24
+ * @throws {Error} If no deploy-rollout provider has been bonded.
25
+ */
26
+ export declare const getProvider: () => DeployRolloutProvider;
27
+ /**
28
+ * Checks whether a deploy-rollout provider is currently bonded.
29
+ *
30
+ * @returns `true` if a provider is bonded.
31
+ */
32
+ export declare const hasProvider: () => boolean;
33
+ /**
34
+ * Runs a grow-then-shrink rollout through the bonded provider.
35
+ *
36
+ * @param options - The set to build, the old set, and the instance provider.
37
+ * @returns What the rollout did.
38
+ */
39
+ export declare const runRollout: <I extends RolloutInstance>(options: RolloutOptions<I>) => Promise<RolloutOutcome<I>>;
40
+ /**
41
+ * Runs an in-place rollout (the same instances changed one at a time) through the
42
+ * bonded provider.
43
+ *
44
+ * @param options - The instances to roll and the provider or callbacks.
45
+ * @returns What the rollout did.
46
+ */
47
+ export declare const runInPlaceRollout: <I extends RolloutInstance>(options: InPlaceRolloutOptions<I>) => Promise<InPlaceRolloutOutcome<I>>;
48
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,cAAc,EACf,MAAM,YAAY,CAAA;AAInB;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,UAAU,qBAAqB,KAAG,IAE7D,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,QAAO,qBAS9B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,QAAO,OAE9B,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,eAAe,EAClD,SAAS,cAAc,CAAC,CAAC,CAAC,KACzB,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAE3B,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,CAAC,SAAS,eAAe,EACzD,SAAS,qBAAqB,CAAC,CAAC,CAAC,KAChC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAElC,CAAA"}