@forumone/throughline-workflows 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/README.md +44 -2
- package/dist/execute-scheduled-publishes.d.ts +5 -1
- package/dist/execute-scheduled-publishes.d.ts.map +1 -1
- package/dist/execute-scheduled-publishes.js +17 -3
- package/dist/execute-scheduled-publishes.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/publish-at-scheduled-time.d.ts +23 -0
- package/dist/publish-at-scheduled-time.d.ts.map +1 -0
- package/dist/publish-at-scheduled-time.js +133 -0
- package/dist/publish-at-scheduled-time.js.map +1 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @forumone/throughline-workflows
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 35060e5: Scheduled publishing works from the admin, publishes on time, and cleans up after itself.
|
|
8
|
+
|
|
9
|
+
A schedule set from the admin never published. It was written by a draft save,
|
|
10
|
+
Payload keeps a draft save in the versions table only, and the cron read the main
|
|
11
|
+
row — so only a schedule written over MCP, by a non-draft update, was ever found.
|
|
12
|
+
- **publishing**: a Schedule control replaces the scheduled-publish date field on
|
|
13
|
+
any collection that declares one, and runs the pipeline's checks when a time is
|
|
14
|
+
picked. An approval not yet granted, or an embargo that ends first, schedules
|
|
15
|
+
with a warning rather than refusing. `schedule` and `unschedule` admin
|
|
16
|
+
endpoints, `PublishingService.schedule` / `.unschedule`, and
|
|
17
|
+
`scheduleDocument` / `unscheduleDocument`; `schedule_publish` now calls the
|
|
18
|
+
service and writes the time as a draft. An `afterChange` hook sends
|
|
19
|
+
`content/page.scheduled` whenever the time changes, whichever route set it.
|
|
20
|
+
Publishing and unpublishing clear the time, so an unpublished page can no longer
|
|
21
|
+
put itself back up.
|
|
22
|
+
- **workflows**: `createPublishAtScheduledTimeFunction` sleeps until the scheduled
|
|
23
|
+
time instead of polling, in six-day hops for schedules further out.
|
|
24
|
+
`createExecuteScheduledPublishesFunction` reads the latest version
|
|
25
|
+
(`draft: true`) and takes `overdueByMs`, for running it as a backstop.
|
|
26
|
+
|
|
27
|
+
## 0.3.1
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [d02772f]
|
|
32
|
+
- @forumone/throughline-core@0.9.1
|
|
33
|
+
|
|
3
34
|
## 0.3.0
|
|
4
35
|
|
|
5
36
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@ This package has **no Payload plugin** — it exports factories only. Workflows
|
|
|
9
9
|
| Factory | What it does |
|
|
10
10
|
|---|---|
|
|
11
11
|
| `createRevalidateOnPublishFunction` | Invalidates Next.js caches for the page, listings, and sitemap when content publishes |
|
|
12
|
-
| `
|
|
12
|
+
| `createPublishAtScheduledTimeFunction` | Publishes a document at its scheduled time by sleeping until then, woken by `content/page.scheduled` |
|
|
13
|
+
| `createExecuteScheduledPublishesFunction` | Cron that publishes any document past its scheduled time — the backstop for the one above, or a poller on its own |
|
|
13
14
|
| `createExpireStaleApprovalsFunction` | Daily cron that flips pending approvals past `expiresAt` to `expired` and fires an `approval/expired` event |
|
|
14
15
|
| `createAuditEventEchoFunction` | Fan-out point: turns `audit/event.recorded` into `notification/send-approval-*` events plus custom handlers |
|
|
15
16
|
| `createHealthcheckFunction` | Periodic health monitoring with configurable checks |
|
|
@@ -93,6 +94,46 @@ createRevalidateOnPublishFunction({
|
|
|
93
94
|
|
|
94
95
|
`next` is declared as an optional peer (`peerDependenciesMeta.next.optional = true`) so non-Next consumers don't see a missing-peer warning.
|
|
95
96
|
|
|
97
|
+
## Scheduled publishing: sleep, don't poll
|
|
98
|
+
|
|
99
|
+
`createPublishAtScheduledTimeFunction` is woken by `content/page.scheduled` — which
|
|
100
|
+
the publishing plugin sends whenever a document's scheduled time changes — sleeps
|
|
101
|
+
until that time, re-reads the document, and publishes it only if the document still
|
|
102
|
+
carries that exact time. The document is the source of truth and the event is a
|
|
103
|
+
wake-up call, so a reschedule, a cancellation, or a publish or unpublish in the
|
|
104
|
+
meantime needs no cancellation event: the old run wakes, finds the time changed, and
|
|
105
|
+
ends.
|
|
106
|
+
|
|
107
|
+
It publishes on the minute and costs a few steps per schedule. The poller costs two
|
|
108
|
+
executions per tick whether or not anything is due — at `*/15` that is 5,760 a month
|
|
109
|
+
to find, almost always, nothing.
|
|
110
|
+
|
|
111
|
+
A schedule more than six days out is carried in hops: the run sleeps six days,
|
|
112
|
+
re-sends the event and ends, so no single sleep passes the seven-day cap on
|
|
113
|
+
Inngest's free plan and no run approaches its thirty-day limit. Set `maxSleepMs` on
|
|
114
|
+
a paid plan if you prefer fewer hops.
|
|
115
|
+
|
|
116
|
+
Run the poller alongside it as a backstop for an event that never arrived, on a slow
|
|
117
|
+
schedule and with `overdueByMs`, so the two never reach a just-due document in the
|
|
118
|
+
same moment:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
createPublishAtScheduledTimeFunction({ inngest, payload, collections, publish }),
|
|
122
|
+
createExecuteScheduledPublishesFunction({
|
|
123
|
+
inngest,
|
|
124
|
+
payload,
|
|
125
|
+
collections,
|
|
126
|
+
publish,
|
|
127
|
+
schedule: '17 3 * * *',
|
|
128
|
+
overdueByMs: 60 * 60 * 1000,
|
|
129
|
+
}),
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Both read the document's **latest version** (`draft: true`). A schedule is written
|
|
133
|
+
by a draft save, and Payload writes a draft save to the versions table only, so the
|
|
134
|
+
main row never carries it — and reading the versions is also what lets a revision
|
|
135
|
+
of a live document be scheduled.
|
|
136
|
+
|
|
96
137
|
## Why scheduled publishes go through the pipeline
|
|
97
138
|
|
|
98
139
|
`createExecuteScheduledPublishesFunction` never writes to Payload. It finds what is
|
|
@@ -154,7 +195,8 @@ Each handler runs in its own `step.run`, so failures isolate.
|
|
|
154
195
|
Every factory takes a typed options object. See `src/types.ts` for the full surface — defaults documented there:
|
|
155
196
|
|
|
156
197
|
- `RevalidateOnPublishOptions` — `revalidate?`, `urlBuilders?`, `collectionTags?`, `id?`
|
|
157
|
-
- `
|
|
198
|
+
- `PublishAtScheduledTimeOptions` — `collections[]`, `publish`, `maxSleepMs?` (default six days), `id?`
|
|
199
|
+
- `ExecuteScheduledPublishesOptions` — `collections[]`, `publish`, `schedule?` (default `*/5 * * * *`), `overdueByMs?` (default 0), `id?`
|
|
158
200
|
- `ExpireStaleApprovalsOptions` — `collectionSlug?` (default `approvals`), `schedule?` (default `0 2 * * *`), `id?`
|
|
159
201
|
- `AuditEventEchoOptions` — `handlers?`, `id?`
|
|
160
202
|
- `HealthcheckOptions` — `checks[]`, `schedule?` (default `*/15 * * * *`), `onFailure?`, `id?`
|
|
@@ -3,9 +3,13 @@ import type { ExecuteScheduledPublishesOptions } from './types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Cron-driven scheduled publish executor. Every tick (default: every 5
|
|
5
5
|
* minutes) the function looks for documents in any of the configured
|
|
6
|
-
* collections whose
|
|
6
|
+
* collections whose latest version is still a draft and whose
|
|
7
7
|
* `scheduledPublishAt` has passed, and calls `options.publish` for each.
|
|
8
8
|
*
|
|
9
|
+
* `createPublishAtScheduledTimeFunction` does the same job on time and without
|
|
10
|
+
* polling. Run alongside it, this is the backstop — set `overdueByMs` and a
|
|
11
|
+
* slow schedule, and it only ever finds a document whose event went missing.
|
|
12
|
+
*
|
|
9
13
|
* `publish` must go through the publishing pipeline — see the option's own
|
|
10
14
|
* documentation for the wiring. That is what makes a scheduled publish get the
|
|
11
15
|
* same composition / accessibility / approval checks as an interactive one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-scheduled-publishes.d.ts","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAA;AAWlE
|
|
1
|
+
{"version":3,"file":"execute-scheduled-publishes.d.ts","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,YAAY,CAAA;AAWlE;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,gCAAgC,GACxC,eAAe,CAAC,GAAG,CAiGrB"}
|
|
@@ -4,9 +4,13 @@ const REASONING = 'Scheduled publish executed by workflow cron';
|
|
|
4
4
|
/**
|
|
5
5
|
* Cron-driven scheduled publish executor. Every tick (default: every 5
|
|
6
6
|
* minutes) the function looks for documents in any of the configured
|
|
7
|
-
* collections whose
|
|
7
|
+
* collections whose latest version is still a draft and whose
|
|
8
8
|
* `scheduledPublishAt` has passed, and calls `options.publish` for each.
|
|
9
9
|
*
|
|
10
|
+
* `createPublishAtScheduledTimeFunction` does the same job on time and without
|
|
11
|
+
* polling. Run alongside it, this is the backstop — set `overdueByMs` and a
|
|
12
|
+
* slow schedule, and it only ever finds a document whose event went missing.
|
|
13
|
+
*
|
|
10
14
|
* `publish` must go through the publishing pipeline — see the option's own
|
|
11
15
|
* documentation for the wiring. That is what makes a scheduled publish get the
|
|
12
16
|
* same composition / accessibility / approval checks as an interactive one.
|
|
@@ -33,7 +37,7 @@ export function createExecuteScheduledPublishesFunction(options) {
|
|
|
33
37
|
...failureOptions(options, 1),
|
|
34
38
|
triggers: [{ cron: schedule }],
|
|
35
39
|
}, async ({ step, logger }) => {
|
|
36
|
-
const
|
|
40
|
+
const dueBy = new Date(Date.now() - (options.overdueByMs ?? 0)).toISOString();
|
|
37
41
|
let publishedCount = 0;
|
|
38
42
|
let blockedCount = 0;
|
|
39
43
|
for (const config of options.collections) {
|
|
@@ -46,9 +50,19 @@ export function createExecuteScheduledPublishesFunction(options) {
|
|
|
46
50
|
and: [
|
|
47
51
|
{ [statusField]: { equals: 'draft' } },
|
|
48
52
|
{ [scheduledField]: { exists: true } },
|
|
49
|
-
{ [scheduledField]: { less_than_equal:
|
|
53
|
+
{ [scheduledField]: { less_than_equal: dueBy } },
|
|
50
54
|
],
|
|
51
55
|
},
|
|
56
|
+
/*
|
|
57
|
+
The latest version, not the main row. A schedule is set by a draft
|
|
58
|
+
save, and Payload writes a draft save to the versions table alone —
|
|
59
|
+
so without this the poll read a column that the admin never wrote,
|
|
60
|
+
and only a schedule set over MCP, by a non-draft update, was ever
|
|
61
|
+
found. It is also what lets a revision of a live document be
|
|
62
|
+
scheduled: its latest version is a draft even while the main row
|
|
63
|
+
says `published`.
|
|
64
|
+
*/
|
|
65
|
+
draft: true,
|
|
52
66
|
limit: 100,
|
|
53
67
|
});
|
|
54
68
|
return result.docs.map((doc) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute-scheduled-publishes.js","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAI3C,MAAM,gBAAgB,GAAG,aAAa,CAAA;AACtC,MAAM,SAAS,GAAG,6CAA6C,CAAA;AAQ/D
|
|
1
|
+
{"version":3,"file":"execute-scheduled-publishes.js","sourceRoot":"","sources":["../src/execute-scheduled-publishes.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { createRevalidateOnPublishFunction } from './revalidate-on-publish.js';
|
|
2
2
|
export { createExecuteScheduledPublishesFunction } from './execute-scheduled-publishes.js';
|
|
3
|
+
export { createPublishAtScheduledTimeFunction } from './publish-at-scheduled-time.js';
|
|
3
4
|
export { createExpireStaleApprovalsFunction } from './expire-stale-approvals.js';
|
|
4
5
|
export { createAuditEventEchoFunction } from './audit-event-echo.js';
|
|
5
6
|
export { createHealthcheckFunction, createPayloadReachableCheck, createManifestReachableCheck, } from './healthcheck.js';
|
|
6
7
|
export { failureOptions } from './types.js';
|
|
7
|
-
export type { BaseWorkflowOptions, WorkflowFailureHandler, FailureAwareOptions, RevalidateFn, RevalidatePathsInput, RevalidateOnPublishOptions, ScheduledCollectionConfig, ExecuteScheduledPublishesOptions, ExpireStaleApprovalsOptions, AuditEchoEvent, AuditEchoHandler, AuditEventEchoOptions, HealthcheckDefinition, HealthcheckOptions, HealthcheckResult, } from './types.js';
|
|
8
|
+
export type { BaseWorkflowOptions, WorkflowFailureHandler, FailureAwareOptions, RevalidateFn, RevalidatePathsInput, RevalidateOnPublishOptions, ScheduledCollectionConfig, ExecuteScheduledPublishesOptions, PublishAtScheduledTimeOptions, ScheduledPublishRequest, ScheduledPublishResult, ExpireStaleApprovalsOptions, AuditEchoEvent, AuditEchoHandler, AuditEventEchoOptions, HealthcheckDefinition, HealthcheckOptions, HealthcheckResult, } from './types.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gCAAgC,EAChC,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,oCAAoC,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,YAAY,EACV,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,gCAAgC,EAChC,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,EACtB,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,YAAY,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Other factory exports land in subsequent commits.
|
|
2
2
|
export { createRevalidateOnPublishFunction } from './revalidate-on-publish.js';
|
|
3
3
|
export { createExecuteScheduledPublishesFunction } from './execute-scheduled-publishes.js';
|
|
4
|
+
export { createPublishAtScheduledTimeFunction } from './publish-at-scheduled-time.js';
|
|
4
5
|
export { createExpireStaleApprovalsFunction } from './expire-stale-approvals.js';
|
|
5
6
|
export { createAuditEventEchoFunction } from './audit-event-echo.js';
|
|
6
7
|
export { createHealthcheckFunction, createPayloadReachableCheck, createManifestReachableCheck, } from './healthcheck.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,oDAAoD;AAEpD,OAAO,EAAE,iCAAiC,EAAE,MAAM,4BAA4B,CAAA;AAC9E,OAAO,EAAE,uCAAuC,EAAE,MAAM,kCAAkC,CAAA;AAC1F,OAAO,EAAE,oCAAoC,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EAAE,kCAAkC,EAAE,MAAM,6BAA6B,CAAA;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAA;AACpE,OAAO,EACL,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,GAC7B,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { InngestFunction } from 'inngest';
|
|
2
|
+
import type { PublishAtScheduledTimeOptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Publishes a document at the moment it was scheduled for, by sleeping until
|
|
5
|
+
* then — rather than polling for due documents.
|
|
6
|
+
*
|
|
7
|
+
* Triggered by `content/page.scheduled`, which the publishing plugin sends
|
|
8
|
+
* whenever a document's scheduled time changes to a new value. The event is a
|
|
9
|
+
* wake-up call and nothing more: **the document is the source of truth.** On
|
|
10
|
+
* waking, the run re-reads the document's latest version and publishes only if
|
|
11
|
+
* it still carries this exact time. So a reschedule, a cancellation, a manual
|
|
12
|
+
* publish in the meantime or an unpublish — each of which changes or clears
|
|
13
|
+
* the field — leaves the old run to wake, find nothing to do, and end. No
|
|
14
|
+
* cancellation event has to arrive for that to be correct, and a duplicate
|
|
15
|
+
* event cannot publish twice (the `idempotency` key drops the second anyway).
|
|
16
|
+
*
|
|
17
|
+
* `publish` must go through the publishing pipeline, exactly as for
|
|
18
|
+
* `createExecuteScheduledPublishesFunction`: a scheduled publish gets the same
|
|
19
|
+
* composition / accessibility / approval checks as an interactive one, and a
|
|
20
|
+
* refusal is logged, not retried.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createPublishAtScheduledTimeFunction(options: PublishAtScheduledTimeOptions): InngestFunction.Any;
|
|
23
|
+
//# sourceMappingURL=publish-at-scheduled-time.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-at-scheduled-time.d.ts","sourceRoot":"","sources":["../src/publish-at-scheduled-time.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,6BAA6B,EAA6B,MAAM,YAAY,CAAA;AA8B1F;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,6BAA6B,GACrC,eAAe,CAAC,GAAG,CA4FrB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { failureOptions } from './types.js';
|
|
2
|
+
const SCHEDULED_EVENT = 'content/page.scheduled';
|
|
3
|
+
const REASONING = 'Scheduled publish executed at its scheduled time';
|
|
4
|
+
/*
|
|
5
|
+
Six days, under the seven Inngest's free plan allows a single sleep.
|
|
6
|
+
|
|
7
|
+
A schedule further out than one hop is carried by a relay: the run sleeps a
|
|
8
|
+
hop, then re-sends the event and ends, so each leg is its own run. That also
|
|
9
|
+
keeps every run far inside the free plan's thirty-day run duration, which a
|
|
10
|
+
loop of sleeps inside one run would not — a post scheduled for next quarter
|
|
11
|
+
would simply be killed.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_MAX_SLEEP_MS = 6 * 24 * 60 * 60 * 1000;
|
|
14
|
+
/**
|
|
15
|
+
* Publishes a document at the moment it was scheduled for, by sleeping until
|
|
16
|
+
* then — rather than polling for due documents.
|
|
17
|
+
*
|
|
18
|
+
* Triggered by `content/page.scheduled`, which the publishing plugin sends
|
|
19
|
+
* whenever a document's scheduled time changes to a new value. The event is a
|
|
20
|
+
* wake-up call and nothing more: **the document is the source of truth.** On
|
|
21
|
+
* waking, the run re-reads the document's latest version and publishes only if
|
|
22
|
+
* it still carries this exact time. So a reschedule, a cancellation, a manual
|
|
23
|
+
* publish in the meantime or an unpublish — each of which changes or clears
|
|
24
|
+
* the field — leaves the old run to wake, find nothing to do, and end. No
|
|
25
|
+
* cancellation event has to arrive for that to be correct, and a duplicate
|
|
26
|
+
* event cannot publish twice (the `idempotency` key drops the second anyway).
|
|
27
|
+
*
|
|
28
|
+
* `publish` must go through the publishing pipeline, exactly as for
|
|
29
|
+
* `createExecuteScheduledPublishesFunction`: a scheduled publish gets the same
|
|
30
|
+
* composition / accessibility / approval checks as an interactive one, and a
|
|
31
|
+
* refusal is logged, not retried.
|
|
32
|
+
*/
|
|
33
|
+
export function createPublishAtScheduledTimeFunction(options) {
|
|
34
|
+
const maxSleepMs = options.maxSleepMs ?? DEFAULT_MAX_SLEEP_MS;
|
|
35
|
+
const collections = new Map(options.collections.map((c) => [c.slug, c]));
|
|
36
|
+
return options.inngest.createFunction({
|
|
37
|
+
id: options.id ?? 'publish-at-scheduled-time',
|
|
38
|
+
/*
|
|
39
|
+
One run per schedule. The plugin sends once per change, but an MCP
|
|
40
|
+
schedule and the field hook seeing the same write, or a retried send,
|
|
41
|
+
would otherwise start two sleepers that both wake and both publish.
|
|
42
|
+
Inngest keeps this key for 24 hours, and a relay is six days after the
|
|
43
|
+
event that started its leg, so a relay is never mistaken for a duplicate.
|
|
44
|
+
*/
|
|
45
|
+
idempotency: 'event.data.collection + ":" + event.data.id + ":" + event.data.scheduledFor',
|
|
46
|
+
...failureOptions(options),
|
|
47
|
+
triggers: [{ event: SCHEDULED_EVENT }],
|
|
48
|
+
}, async ({ event, step, logger }) => {
|
|
49
|
+
const data = event.data;
|
|
50
|
+
const config = data.collection ? collections.get(data.collection) : undefined;
|
|
51
|
+
const target = typeof data.scheduledFor === 'string' ? Date.parse(data.scheduledFor) : NaN;
|
|
52
|
+
if (!config || !data.id || !data.scheduledFor || Number.isNaN(target)) {
|
|
53
|
+
return { outcome: 'ignored', reason: 'not a scheduled publish this function handles' };
|
|
54
|
+
}
|
|
55
|
+
const request = { collection: config.slug, id: data.id, scheduledFor: data.scheduledFor };
|
|
56
|
+
/*
|
|
57
|
+
Measured from the event's own timestamp, not the clock. Inngest replays
|
|
58
|
+
the handler from the top after every step, so a `Date.now()` here would
|
|
59
|
+
give a different answer on each replay — and flipping from the relay
|
|
60
|
+
branch to the direct branch halfway through a run is a run whose steps
|
|
61
|
+
no longer match its history.
|
|
62
|
+
*/
|
|
63
|
+
const startedAt = typeof event.ts === 'number' ? event.ts : Date.now();
|
|
64
|
+
if (target - startedAt > maxSleepMs) {
|
|
65
|
+
const hopUntil = new Date(startedAt + maxSleepMs);
|
|
66
|
+
await step.sleepUntil('wait-one-hop', hopUntil);
|
|
67
|
+
// Only relay a schedule that still stands, or a cancelled one would
|
|
68
|
+
// keep re-sending itself every six days until its date came round.
|
|
69
|
+
const current = await step.run('check-still-scheduled', () => isStillScheduled(options, config, request));
|
|
70
|
+
if (!current)
|
|
71
|
+
return { outcome: 'superseded' };
|
|
72
|
+
await step.sendEvent('relay', { name: SCHEDULED_EVENT, data: request });
|
|
73
|
+
return { outcome: 'relayed', hopUntil: hopUntil.toISOString() };
|
|
74
|
+
}
|
|
75
|
+
await step.sleepUntil('wait-until-due', new Date(target));
|
|
76
|
+
const due = await step.run('check-still-scheduled', () => isStillScheduled(options, config, request));
|
|
77
|
+
if (!due) {
|
|
78
|
+
logger.info('Scheduled publish superseded', request);
|
|
79
|
+
return { outcome: 'superseded' };
|
|
80
|
+
}
|
|
81
|
+
return step.run('publish', async () => {
|
|
82
|
+
try {
|
|
83
|
+
const result = await options.publish({
|
|
84
|
+
collection: config.slug,
|
|
85
|
+
id: request.id,
|
|
86
|
+
reasoning: REASONING,
|
|
87
|
+
});
|
|
88
|
+
if (!result.published) {
|
|
89
|
+
logger.warn('Scheduled publish blocked by policy', {
|
|
90
|
+
...request,
|
|
91
|
+
reason: result.reason,
|
|
92
|
+
});
|
|
93
|
+
return { outcome: 'blocked', reason: result.reason };
|
|
94
|
+
}
|
|
95
|
+
logger.info('Scheduled publish succeeded', request);
|
|
96
|
+
return { outcome: 'published' };
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
/*
|
|
100
|
+
Not rethrown. A retry would re-run the pipeline against the same
|
|
101
|
+
document, and the daily backstop in
|
|
102
|
+
`createExecuteScheduledPublishesFunction` already comes back for a
|
|
103
|
+
document that is still a draft past its time.
|
|
104
|
+
*/
|
|
105
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
106
|
+
logger.error('Scheduled publish threw', { ...request, error: reason });
|
|
107
|
+
return { outcome: 'error', reason };
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Whether the document's latest version still carries this schedule.
|
|
114
|
+
*
|
|
115
|
+
* `draft: true`, because a schedule is written by a draft save and Payload
|
|
116
|
+
* writes a draft save to the versions table only — the main row is not
|
|
117
|
+
* touched, so a read without it would see a document with no schedule at all.
|
|
118
|
+
*/
|
|
119
|
+
async function isStillScheduled(options, config, request) {
|
|
120
|
+
const field = config.scheduledField ?? 'scheduledPublishAt';
|
|
121
|
+
const doc = (await options.payload.findByID({
|
|
122
|
+
collection: config.slug,
|
|
123
|
+
id: request.id,
|
|
124
|
+
draft: true,
|
|
125
|
+
depth: 0,
|
|
126
|
+
disableErrors: true,
|
|
127
|
+
}));
|
|
128
|
+
const value = doc?.[field];
|
|
129
|
+
if (typeof value !== 'string')
|
|
130
|
+
return false;
|
|
131
|
+
return Date.parse(value) === Date.parse(request.scheduledFor);
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=publish-at-scheduled-time.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish-at-scheduled-time.js","sourceRoot":"","sources":["../src/publish-at-scheduled-time.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -172,9 +172,36 @@ export interface ExecuteScheduledPublishesOptions extends BaseWorkflowOptions {
|
|
|
172
172
|
* URL sat behind access protection.
|
|
173
173
|
*/
|
|
174
174
|
publish: (request: ScheduledPublishRequest) => Promise<ScheduledPublishResult>;
|
|
175
|
+
/**
|
|
176
|
+
* Leave a document alone until it is this many milliseconds past its time.
|
|
177
|
+
* Default: 0.
|
|
178
|
+
*
|
|
179
|
+
* For a host that also runs `createPublishAtScheduledTimeFunction`, which
|
|
180
|
+
* publishes on time and makes this poll a backstop for an event that never
|
|
181
|
+
* arrived. Without a grace period the two can reach the same due document in
|
|
182
|
+
* the same moment and publish it twice.
|
|
183
|
+
*/
|
|
184
|
+
overdueByMs?: number;
|
|
175
185
|
/** Override the function id. Default: `execute-scheduled-publishes`. */
|
|
176
186
|
id?: string;
|
|
177
187
|
}
|
|
188
|
+
export interface PublishAtScheduledTimeOptions extends BaseWorkflowOptions {
|
|
189
|
+
/**
|
|
190
|
+
* Collections that participate in scheduled publishing. An event naming any
|
|
191
|
+
* other collection is ignored.
|
|
192
|
+
*/
|
|
193
|
+
collections: ScheduledCollectionConfig[];
|
|
194
|
+
/** How to publish one document. The same contract, and the same warning, as `ExecuteScheduledPublishesOptions.publish`. */
|
|
195
|
+
publish: (request: ScheduledPublishRequest) => Promise<ScheduledPublishResult>;
|
|
196
|
+
/**
|
|
197
|
+
* The longest single sleep, in milliseconds. A schedule further out is
|
|
198
|
+
* reached by relaying the event. Default: six days — Inngest's free plan caps
|
|
199
|
+
* a sleep at seven.
|
|
200
|
+
*/
|
|
201
|
+
maxSleepMs?: number;
|
|
202
|
+
/** Override the function id. Default: `publish-at-scheduled-time`. */
|
|
203
|
+
id?: string;
|
|
204
|
+
}
|
|
178
205
|
export interface ExpireStaleApprovalsOptions extends BaseWorkflowOptions {
|
|
179
206
|
/** Approvals collection slug. Default: 'approvals'. */
|
|
180
207
|
collectionSlug?: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forumone/throughline-workflows",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Composable Inngest function factories for the Throughline framework — revalidation, scheduled publishing, approval expiration, audit fan-out, healthcheck.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,11 +46,11 @@
|
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@forumone/throughline-core": "0.9.
|
|
49
|
+
"@forumone/throughline-core": "0.9.1"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/node": "^24.13.2",
|
|
53
|
-
"eslint": "^
|
|
53
|
+
"eslint": "^10.11.0",
|
|
54
54
|
"inngest": "^4.2.0",
|
|
55
55
|
"next": "^16.2.4",
|
|
56
56
|
"payload": "^3.83.0",
|