Tactical Media Broadcast Hub — initial release
Self-hosted multi-platform broadcast newsroom for activist collectives: publishing pipeline with group approval and DST-proof scheduling, TweetDeck-style column wall with hostile-content-safe rendering, live control room with Auto Director, bridged chat governance with polls and quorum, distributed sandboxed transcode workers, encrypted content-addressed archive, monthly analytics. MIT licensed. See README.md and docs/.
This commit is contained in:
commit
aa5e262f3a
880 changed files with 111042 additions and 0 deletions
58
packages/scheduling/src/index.ts
Normal file
58
packages/scheduling/src/index.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @tactical-media-broadcast-hub/scheduling — shared schedule time semantics (WP3, reused by WP13).
|
||||
*
|
||||
* A schedule is a five-field cron expression plus an explicit IANA timezone
|
||||
* (never server-local; UTC allowed). Occurrences are evaluated in that zone as
|
||||
* nominal local times, then materialized to UTC fire instants. The occurrence
|
||||
* key is the materialized UTC instant, so `UNIQUE (workspace_id, schedule_id,
|
||||
* fire_at_utc)` holds by construction.
|
||||
*
|
||||
* - DST gap: a nonexistent local time fires at the first valid instant after
|
||||
* the gap (shift forward).
|
||||
* - DST fold: an ambiguous local time fires once, at its earlier instant.
|
||||
* - Collapse: several nominal local times mapping onto one post-gap instant
|
||||
* yield exactly one occurrence.
|
||||
* - Re-materialization on tzdata/timezone change deletes unclaimed future
|
||||
* occurrences and regenerates only strictly-later slots, never refiring a
|
||||
* slot already fired under the old zone.
|
||||
*
|
||||
* Pure functions only: no app, DB or Temporal imports.
|
||||
*/
|
||||
export {
|
||||
SchedulingError,
|
||||
InvalidCronError,
|
||||
InvalidTimezoneError,
|
||||
InvalidNominalLocalError,
|
||||
InvalidInstantError,
|
||||
ImpossibleScheduleError,
|
||||
} from "./errors.js";
|
||||
export {
|
||||
canonicalTimezone,
|
||||
isValidTimezone,
|
||||
assertValidTimezone,
|
||||
wallOfInstant,
|
||||
offsetMs,
|
||||
toInstantMs,
|
||||
currentTzdataVersion,
|
||||
epochOfWall,
|
||||
} from "./timezone.js";
|
||||
export type { WallClock, NominalLocal } from "./timezone.js";
|
||||
export { parseCron, cronMatchesDay, cronMatchesTime, FIELD_NAMES } from "./cron.js";
|
||||
export type { ParsedCron, CronField } from "./cron.js";
|
||||
export { formatNominal, parseNominal, compareWall, wallEquals, wallAsEpochMs } from "./nominal.js";
|
||||
export { resolveWallToInstant } from "./materialize.js";
|
||||
export { materializeOccurrence } from "./materialize-api.js";
|
||||
export {
|
||||
prepareSchedule,
|
||||
sortedHours,
|
||||
sortedMinutes,
|
||||
slotNominal,
|
||||
matchingLocalDays,
|
||||
stepOneLocalDay,
|
||||
} from "./schedule.js";
|
||||
export type { ScheduleSpec, Occurrence, PreparedSchedule } from "./schedule.js";
|
||||
export { nextOccurrencesPrepared } from "./occurrences.js";
|
||||
export type { NextOccurrencesOptions } from "./occurrences.js";
|
||||
export { nextOccurrences, materializeOccurrences } from "./occurrences_extra.js";
|
||||
export { rematerialize } from "./rematerialize.js";
|
||||
export type { StoredOccurrence, RematerializeOptions, RematerializeResult } from "./rematerialize.js";
|
||||
Loading…
Add table
Add a link
Reference in a new issue