跳到主要内容

原生脚本自定义协议

由持续 QuickJS 回调直接供应动态库的地图资源字节

启用 script 的开发动态库,使用持续会话入口后,可从 sqsmap 命名导入 addProtocol、removeProtocol。await map.sqs.getCapabilities() 的 nativeScriptProtocols 为 true 才表示此宿主接通了回调。低层地图/C、一次性原生脚本、WASM和应用共同脚本不据此自动提供回调;网页SDK原有 addProtocol 仍需在实际加载资源的主线程/地图Worker登记。

import {map, addProtocol, removeProtocol} from 'sqsmap';
// This sample JSON contains ASCII characters only.
const text = JSON.stringify({type: 'FeatureCollection', features: [
  {type: 'Feature', id: 1, properties: {},
   geometry: {type: 'Point', coordinates: [116.4, 39.9]}}
]});
const bytes = new Uint8Array(Array.from(text, c => c.charCodeAt(0)));
addProtocol('local', (request, controller) => {
  controller.signal.throwIfAborted();
  if (request.url !== 'local://sample/point.json') throw Error('Unknown resource');
  return {data: bytes};
});
const ready = new Promise((resolve, reject) => {
  let loaded, failed;
  const close = () => {loaded.unsubscribe(); failed.unsubscribe();};
  loaded = map.on('sourcedata', event => {
    if (event.sourceId === 'sample' && event.isSourceLoaded) {close(); resolve();}
  });
  failed = map.on('error', event => {
    if (event.sourceId === 'sample') {close(); reject(Error(event.error.message));}
  });
});
map.addSource('sample', {type: 'geojson', data: 'local://sample/point.json'});
await map.sqs.flush();
await ready;
map.addLayer({id: 'points', type: 'circle', source: 'sample',
  paint: {'circle-radius': 8, 'circle-color': 'red'}});
map.jumpTo({center: [116.4, 39.9], zoom: 12});
await map.sqs.flush({render: true});
removeProtocol('local');

协议登记属于脚本会话;名称使用小写 URI scheme,最多32字符,每会话最多16种。HTTP/HTTPS/WS/WSS/file/data/blob 保留给宿主。同一地图的同一协议只能由一个活动会话拥有,冲突会使后启动/登记的会话明确失败,不替换另一脚本。相同会话重新登记会取消旧在途回调。

处理函数收到冻结的 url、resourceType、maxBytes、method 和取消控制器。可返回或异步返回 {data: ArrayBuffer | Uint8Array},子视图只复制其有效区间。UTF-8 JSON、PNG/JPEG/WebP、字形PBF、瓦片和视频仍由原资源类型解码;协议本身不改变坐标/格式。当前回传只接受 data,缓存元数据等其他字段明确拒绝,不静默忽略。

并发取配置值与8的较小值;超时遵守 resourceTimeoutMs(1~120000ms)。单条回传最多8MiB且不得超过原请求预算,回复队列最多16MiB/32条;复制前检查。每次pump仍有2秒/4096微任务限制。协议回调可 await 地图查询;没有新增线程、网络客户端、浏览器DOM、fetch或定时器。函数负责自行取得或生成字节。

移除/替换协议及资源失效/超时会取消在途控制器;旧代字节不复用。显式停止直接释放VM,不运行用户清理函数;其资源得到失败结果并解除协议占用,新的会话可以再登记。地图销毁仍派发已有remove清理;销毁后可停止/释放保留的脚本句柄。抛错、无效字节和超时表现为资源加载错误,等待中的 loadImage 可以捕获 IO_ERROR。

C宿主仍按原 sqsm_map_script_session_pump_json 推进。已登记资源不会出现在外部 sqsm_map_resource_requests_json;未登记资源继续交外部传输。标准C输出所有权和ABI1/40导出不变。

本机验收:12项实际C/QuickJS资源检查及视频像素,另4项占用/停止/超时/销毁检查,原生VM10项回归及2项文档编译通过。原样验收脚本。这不表示Android/iOS设备、桌面默认下载器或应用共享脚本跨Worker回调转发已完成。