豫言 / 豫言操作系统网页消息 @ 0.2.0

当前网页的带 JSON 详情消息通道,接入统一事件队列。

源码浏览已生成;不能解析的文件以纯文本展示,不表示通过类型检查。

规范.汉语.md

# 网页消息接口规范 0.2.0

此能力组让豫言应用订阅、等待、发布和取消订阅当前文档的应用消息。名称必须以“豫言”开头(UTF-8 至多 128 字节);detail 以 UTF-8 JSON 文字传递,最多 1 MiB。订阅的消息进入本应用实例的**统一事件队列**(类型“消息”,见[网页事件接口规范](../网页事件/规范.汉语.md)),关闭时等待函数以“关闭”为名称返回。发布后的事件在当前文档同步派发,应用须自行用请求编号配对响应。

0.2.0 相对 0.1.0 是**行为统一**加一个新函数:

- 消息与界面、定时等事件同处一个队列。`等待网页消息` 只取“消息”类型的事件,其余类型的事件原样留在队列里,**不再被吞掉**;同样,`等待界面事件` 与 `等待网页事件` 也不会吞掉未到取的消息。
- 新增 `取消订阅网页消息`。
- 同一名称重复 `订阅网页消息` 不产生第二个订阅(0.1.0 的重复订阅行为未规定)。
- 详情超过 1 MiB 或不是有效 JSON 时,`等待网页消息` 抛事故(事件本身已被取走);通过 `等待网页事件` 取到的消息事件带 `"详情":null` 与 `"详情错误":"超过一 MiB"` 或 `"详情错误":"不是有效 JSON"`。
- 队列上限、丢弃计数与背压规则同网页事件接口(消息类型默认上限 1024,可用 `设置网页事件队列上限` 调整)。

浏览器适配只传递事件名称和 JSON 值,不能执行全局回调或把 JavaScript 对象句柄交给应用。此接口不承诺跨窗口、跨 Worker 或持久消息;需要这些语义时另建能力包。当前宿主必须有文档事件队列,没有文档的平台不提供本组。

## 函数

- `订阅网页消息 : 字符串 → 有`:订阅当前文档里该名称的消息;名称不合法(不以“豫言”开头,或超过 128 字节)时抛事故;订阅总数至多 128 个。订阅后到达的消息才会入队,订阅前已发出的不补发。
- `等待网页消息 : 有 → (字符串 合 字符串)`:等待下一个消息,返回(名称,detail 的 JSON 文字);只取消息类型;宿主关闭队列后返回(“关闭”,“null”),之后的调用继续返回相同标记。`CustomEvent` 没有 detail 时详情文字为 `null`。
- `发布网页消息 : 字符串 → 字符串 → 有`:在当前文档同步派发消息。detail 必须是有效 JSON 且不超过 1 MiB(字节),名称须合法;否则抛事故。发布者自己订阅了该名称时,也会在自己的队列里收到(应用通常用不同名称区分请求与响应)。
- `取消订阅网页消息 : 字符串 → 有`:取消订阅并移除该名称尚未取走的消息;名称未订阅时什么也不做。

## 失败语义

名称无效、详情非法或超过限额属于**违规调用**,抛事故;详情超过限额(来自页面上其他脚本发布的消息)是**接收时的违规**,同样抛事故,但事件已出队,应用可继续等待下一条;宿主关闭不是失败。

## 限额

| 项 | 限额 |
| --- | --- |
| 名称 | UTF-8 至多 128 字节,以“豫言”开头 |
| detail | 至多 1 MiB(UTF-8 字节) |
| 订阅数 | 至多 128 个名称 |
| 队列 | 每类型默认 1024,超限丢弃最旧并计数(见网页事件接口) |

## 一致性样例

