@stacksjs/defaults 0.75.165 → 0.75.167
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.
|
@@ -25,6 +25,13 @@ accepted input; fetchSubmissions and exportSubmissionsCsv serve administrative
|
|
|
25
25
|
reads. Supply the site identity from trusted request context. A null site id is
|
|
26
26
|
the single-site/global context, not a tenant identity from a client.
|
|
27
27
|
|
|
28
|
+
Public endpoints that are not persisted forms (a lead or contact form an app
|
|
29
|
+
stores itself) use `checkSubmissionSpam({ honeypot, renderedAtMs }, policy)`
|
|
30
|
+
from `@stacksjs/forms/spam`: `honeypot` (answer as if it worked, store nothing),
|
|
31
|
+
`too_fast` (under `minSubmitSeconds`, default 3) or null. submitForm uses the
|
|
32
|
+
same check with `config.forms.spam`. No CAPTCHA, no third-party script; still
|
|
33
|
+
rate-limit per address or IP.
|
|
34
|
+
|
|
28
35
|
## Uploads, notifications, and paid forms
|
|
29
36
|
|
|
30
37
|
Use resolveUploadLimits, checkUpload, fileFieldNamed, formUploadPrefix and
|
|
@@ -256,6 +256,51 @@ with fixes recorded separately. In a browser and on Android `isAvailable()` is
|
|
|
256
256
|
false, the state says `available: false` and nothing fires. Word iOS's prompt
|
|
257
257
|
with `ios.usageDescriptions.NSBluetoothAlwaysUsageDescription`.
|
|
258
258
|
|
|
259
|
+
## Apple Watch scheduled workouts
|
|
260
|
+
|
|
261
|
+
`scheduledWorkouts` puts structured workouts on the paired Apple Watch through
|
|
262
|
+
WorkoutKit's scheduler (iOS 17+): each appears in the watch's Workout app on
|
|
263
|
+
its day, with its warmup, repeated blocks, cooldown, goals and alerts. iOS
|
|
264
|
+
only, behind `capabilities.scheduledWorkouts`; only an app with it compiles in
|
|
265
|
+
and links WorkoutKit. The calls work on the page and on native stx screens.
|
|
266
|
+
A plan is plain JSON in SI units, its `id` a UUID the app keeps for it.
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
import { scheduledWorkouts } from '@stacksjs/mobile'
|
|
270
|
+
|
|
271
|
+
if (await scheduledWorkouts.isSupported()) { // false off an iPhone, never rejects
|
|
272
|
+
await scheduledWorkouts.requestAuthorization() // iOS's prompt, once; call it from a tap
|
|
273
|
+
const kept = await scheduledWorkouts.list() // [{ id, date, hour, minute, complete }]
|
|
274
|
+
await scheduledWorkouts.schedule({
|
|
275
|
+
id: '6f1c2b8e-5a7d-4c3e-9b1a-2d4e6f8a0b1c',
|
|
276
|
+
date: '2026-10-20', hour: 6, minute: 30, // local; 07:00 without a time
|
|
277
|
+
workout: {
|
|
278
|
+
activity: 'running', location: 'outdoor', displayName: '4 x 1 km',
|
|
279
|
+
warmup: { goal: { type: 'time', seconds: 600 } },
|
|
280
|
+
blocks: [{ iterations: 4, steps: [
|
|
281
|
+
{ purpose: 'work', step: { goal: { type: 'distance', meters: 1000 }, alert: { type: 'speed', min: 4.1, max: 4.4 } } },
|
|
282
|
+
{ purpose: 'recovery', step: { goal: { type: 'time', seconds: 120 } } },
|
|
283
|
+
] }],
|
|
284
|
+
},
|
|
285
|
+
})
|
|
286
|
+
await scheduledWorkouts.remove(kept[0].id) // every day it is on
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Goals are `open`, `time` (seconds), `distance` (meters) and `energy`
|
|
291
|
+
(kilocalories); alerts `heartRate`, `power`, `speed` (m/s), `cadence` ranges and
|
|
292
|
+
`heartRateZone` / `powerZone`. An activity or goal WorkoutKit refuses rejects
|
|
293
|
+
the call with a message naming it; an alert it refuses is left out and named
|
|
294
|
+
in the result's `droppedAlerts`. `schedule` also rejects LIMIT_REACHED (the
|
|
295
|
+
watch holds 15) and NOT_SCHEDULED when nothing kept the plan, as without a
|
|
296
|
+
paired watch. In a browser and on Android `isSupported()` is false and every
|
|
297
|
+
other call rejects `unsupported`.
|
|
298
|
+
|
|
299
|
+
For tests, `createScheduledWorkoutsFake()` from `@stacksjs/mobile/testing` is a
|
|
300
|
+
`craft.scheduledWorkouts` that answers like the shell. On the iOS simulator,
|
|
301
|
+
which never has a watch, the app's `CraftFakeWorkoutScheduler` default makes
|
|
302
|
+
the shell keep plans itself (`xcrun simctl spawn <device> defaults write <bundle id> CraftFakeWorkoutScheduler -bool YES`).
|
|
303
|
+
|
|
259
304
|
## Apple Music (now playing)
|
|
260
305
|
|
|
261
306
|
`music` shows what the Music app is playing (title, artist, album, a small
|
|
@@ -51,7 +51,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
51
51
|
| `@stacksjs/faker` | [`stacks-faker`](../stacks-faker/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/faker/src/index.ts) | 1 |
|
|
52
52
|
| `@stacksjs/feature-flags` | [`stacks-feature-flags`](../stacks-feature-flags/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/feature-flags/src/index.ts) | 7 |
|
|
53
53
|
| `@stacksjs/features` | [`stacks-features`](../stacks-features/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/features/src/index.ts) | 1 |
|
|
54
|
-
| `@stacksjs/forms` | [`stacks-forms`](../stacks-forms/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/index.ts) |
|
|
54
|
+
| `@stacksjs/forms` | [`stacks-forms`](../stacks-forms/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/index.ts) | 4 |
|
|
55
55
|
| `@stacksjs/git` | [`stacks-git`](../stacks-git/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/src/index.ts) | 1 |
|
|
56
56
|
| `@stacksjs/github` | [`stacks-git`](../stacks-git/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/github/src/index.ts) | 7 |
|
|
57
57
|
| `@stacksjs/health` | [`stacks-health`](../stacks-health/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/health/src/index.ts) | 2 |
|
|
@@ -60,10 +60,10 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
|
|
|
60
60
|
| `@stacksjs/image` | [`stacks-image`](../stacks-image/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/image/src/index.ts) | 2 |
|
|
61
61
|
| `@stacksjs/lint` | [`stacks-lint`](../stacks-lint/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/lint/src/index.ts) | 3 |
|
|
62
62
|
| `@stacksjs/logging` | [`stacks-logging`](../stacks-logging/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/logging/src/index.ts) | 14 |
|
|
63
|
-
| `@stacksjs/mobile` | [`stacks-mobile`](../stacks-mobile/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/index.ts) |
|
|
63
|
+
| `@stacksjs/mobile` | [`stacks-mobile`](../stacks-mobile/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/index.ts) | 17 |
|
|
64
64
|
| `@stacksjs/model-meta` | [`stacks-models`](../stacks-models/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/model-meta/src/index.ts) | 1 |
|
|
65
65
|
| `@stacksjs/newsletter` | [`stacks-newsletter`](../stacks-newsletter/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/newsletter/src/index.ts) | 7 |
|
|
66
|
-
| `@stacksjs/notifications` | [`stacks-notifications`](../stacks-notifications/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/index.ts) |
|
|
66
|
+
| `@stacksjs/notifications` | [`stacks-notifications`](../stacks-notifications/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/index.ts) | 15 |
|
|
67
67
|
| `@stacksjs/objects` | [`stacks-objects`](../stacks-objects/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/objects/src/index.ts) | 4 |
|
|
68
68
|
| `@stacksjs/orm` | [`stacks-orm`](../stacks-orm/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/orm/src/index.ts) | 60 |
|
|
69
69
|
| `@stacksjs/pagination` | [`stacks-pagination`](../stacks-pagination/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/pagination/src/index.ts) | 0 |
|
|
@@ -497,11 +497,11 @@ Evidence directory: [1 retained tests](https://github.com/stacksjs/stacks/blob/m
|
|
|
497
497
|
|
|
498
498
|
Guidance: [`stacks-forms`](../stacks-forms/SKILL.md). Source: [storage/framework/core/forms/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/index.ts).
|
|
499
499
|
|
|
500
|
-
Declared runtime exports: `checkUpload`, `completeSubmissionPayment`, `computeAmountCents`, `createForm`, `dispatchSubmissionNotifications`, `evaluateConditions`, `exportSubmissionsCsv`, `extensionOf`, `fetchSubmissions`, `fileFieldNamed`, `formUploadPrefix`, `isOwnedUploadPath`, `loadFormByHandle`, `loadFormByUuid`, `publicDefinition`, `resolveUploadLimits`, `submissionIdentity`, `submitForm`, `toCreateFields`, `validateSubmission`, `visibleFields`.
|
|
500
|
+
Declared runtime exports: `checkSubmissionSpam`, `checkUpload`, `completeSubmissionPayment`, `computeAmountCents`, `createForm`, `dispatchSubmissionNotifications`, `evaluateConditions`, `exportSubmissionsCsv`, `extensionOf`, `fetchSubmissions`, `fileFieldNamed`, `formUploadPrefix`, `isOwnedUploadPath`, `loadFormByHandle`, `loadFormByUuid`, `publicDefinition`, `resolveUploadLimits`, `submissionIdentity`, `submitForm`, `toCreateFields`, `validateSubmission`, `visibleFields`.
|
|
501
501
|
|
|
502
|
-
Local source modules: [src/conditions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/conditions.ts), [src/create.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/create.ts), [src/definition.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/definition.ts), [src/notifications.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/notifications.ts), [src/submissions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/submissions.ts), [src/uploads.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/uploads.ts), [src/validate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/validate.ts).
|
|
502
|
+
Local source modules: [src/conditions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/conditions.ts), [src/create.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/create.ts), [src/definition.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/definition.ts), [src/notifications.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/notifications.ts), [src/spam.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/spam.ts), [src/submissions.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/submissions.ts), [src/uploads.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/uploads.ts), [src/validate.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/validate.ts).
|
|
503
503
|
|
|
504
|
-
Evidence directory: [
|
|
504
|
+
Evidence directory: [4 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
505
505
|
|
|
506
506
|
### @stacksjs/git
|
|
507
507
|
|
|
@@ -581,9 +581,9 @@ Guidance: [`stacks-mobile`](../stacks-mobile/SKILL.md). Source: [storage/framewo
|
|
|
581
581
|
|
|
582
582
|
Declared runtime exports: `appReview`, `biometrics`, `brightness`, `camera`, `deepLinks`, `device`, `getNativeMobileBridge`, `haptics`, `health`, `heartRate`, `isNativeMobile`, `keepAwake`, `lifecycle`, `liveActivities`, `location`, `mobile`, `music`, `network`, `normalizeDeepLinkURL`, `notifications`, `onMobileReady`, `permissions`, `pushNotifications`, `secureStorage`, `share`, `snapshots`, `speech`, `splash`, `watchConnectivity`, `whenNativeMobile`, `withNativeFeedback`.
|
|
583
583
|
|
|
584
|
-
Local source modules: [src/bridge.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/bridge.ts), [src/controls.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/controls.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/events.ts), [src/gestures.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/gestures.ts), [src/indoor.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/indoor.ts), [src/native.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/native.ts), [src/navigation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/navigation.ts), [src/refresh-control.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/refresh-control.ts), [src/route.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/route.ts), [src/session-clock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/session-clock.ts), [src/sheet-gesture.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/sheet-gesture.ts), [src/sheets.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/sheets.ts), [src/shell.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/shell.ts), [src/spotlight.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/spotlight.ts), [src/tab-bar.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/tab-bar.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/types.ts).
|
|
584
|
+
Local source modules: [src/bridge.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/bridge.ts), [src/controls.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/controls.ts), [src/events.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/events.ts), [src/gestures.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/gestures.ts), [src/indoor.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/indoor.ts), [src/native.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/native.ts), [src/navigation.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/navigation.ts), [src/refresh-control.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/refresh-control.ts), [src/route.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/route.ts), [src/scheduled-workouts.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/scheduled-workouts.ts), [src/session-clock.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/session-clock.ts), [src/sheet-gesture.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/sheet-gesture.ts), [src/sheets.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/sheets.ts), [src/shell.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/shell.ts), [src/spotlight.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/spotlight.ts), [src/tab-bar.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/tab-bar.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/src/types.ts).
|
|
585
585
|
|
|
586
|
-
Evidence directory: [
|
|
586
|
+
Evidence directory: [17 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/mobile/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
587
587
|
|
|
588
588
|
### @stacksjs/model-meta
|
|
589
589
|
|
|
@@ -607,11 +607,11 @@ Evidence directory: [7 retained tests](https://github.com/stacksjs/stacks/blob/m
|
|
|
607
607
|
|
|
608
608
|
Guidance: [`stacks-notifications`](../stacks-notifications/SKILL.md). Source: [storage/framework/core/notifications/src/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/index.ts).
|
|
609
609
|
|
|
610
|
-
Declared runtime exports: `BroadcastNotificationDriver`, `DEFAULT_SMS_OPT_OUT`, `DEFAULT_UNSUBSCRIBE_NOTICE`, `DatabaseNotificationDriver`, `NOTIFICATION_FRAME_STRINGS`, `SMS_SENDER_MAX_LENGTH`, `accountNotificationTemplates`, `bulkSetPreferences`, `commerceNotificationTemplates`, `createNotificationTemplates`, `defineNotificationTemplates`, `emailParagraphs`, `ensureSuccessfulEmailResult`, `ensureSuccessfulNotificationResults`, `filterChannelsByPreferences`, `getNotificationPreferences`, `interpolateNotificationText`, `listUnsubscribeHeaders`, `makeDeliveryRecord`, `notification`, `notificationChannel`, `notificationEmailHtml`, `notificationEmailMessage`, `notificationEmailText`, `notificationFrameStrings`, `notificationLanguageTag`, `notificationSmsBody`, `notificationTemplateVariables`, `notificationUnsubscribeLinks`, `notificationUnsubscribeToken`, `notify`, `parseNotificationUnsubscribeToken`, `recordNotificationDelivery`, `renderNotificationTemplate`, `resolveDeliveryRecipient`, `resolveNotificationLocale`, `setNotificationPreference`, `smsSenderPrefix`, `subscriptionNotificationTemplates`, `unsubscribeTokenFromRequest`, `unsubscribeWithToken`, `useBroadcast`, `useChat`, `useDatabase`, `useEmail`, `useNotification`, `usePush`, `useSMS`, `wherePreferenceCategory`.
|
|
610
|
+
Declared runtime exports: `BroadcastNotificationDriver`, `DEFAULT_SMS_OPT_OUT`, `DEFAULT_UNSUBSCRIBE_NOTICE`, `DatabaseNotificationDriver`, `NOTIFICATION_FRAME_STRINGS`, `SMS_SENDER_MAX_LENGTH`, `accountNotificationTemplates`, `advanceSequence`, `bulkSetPreferences`, `commerceNotificationTemplates`, `createNotificationTemplates`, `defineNotificationTemplates`, `emailParagraphs`, `ensureSuccessfulEmailResult`, `ensureSuccessfulNotificationResults`, `filterChannelsByPreferences`, `getNotificationPreferences`, `interpolateNotificationText`, `isQuietTime`, `listUnsubscribeHeaders`, `makeDeliveryRecord`, `nextSendableTime`, `notification`, `notificationChannel`, `notificationEmailHtml`, `notificationEmailMessage`, `notificationEmailText`, `notificationFrameStrings`, `notificationLanguageTag`, `notificationSmsBody`, `notificationTemplateVariables`, `notificationUnsubscribeLinks`, `notificationUnsubscribeToken`, `notify`, `parseNotificationUnsubscribeToken`, `recordNotificationDelivery`, `renderNotificationTemplate`, `resolveDeliveryRecipient`, `resolveNotificationLocale`, `sequenceTimeline`, `setNotificationPreference`, `smsSenderPrefix`, `subscriptionNotificationTemplates`, `unsubscribeTokenFromRequest`, `unsubscribeWithToken`, `useBroadcast`, `useChat`, `useDatabase`, `useEmail`, `useNotification`, `usePush`, `useSMS`, `wherePreferenceCategory`.
|
|
611
611
|
|
|
612
|
-
Local source modules: [src/delivery.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/delivery.ts), [src/drivers/broadcast.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/broadcast.ts), [src/drivers/database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/database.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/index.ts), [src/email-body.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/email-body.ts), [src/frame-strings.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/frame-strings.ts), [src/preferences.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/preferences.ts), [src/templates.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/templates.ts), [src/unsubscribe.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/unsubscribe.ts).
|
|
612
|
+
Local source modules: [src/delivery.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/delivery.ts), [src/drivers/broadcast.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/broadcast.ts), [src/drivers/database.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/database.ts), [src/drivers/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/drivers/index.ts), [src/email-body.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/email-body.ts), [src/frame-strings.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/frame-strings.ts), [src/preferences.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/preferences.ts), [src/sequences.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/sequences.ts), [src/templates.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/templates.ts), [src/unsubscribe.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/src/unsubscribe.ts).
|
|
613
613
|
|
|
614
|
-
Evidence directory: [
|
|
614
|
+
Evidence directory: [15 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/notifications/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
|
|
615
615
|
|
|
616
616
|
### @stacksjs/objects
|
|
617
617
|
|
|
@@ -186,6 +186,34 @@ const { subject, body, action } = templates.render('password_changed', { app: 'H
|
|
|
186
186
|
- `account_created` carries a credential link: send it directly, not through a
|
|
187
187
|
stored queue that keeps the body.
|
|
188
188
|
|
|
189
|
+
## Sequences: steps with waits and quiet hours
|
|
190
|
+
|
|
191
|
+
`@stacksjs/notifications/sequences` (pure; also exported from the root) is the
|
|
192
|
+
timing engine for journeys such as "email now, wait two days, text, then a call
|
|
193
|
+
task for staff". It never sends or stores anything: the app keeps each
|
|
194
|
+
person's next step index and due time, and on each tick asks what to do now.
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import { advanceSequence, sequenceTimeline } from '@stacksjs/notifications/sequences'
|
|
198
|
+
|
|
199
|
+
const quietHours = { start: '21:00', end: '08:00', timeZone: 'Europe/Berlin' }
|
|
200
|
+
const { run, next } = advanceSequence(steps, enrollment.step_index, new Date(), {
|
|
201
|
+
quietHours,
|
|
202
|
+
respectsQuietHours: step => step.type === 'email' || step.type === 'sms',
|
|
203
|
+
})
|
|
204
|
+
// perform `run` in order, then store next?.index / next?.at (null: finished)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
- A step is `{ type, minutes? }` plus whatever the app needs. `type: 'wait'`
|
|
208
|
+
with `minutes` sets when the sequence continues; a zero wait is skipped.
|
|
209
|
+
- A step that respects quiet hours (default: every non-wait) is held until the
|
|
210
|
+
window ends in its zone (`nextSendableTime`); `isQuietTime` answers for one
|
|
211
|
+
instant. Windows may cross midnight; DST comes from the runtime's tz data.
|
|
212
|
+
- `sequenceTimeline(steps, start, options)` lays the steps out in time for a
|
|
213
|
+
preview.
|
|
214
|
+
- Consent, unsubscribes and STOP are still the sender's checks (`notify()`,
|
|
215
|
+
preferences); the engine only decides when.
|
|
216
|
+
|
|
189
217
|
## Channel factories
|
|
190
218
|
|
|
191
219
|
- `useEmail(driver?)` returns a sendable transport. Without a driver it uses
|
|
@@ -231,7 +259,7 @@ delivery log, not extra columns on the inbox.
|
|
|
231
259
|
`storage/framework/core/notifications/src/index.ts` defines the real
|
|
232
260
|
signatures. `preferences.ts`, `delivery.ts` and `drivers/database.ts`
|
|
233
261
|
own their persistence; the query builder is bun-query-builder.
|
|
234
|
-
`notifications.test.ts`, `delivery-tracking.test.ts`,
|
|
262
|
+
`notifications.test.ts`, `delivery-tracking.test.ts`, `sequences.test.ts`,
|
|
235
263
|
`broadcast.test.ts`, `email-body.test.ts` and `frame-locale.test.ts` cover
|
|
236
264
|
retained behavior; `frame-strings.ts` holds the frame's languages.
|
|
237
265
|
For provider status, consult `config/src/capabilities.ts` and each channel
|
package/ide/vscode/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"publisher": "Stacks",
|
|
3
3
|
"name": "vscode-stacks",
|
|
4
4
|
"displayName": "Stacks",
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.167",
|
|
6
6
|
"description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.167",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@iconify-json/f7": "^1.2.2",
|
|
57
57
|
"@iconify-json/hugeicons": "^1.2.35",
|
|
58
|
-
"@stacksjs/mobile": "0.75.
|
|
58
|
+
"@stacksjs/mobile": "0.75.167",
|
|
59
59
|
"@stacksjs/sanitizer": "^0.2.483",
|
|
60
60
|
"@xterm/addon-fit": "^0.11.0",
|
|
61
61
|
"@xterm/xterm": "^6.0.0",
|