M 发布者指南 作品要求 · 统一账号 SDK · 深浅色主题 · 分享与素材库

写给发布者

拿到「发布者」角色后,登录画廊首页就会看到「发布新作品」磁贴。作品是纯静态网页(HTML/CSS/JS), 上传后跑在 /p/<id>/ 子路径下,任何人打开即用。

作品要求

作品代码与本站同源,能读到打开它的访客在本站的登录态。这正是下面 SDK 能「零后端」工作的原因, 也意味着授予发布者角色等于信任其代码——请只上传你自己写的东西。

更新 / 可见性 / 删除

接入统一账号(可选,零后端)

作品可以识别当前登录用户,并把进度 / 设置存到该用户的云端(多设备同步)。站点托管了官方 SDK /sdk/mksync-1.js,把下面几行放进你的 index.html 就够了:

<script src="/sdk/mksync-1.js?v=20260907"></script>
<script>
const sync = MKSync.create({
  slug: 'myapp',                                // 必填:小写字母数字-,作品的短名
  initial: () => ({ score: 0, unlocked: [] }),  // 空档形状
  onChange: (data) => render(data),             // 云端有新数据到达(含启动首拉)时被调
});
const { authed, data } = await sync.start();    // 唯一需要 await 的调用;未登录也正常返回
render(data);

sync.set(d => ({ ...d, score: d.score + 1 }));  // 改数据:本地立即落盘,2 秒防抖推云
loginBtn.onclick = () => sync.login();           // 登录按钮必须放在用户点击里(iframe 会拦非手势弹窗)
</script>

三条纪律

  1. 未登录也要能玩——账号是增强不是门槛,SDK 未登录时自动降级到 localStorage。
  2. 登录状态只信 SDK / /api/user/me——cookie 是 HttpOnly 的,JS 读不到。
  3. 数据整文档读写——一个作品一份 JSON(≤256KB),读回来、改内存、整体写回。

注意事项

深浅色主题(1 行接入)

本站与所有作品共用一个主题开关。在 <head> 里加一行,作品就会跟随站内当前主题并实时切换:

<script src="/sdk/mktheme-1.js?v=20260907"></script>

它会给 <html> 打 data-theme="light|dark",你的 CSS 用 [data-theme="dark"] 选择器写深色样式即可。 不要自建主题键,也不要写死 prefers-color-scheme。协议细节见 /sdk/README.md。

多人联机(对战 / 协作 / 聊天 / 同屏)

再引一个 SDK,作品就能让多个玩家进同一个房间实时互动。登录可选:未登录以匿名访客参与,登录用户带账号名。 服务端只做通道(成员表、消息路由、共享状态、房主、断线恢复),游戏规则由作品自己定。

<script src="/sdk/mkroom-1.js?v=20260919"></script>
<script>
const room = MKRoom.create({ slug: 'mygame' });
room.on('join',    p => addPlayer(p));
room.on('leave',   p => removePlayer(p));
room.on('message', (data, from) => handle(data, from));   // 别人 send() 的内容
room.on('state',   state => render(state));                // 共享状态(迟到者进房直接拿到)
room.on('host',    (id, isMe) => { if (isMe) becomeAuthority(); });

const { code } = await room.create({ max: 4 });   // 6 位房间码给朋友;或 room.join('AB3K9Q')
room.send({ t: 'move', x, y });                    // 广播;(data, 'host') 只发房主;(data, peerId) 点对点
room.setState({ phase: 'playing' });               // 浅合并,全员按同一顺序收到
</script>

加载进度与就绪(MKApp)

访客从画廊或分享链接打开作品时,会先看到一层带作品名和进度条的加载遮罩,作品在它下面的 iframe 里加载。 不做任何事遮罩也会揭开(资源请求安静下来就判定就绪,最长 20 秒兜底);引 /sdk/mkapp-1.js 上报真实进度, 遮罩就能准确地在「真正能玩」那一刻揭开,大资源作品不会提前露出黑屏。

<script src="/sdk/mkapp-1.js?v=20261006"></script>
<script>
let done = 0;
Promise.all(assets.map(a => load(a).then(() => window.MKApp && MKApp.progress(++done, assets.length))))
  .then(() => { startGame(); window.MKApp && MKApp.ready(); });   // ready() 幂等,多调无害
</script>

分享与展示集

每个作品都有一条短链 /play/<id>:打开即是带加载遮罩的全屏外壳,服务端直接输出作品名、简介和封面的 预览卡片(微信 / QQ / Telegram 等聊天软件的链接预览不执行 JS,靠的就是这个)。所以封面图和简介写好,分享出去才好看。

shareBtn.onclick = async () => {
  const r = await MKApp.share({ title: '来玩我的作品' });   // 手机弹系统分享面板,电脑复制 /play/<id> 链接
  toast(r.method === 'copy' ? '链接已复制' : r.method === 'share' ? '已分享' : '请手动复制:' + r.url);
};

素材库(MKVault)

需要给每个登录用户存大量条目或图片 / 音频 / 视频(作品集、日记、卡片、录音……)时用素材库:条目是任意 JSON(每条 ≤256KB), 文件单独上传后把 fileId 写进条目引用。只存进度 / 设置用上面的 MKSync 就够了。素材库必须登录,未登录没有本地降级。

<script src="/sdk/mkvault-1.js?v=20261006"></script>
<script>
const vault = MKVault.open({ slug: 'myapp' });          // 线上自动按 /p/<id>/ 隔离;本地开发落 myapp-devlocal
const list = await vault.items();                       // 带缓存与 ETag,没变化时几乎零流量
const f = await vault.upload(file, { downscale: { maxSide: 2048 }, onProgress: p => bar(p) });
await vault.put(MKVault.newId(), { title: '水墨山', media: [{ fileId: f.fileId }] });
img.src = vault.fileUrl(f.fileId);
</script>

下载与参考

文件用途
mksync-1.js · mksync.d.ts 统一账号云同步 SDK(全局 MKSync)。运行时请引站内绝对路径,.d.ts 只用于类型。
mkchip-1.js · mkchip.d.ts 可选的账号 / 同步状态角标(全局 MKChip)。
mktheme-1.js · mktheme.d.ts 统一深浅色主题(全局 MKTheme)。
mkroom-1.js · mkroom.d.ts 联机房间 SDK(全局 MKRoom):建房 / 加入、消息、共享状态、房主、断线恢复、WebRTC 信令。
mkapp-1.js · mkapp.d.ts 平台桥(全局 MKApp):加载进度 / 就绪、运行上下文、当前用户、登录、分享短链。平台外全部静默。
mkvault-1.js · mkvault.d.ts 用户素材库(全局 MKVault):条目 JSON + 图片 / 音视频上传,带缓存、并发控制与图片压缩。
app-api.md · vault-api.md 平台桥与素材库接入指南。
room-api.md · roomdemo.html 联机接入指南与自测台。
user-api.md 完整接入指南:全部选项、匿名进度合并、冲突 merge、登录引导、排错手册、底层 HTTP API。
demo.html SDK 自测台:登录 / 多标签同步 / 冲突场景一步步验证。
README.md SDK 版本纪律与主题协议。已被引用的文件永不删除、永不做破坏性改动。

遇到问题:给 MKSync.create 加 debug: true,所有静默失败都会 console.warn。