1. 应用订阅 `豫言甲` 后阻塞在 `等待界面事件`;页面发布 `豫言甲`,随后用户点击带 ID 的按钮:`等待界面事件` 返回(click,按钮 ID),消息仍在队列里;应用随后 `等待网页消息` 得(豫言甲,详情文字)。
2. 页面发布 detail 为 1 MiB + 1 字节的 `豫言甲`:应用的 `等待网页消息` 抛事故“网页消息详情超过一 MiB”,其后的消息照常收取。
3. 订阅两次同名消息再取消一次:该名称不再产生事件,队列里遗留的未取消息被移除。

## 边界

本包不规定:跨窗口、跨 Worker、持久消息;消息的请求与响应配对(由应用用编号完成);除 JSON 外的详情。

规范.文言.md

# 网页消息之约 0.2.0

此组令豫言客订、候、发与撤订当前文档之客消息。名须以“豫言”首(UTF-8 至多一百二十八字节);详情以 UTF-8 癸象文传,至多一 MiB。所订之事入本客器之**统一事列**(类曰消息,见[网页事件之约](../网页事件/规范.文言.md)),关环则候术以“关闭”为名返。发事于当前文档同步派,客自以请求号配其答。

零点二点零较零点一点零,乃**统其行**而增一术:

- 消息与界面、定时诸事同处一列。等待网页消息惟取消息类之事,他类之事原样留于列,**不复被吞**;等待界面事件与等待网页事件亦不吞未及取之消息。
- 增取消订阅网页消息。
- 同名复订不生第二订阅(零点一点零未定重订之行)。
- 详情逾一 MiB 或非有效癸象,则等待网页消息发事故(事已出列);经等待网页事件所得之消息事,则带 `"详情":null` 与 `"详情错误":"超过一 MiB"` 或 `"详情错误":"不是有效 JSON"`。
- 事列之限、弃数之计与背压之规同网页事件之约(消息类默认限一千零二十四,可以设置网页事件队列上限调之)。

浏览器适配惟传事名与癸象值,不行全局回调,亦不授 JavaScript 物柄于客。此约不及跨窗、跨工与久藏之消息;欲有其义,当别立包。无文档事队列之宿主不供此组。

## 诸术

- 订阅网页消息:订当前文档中此名之消息;名不合(非“豫言”首,或逾一百二十八字节)则发事故;订阅至多一百二十八名。订后至者方入列,订前已发者不补。
- 等待网页消息:候下一消息,返(名,详情之癸象文);惟取消息类;宿主闭列后返(关闭,null),其后亦然。CustomEvent 无 detail 则详情文为 null。
- 发布网页消息:于当前文档同步派消息。详情须为有效癸象而不逾一 MiB(字节),名须合法;否则发事故。发者自订此名,亦于己之列收之(客常以异名别请与答)。
- 取消订阅网页消息:撤订并去此名未取之消息;名未订则无事。

## 败之义

名不合、详情非法或逾限,属**违约之调用**,发事故;详情逾限而来自页中他脚本所发者,乃**收时之违约**,亦发事故,然事已出列,客可续候下一条;宿主闭非败。

## 限额

| 项 | 限 |
| --- | --- |
| 名 | UTF-8 至多一百二十八字节,“豫言”首 |
| 详情 | 至多一 MiB(UTF-8 字节) |
| 订阅 | 至多一百二十八名 |
| 事列 | 每类默认一千零二十四,逾则弃最旧而计其数(见网页事件之约) |

## 一致性之例

1. 客订“豫言甲”后止于等待界面事件;页发“豫言甲”,继而用户点有标识之钮:等待界面事件返(click,钮标识),消息仍在列;客随后等待网页消息得(豫言甲,详情文)。
2. 页发详情为一 MiB 加一字节之“豫言甲”:客之等待网页消息发事故“网页消息详情超过一 MiB”,其后之消息照常收。
3. 同名订二次而撤一次:此名不复生事,列中遗留未取之消息被去。

## 界

此包不定:跨窗、跨工、久藏之消息;消息请求与答之相配(客以编号成之);癸象外之详情。