@baukit/notifications-core
@baukit/notifications-core 计划本地通知,只替换产品拥有的.
除此之外,它没有运行时间依赖关系 @baukit/localization-core 绝不进口
通知库。 产品决定哪些产品符合条件,以及副本的内容.
这个包把它们变成瞬间, 扔出地平线以外的, 并计算什么
保留、取消和时间表.
规划
import {
planNotificationReplacement,
resolveNotificationOccurrences,
} from '@baukit/notifications-core';
const resolution = resolveNotificationOccurrences({
occurrences: [
{
logicalId: 'plan:2026-03-29',
civilDate: '2026-03-29',
civilTime: '02:30',
contentDigest: 'v3',
},
{
logicalId: 'plan:2026-03-30',
civilDate: '2026-03-30',
civilTime: '02:30',
contentDigest: 'v3',
},
],
timeZone: 'Europe/Berlin',
gap: 'shiftForward',
fold: 'earlier',
clock: () => Date.now(),
horizonDays: 14,
});
// resolution.desired: both entries with epochMilliseconds and transition ('gap' for the first)
const plan = planNotificationReplacement(current, resolution.desired);
// plan.keep, plan.cancel, plan.schedule, each sorted by instant, then logical ID
- 每起事件都会解决
resolveZonedLocalTime从@baukit/localization-core编辑 调用者会选择空格并折叠策略;也没有默认. - 地平线是今天开始的民用日期
timeZone通过今天加horizonDays - 1。 。 。 .resolution.firstCivilDate财务报告和审定财务报表resolution.lastCivilDate报告. resolution.skipped列出出现的原因 :past(此时此刻或之前) 时钟,outside_horizon,或nonexistent_local_time(缺额)gap: 'reject') (中文(简体) ).- 发生时的额外字段,如通知副本,通过
desired。 。 。 . - 一个条目只有在其逻辑ID,即时,和内容消化全部匹配时才保留. 文本更改
在同一文摘下,故意保留。 更改文摘或通过
{ replaceAll: true },改为 替换文本. - 无效的输入抛出
NotificationPlanError带有code在适用时logicalId数字 :invalid_civil_date, (中文(简体) ),invalid_civil_time, (中文(简体) ),invalid_time_zone, (中文(简体) ),invalid_horizon, (中文(简体) ),invalid_clock, (中文(简体) ),invalid_logical_id, (中文(简体) ),invalid_content_digest, (中文(简体) ),invalid_instant,或duplicate_logical_id。无效的日期即使落在地平线之外也会丢出。 一个 未知的策略抛出RangeError时,如resolveZonedLocalTime。 。 。 .
同样的输入和时钟给出了相同的结果,无论出现时的顺序如何. 共享
向量在 fixtures/notifications/plan-vectors-v1.json 月和年的DST缺口和折叠数
更改、区间旅行、重复、无效输入、内容改变和地平线边界.
@baukit/notifications-core/vectors 出口 notificationPlanVectorChecks(fixture)检查
Vitest套房运行:每个成功案例产生预期计划,一旦计划实施,趋同,
和独立于输入顺序. examples/expo-notifications-conformance 把他们放进去
赫尔墨斯.
拥有的替换
createOwnedNotificationScheduler(platform, { pendingLimit }) 运行一个计划与
NotificationPlatform<TContent> 有四个呼叫的端口: list, (中文(简体) ), cancel, (中文(简体) ), permission,以及
schedule。 。 。 . @baukit/notifications-expo 是世博会的实施.
const outcome = await scheduler.replaceOwned({ namespace: 'reminders' }, desired);
// { status: 'complete' | 'incomplete' | 'superseded', kept, cancelled, scheduled, failures }
- 当通知带有该命名空间的有效标记时,它属于命名空间
标识符是
baukit:<namespace>:<logicalId>. 其它一切将单独处理,包括其他 Baukit 命名空间和请求带有复制标记 . - 调度器一次取消一个请求,从不取消所有请求. 取消的项目 在同一运行中不重排失败 .
- 它只有在需要安排时才检查许可. 没有许可,它仍然取消 已过时的条目 .
- 它按即时顺序排行,然后停止
pendingLimit,计算每个待处理的请求 装置,不只是这个主人的. - 失败者携带代码和逻辑ID, 永远不会满足:
list_failed, (中文(简体) ),cancel_failed, (中文(简体) ),permission_denied, (中文(简体) ),permission_failed, (中文(简体) ),schedule_failed, (中文(简体) ),schedule_limit失败者 结果incomplete调用replaceOwned同一套装再次汇合. - 每个命名空间一次更换一次 当它运行时, 后呼唤这个命名空间
崩溃到最新的。 那些从未下定决心的人
superseded名称空间不等待 为了彼此。 每个设备共用一个调度器,这样就可以了. - 无效的命名空间( 小写字母和数字分隔由
.或者说-,最多为64个 字符)或无效的想要的集拒绝NotificationPlanError在平台之前 触动.
合规套房
@baukit/notifications-core/vitest 出口 describeOwnedNotificationSchedulerContract运行它
它需要消费者的维特安装.
import {
InMemoryNotificationPlatform,
createOwnedNotificationScheduler,
} from '@baukit/notifications-core';
import { describeOwnedNotificationSchedulerContract } from '@baukit/notifications-core/vitest';
describeOwnedNotificationSchedulerContract<string>((options) => {
const platform = new InMemoryNotificationPlatform<string>();
return {
scheduler: createOwnedNotificationScheduler(platform, options),
faults: platform.faults,
content: (_logicalId, text) => text,
addUnrelated: (identifier) => platform.addUnrelated(identifier),
pending: () => platform.pending(),
};
});
NotificationPlatformFaultState 持有注入的断层( 失败列表、 取消、 调度和
权限调用,被撤销的许可,被持有的列表),因此被嘲笑的本地模块可以再用.
边界
该包不选择提醒时间,安静时间,或复制,也不请求许可. 产品计算符合条件的矿点和内容摘要,在自己的UX中请求许可,以及 选择其平台的待定限制。 它计划每个呼叫一个时区.