@pylonsync/sdk 0.3.288 → 0.3.290
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/package.json +1 -1
- package/src/index.ts +62 -0
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -650,6 +650,21 @@ export interface ManifestPolicy {
|
|
|
650
650
|
|
|
651
651
|
export const MANIFEST_VERSION = 1;
|
|
652
652
|
|
|
653
|
+
/** A recurring job: run a function on a cron schedule. Declared in the
|
|
654
|
+
* manifest via `cron(schedule, functionName)`; the runtime fires the named
|
|
655
|
+
* function with anonymous auth every time the schedule matches. Server-side
|
|
656
|
+
* `ctx.db.*` is trusted, so a maintenance handler reads/writes its entities
|
|
657
|
+
* directly without elevating. */
|
|
658
|
+
export interface ManifestCron {
|
|
659
|
+
/** Standard 5-field cron expression, e.g. `"0 * * * *"` (every hour). */
|
|
660
|
+
schedule: string;
|
|
661
|
+
/** Name of the function (query/mutation/action) to run. Should be an
|
|
662
|
+
* `internal: true` function so it isn't also reachable over HTTP. */
|
|
663
|
+
function: string;
|
|
664
|
+
/** Optional human description, surfaced by `pylon status` / tooling. */
|
|
665
|
+
description?: string;
|
|
666
|
+
}
|
|
667
|
+
|
|
653
668
|
export interface AppManifest {
|
|
654
669
|
manifest_version: number;
|
|
655
670
|
name: string;
|
|
@@ -665,6 +680,49 @@ export interface AppManifest {
|
|
|
665
680
|
/** Declared OAuth integrations. Auto-creates the `_Connection`
|
|
666
681
|
* entity at runtime boot. */
|
|
667
682
|
connections?: ManifestConnection[];
|
|
683
|
+
/** Recurring jobs — run a function on a cron schedule. */
|
|
684
|
+
crons?: ManifestCron[];
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Declare a recurring job. Runs the named function every time the cron
|
|
689
|
+
* `schedule` matches (the runtime checks once a minute).
|
|
690
|
+
*
|
|
691
|
+
* ```ts
|
|
692
|
+
* buildManifest({
|
|
693
|
+
* // ...
|
|
694
|
+
* crons: [
|
|
695
|
+
* cron("0 * * * *", "hourlyRollup"), // every hour, on the hour
|
|
696
|
+
* cron("15 3 * * *", "nightlyCleanup"), // daily at 03:15
|
|
697
|
+
* ],
|
|
698
|
+
* });
|
|
699
|
+
* ```
|
|
700
|
+
*
|
|
701
|
+
* `functionName` is a function in `functions/` — make it `internal: true`
|
|
702
|
+
* so it isn't also exposed over HTTP. It runs with anonymous auth, and a
|
|
703
|
+
* function's own `ctx.db.*` calls are server-side (not policy-gated), so a
|
|
704
|
+
* maintenance handler writes directly. Only call
|
|
705
|
+
* `ctx.auth.elevate({ admin: true, reason: "..." })` if it chains an
|
|
706
|
+
* `internal: true` function via `ctx.scheduler`, or you run with
|
|
707
|
+
* `PYLON_STRICT_FN_POLICIES=1`. The `reason` is mandatory (audited).
|
|
708
|
+
*
|
|
709
|
+
* Multiple replicas: each Pylon process runs its own scheduler. On a SHARED
|
|
710
|
+
* datastore (Postgres — the cloud default), the runtime takes a per-minute
|
|
711
|
+
* lease so each cron fires exactly ONCE per tick across all replicas. On
|
|
712
|
+
* per-replica SQLite there's no shared lease, so each replica fires — keep
|
|
713
|
+
* handlers idempotent there (most maintenance work naturally is). A
|
|
714
|
+
* single-machine app always fires exactly once.
|
|
715
|
+
*/
|
|
716
|
+
export function cron(
|
|
717
|
+
schedule: string,
|
|
718
|
+
functionName: string,
|
|
719
|
+
opts?: { description?: string }
|
|
720
|
+
): ManifestCron {
|
|
721
|
+
return {
|
|
722
|
+
schedule,
|
|
723
|
+
function: functionName,
|
|
724
|
+
...(opts?.description ? { description: opts.description } : {}),
|
|
725
|
+
};
|
|
668
726
|
}
|
|
669
727
|
|
|
670
728
|
export function entitiesToManifest(
|
|
@@ -1352,6 +1410,7 @@ export function buildManifest(options: {
|
|
|
1352
1410
|
auth?: ManifestAuthConfig;
|
|
1353
1411
|
llm?: ManifestLlmConfig;
|
|
1354
1412
|
connections?: ManifestConnection[];
|
|
1413
|
+
crons?: ManifestCron[];
|
|
1355
1414
|
}): AppManifest {
|
|
1356
1415
|
// Pull policies attached via the fluent `e.entity().policies(...)`
|
|
1357
1416
|
// chain onto the top-level policies list. Without this, fluent
|
|
@@ -1396,6 +1455,9 @@ export function buildManifest(options: {
|
|
|
1396
1455
|
...(options.connections && options.connections.length > 0
|
|
1397
1456
|
? { connections: options.connections }
|
|
1398
1457
|
: {}),
|
|
1458
|
+
...(options.crons && options.crons.length > 0
|
|
1459
|
+
? { crons: options.crons }
|
|
1460
|
+
: {}),
|
|
1399
1461
|
};
|
|
1400
1462
|
}
|
|
1401
1463
|
|