@converse/skeletor

中文文档
4.0.2发布于 2026/11/05MITTypeScriptESM + CJS近 30 天下载 3324

现代网络应用的模型和收藏

中文使用文档
文档目录19 节
  1. 为什么是骨骼?
  2. 安装
  3. 快速启动
  4. 型号
  5. 收藏
  6. 地方持久性
  7. 活动
  8. 与反应合并
  9. 图片的特征
  10. 设计哲学
  11. 什么时候用
  12. 什么时候才能找到别的东西
  13. 方向
  14. 从后骨移走
  15. 从 Backbone 更改
  16. 现代化
  17. 被移除的东西
  18. 方法重命名( 分数 ~ Lodash)
  19. 其他行为变化

Skeletor

骨头

XMPP Chat CI Tests

Skeletor是一个轻量级,TypeScript-first反应数据库.

它允许您定义打入的模型,并用事件或订阅来响应变化, 同时坚持索引数据库、本地Storage、会话Storage、SQLite(节点)或REST API.

骨骼器是一种现代化的重写 后骨模式和收藏, 没有jQuery, 没有突触, 也没有查看或运行。 如果你知道Backbone的一切的话 直接转让。 不取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取取出.

骨骼力量 交锋.js,一个全功能的开源XMPP聊天客户端.

为什么是骨骼?

  • 反应模型 ——设定属性,获得属性 change 活动。 使用回调和未订阅功能订阅 。 在任何UI层工作.
  • 直接属性访问 —— 说 model.attrs.name = 'Bob' 火灾改变事件,不需要锅炉板.
  • 计算属性 ——声明有明确依赖关系的衍生值;它们缓存、重新计算和起火 change 自动事件.
  • 存储式订阅 —— 说 subscribe() 返回未订阅的函数,与 React 兼容 useSyncExternalStore 和类似的API.
  • 内建的持久性 ——索引DB, localStorage, sessionStorage, SQLite (Node), 和 REST 退出框.
  • 类型脚本第一 ——完整类型定义,通用模型属性,被打入计算属性.
  • 没有 j 查询, 没有强调 ——本地浏览器 API 和 摇篮 单项进口用于震动树木.
  • 到处都行 ——浏览器,Node.js(22+),Web Workers. 包括无害环境管理+CJS.
  • 与后骨兼容 —— 说 get, (中文(简体) ), set,事件,收藏:都在那里. Backbone数据层的倒置替换.

安装

npm install @converse/skeletor

快速启动

型号

import { Model } from '@converse/skeletor';

interface UserAttrs {
  firstName: string;
  lastName: string;
  active: boolean;
}

class User extends Model<UserAttrs> {
  get defaults() {
    return { firstName: '', lastName: '', active: false };
  }

  get computed() {
    return {
      fullName: {
        deps: ['firstName', 'lastName'],
        fn: (model: User) => `${model.get('firstName')} ${model.get('lastName')}`,
      },
    };
  }
}

const user = new User({ firstName: 'Alice', lastName: 'Smith' });

// Read — three equivalent ways
user.get('firstName'); // → 'Alice'
user.attrs.firstName; // → 'Alice'
user.get('fullName'); // → 'Alice Smith'  (computed — cached, never persisted)

// Write — fires change events
user.attrs.firstName = 'Bob'; // triggers 'change:firstName' and 'change:fullName'
user.set('active', true); // triggers 'change:active'

// React to changes
user.on('change:fullName', (model, value) => {
  console.log('Name is now', value);
});

// Store-style subscription (returns unsubscribe function)
const unsub = user.subscribe((model, changed) => {
  console.log('Changed attrs:', changed);
});
unsub(); // clean up

收藏

import { Model, Collection } from '@converse/skeletor';

class User extends Model {}

class Users extends Collection {
  get model() {
    return User;
  }
  get url() {
    return '/api/users';
  }
}

const users = new Users([
  { id: 1, name: 'Alice', active: true },
  { id: 2, name: 'Bob', active: false },
]);

users.add({ id: 3, name: 'Carol', active: true });

const active = users.filter((u) => u.get('active'));
const names = users.pluck('name'); // → ['Alice', 'Bob', 'Carol']

// Subscribe to structural changes (fires once per operation, not per model)
const unsub = users.subscribe((collection) => {
  console.log('collection changed, length:', collection.length);
});

// Load from the server
await users.fetch();

地方持久性

Skeletor可以坚持模式和收藏到索引DB,localStorage,SessionStorage,或SQLite(Node.js),没有额外的软件包.

人工持久性

传统的 Backbone 风格 API: 设置存储一次, 调用 save()编号 :fetch() 当然.

import { Model, PersistentStorage } from '@converse/skeletor';

class Settings extends Model {
  initialize() {
    this.storage = new PersistentStorage('app-settings', 'local');
  }
}

const settings = new Settings({ id: 'main' });
await settings.fetch(); // load from localStorage
settings.set('theme', 'dark');
await settings.save(); // write to localStorage

自动持久性( O)autoSync(中文(简体) )

选入一次, 然后每个字会自动持续—— 不 save() 需要打电话.

import { Model, PersistentStorage } from '@converse/skeletor';

class Settings extends Model {
  get autoSync() {
    return true;
  }

  initialize() {
    this.storage = new PersistentStorage('app-settings', 'local');
  }
}

const settings = new Settings({ id: 'main' });
await settings.hydrated; // resolves when prior data has been loaded

settings.attrs.theme = 'dark'; // persisted automatically (debounced)
settings.set('lang', 'en'); // also auto-saved

// Pass { noAutoSave: true } to suppress persistence for a specific set() call
settings.set('transient', true, { noAutoSave: true });

待决写作被解禁(参见 autoSyncDelay时冲出 页面被隐藏( e)visibilitychange)或已卸下(pagehide) (中文(简体) ).

何时 autoSync 关闭, hydrated 实值 undefined不过 await model.hydrated 还是安全的 (等待时间) undefined 代码可以统一等待.

在一个 Collection, (中文(简体) ), autoSync 实值 仅水合物: 收藏装入存储的 状态,但不能自动保存 add编号 :remove编号 :reset继续 内容,启用 autoSync 在包含的模型类上——每个模型然后 写自己的记录.

支持的后端 : 'local' (当地施放), 'session' (会议集), 'indexed' (数据库), 'memory', (中文(简体) ), 'node' (SQLite,节点22+).

[注] 卸货时的可涂性是最佳的,不能保证. 冲一冲 visibilitychange编号 :pagehide 是同步的,但基础写可能不是:

  • 与 同步 后端( e)'local', (中文(简体) ), 'session') 冲洗完成之前 所以最后的写作是安全的.
  • 与 一个同步 后端( e)'indexed'只有冲浪 开始 书写 浏览器可以在索引DB交易发生前关闭页面,损失最多 最近取消的更改。 浏览器不会给出原始的等待写入 卸下,所以这是内在的而不是虫子.

visibilitychange → hidden 火更早,更可靠 比 pagehide (特别是在手机上,背景标签在无 pagehide),所以这个 是真正的保存点。 将损失窗口进一步缩放, 降低后端 autoSyncDelay如果写作永远不能丢失,请打电话 await model.save() 明确 而不是依赖卸货冲出.

活动

import { EventEmitter } from '@converse/skeletor';

class Store extends EventEmitter {}

const store = new Store();
store.on('update', (data) => console.log('Updated:', data));
store.trigger('update', { key: 'value' });

// Listen to another object's events (auto-cleaned up with stopListening)
const view = new EventEmitter();
view.listenTo(store, 'update', (data) => console.log('View saw:', data));
view.stopListening(); // removes all listeners set up via listenTo

// subscribe() returns an unsubscribe function
const unsub = store.subscribe('update', (data) => console.log(data));
unsub();

与反应合并

subscribe() 与 React 直接兼容 useSyncExternalStore数字 :

import { useSyncExternalStore } from 'react';

function UserName({ user }) {
  const attrs = useSyncExternalStore(
    (cb) => user.subscribe(cb),  // subscribe — returns unsub
    () => user.toJSON()          // getSnapshot
  );
  return <span>{attrs.firstName}</span>;
}

图片的特征

导出它提供的东西
Modelget编号 :set, (中文(简体) ), attrs 代理, computed 属性、 更改跟踪、 验证、 服务器同步
Collection完整阵列 API 外加 where, (中文(简体) ), findWhere, (中文(简体) ), pluck, (中文(简体) ), groupBy, (中文(简体) ), keyBy, (中文(简体) ), countBy, (中文(简体) ), sortBy
EventEmitteron编号 :off编号 :trigger编号 :once, (中文(简体) ), listenTo编号 :stopListening, (中文(简体) ), subscribe() 返回未订阅的函数
PersistentStorageIndexedDB, localStorage, sessionStorage, SQLite (节点), 和内元后端. autoSync 用于透明自救和自水合物.
sync基于 HTTP 的低级获取功能( 自定义传输的覆盖)

设计哲学

骨骼师是一个 无头数据层,而不是应用程序状态框架。 是属于你的 域模型 (型号) 以及收藏、它们之间的关系、持久性和服务器同步),并远离您的视图层. 把它绑在什么 让你的UI: 升反应(通过) useSyncExternalStore),或平地DOM.

这一范围是深思熟虑的。 Skeletor没有试图与信号库,Zustand,或Redux竞争一般UI状态. 它的特长是给一个真实的,长寿的应用程序 类型、持久性、可承诺性 数据层 可采用 递增 (以上所有现有的Backbone代码库,无法负担重写).

由此产生的原则:

  • 渐入大爆炸. 每个特性都是选择入和倒相兼容的. 通过 attrs, (中文(简体) ), computed, (中文(简体) ), subscribe,或 autoSync 一个模型或一个呼叫站点一次;没有什么迫使迁移.
  • 承诺能力,召回兼容. Async 操作返回承诺, 而 Backbone 风格 success编号 :error 调用和事件继续工作. 新代码可以 await旧代码不会破解.
  • 遗传,不要重复. computed 用缓存和自动变化事件表达一次衍生值.
  • 无头和框架不可知论. 没有视图,没有路由器,没有框架假设. 反应表面是 change 活动及 subscribe()。 。 。 .
  • 诚实的权衡. 无法作出保证的地方(例如,在页面卸载时保持同步) 书中说得很清楚 而不是暗示不存在的耐久性(见下面的注释) 地方持久性) (中文(简体) ).

什么时候用

  • 你正在更新Backbone时代的应用程序 想要一个没有重写 的、可承诺的数据层.
  • 您想要一个无头存储, 内置的持久性, 绑定在任何UI框架上 .
  • 你的状态是真的 域数据 ——具有身份,关系和持续生命周期的实体.

什么时候才能找到别的东西

  • 你想要反应,自动跟踪依赖性并更新单个绑定——这就是信号给你的. 骨架通知每个属性(change:foo)),但你将每个反应自己电线接通,它会在组件颗粒分解时重新发回.
  • 您的"状态"大多是平面视图状态(形式输入,切换,徘徊)——保留在您的视图层中.
  • 你需要时间旅行,结构共享,或者一个严格的不可改变的单层建筑——这就是Redux的地盘.

方向

骨骼器正在从内部而不是被取而代之地现代化。 轨迹是 承诺第一核心 事件和召回作为兼容性shim和反应模型 连接到信号. 目的是让消费者永远不会面临移民。 图书馆在它们下面进行现代化改造 而公众表面保持稳定, 而今天存在的 Backbone 兼容性 并没有牺牲到那里.

从后骨移走

如果您已有 Backbone 工程, 您可以递增迁移数据层 :

  1. 安装骨骼 : npm install @converse/skeletor
  2. 替换 import Backbone from 'backbone' 带有名称的进口: import { Model, Collection } from '@converse/skeletor'
  3. 替换 Backbone.Model.extend({...}) 与 class MyModel extends Model { ... }
  4. 修复下面列出的少数被移除或重新命名的方法
  5. 继续使用 Backbone 查看、路由器和历史——它们不受影响

你的观点和路由器根本不需要改变 骨骼模型和收藏会发出同样的事件 Backbone 做的.

从 Backbone 更改

现代化

  • 在 TypeScript 有完整类型定义的重写
  • 取消了对 j 查询的依赖
  • 已替换 下划线 与 摇篮,用于刮树的单项进口
  • 尽可能使用本地浏览器 API 而不是 lodash
  • 放弃对旧浏览器(包括 IE )的支持; 需要 ES6+
  • 各类Model, (中文(简体) ), Collection)是ES6类——使用 class extends 改为 .extend()
  • 添加数 EventEmitter 混合类(取代旧的) Events 构造函数)
  • Async 操作返回承诺
  • CJS同时提供无害环境管理
  • attrs 直接反应属性访问的代理
  • computed 带有缓存和自动更改事件的属性
  • subscribe() 返回所有被动对象上的未订阅函数

被移除的东西

  • View 财务报告和审定财务报表 ElementView ——单独管理您的用户界面
  • Router 财务报告和审定财务报表 History ——使用浏览器的历史 API 或专用路由器库
  • .extend() 静态方法——使用 class MyModel extends Model 换成
  • clone() 模型——使用 new MyModel(model.toJSON()) 换成
  • chain() 财务报告和审定财务报表 escape() 模型
  • inject, (中文(简体) ), foldl, (中文(简体) ), foldr 关于收藏-使用 reduce 换成
  • sample, (中文(简体) ), take, (中文(简体) ), tail, (中文(简体) ), initial 收藏时
  • without, (中文(简体) ), reject, (中文(简体) ), select 关于收藏-使用 filter 换成
  • partition 财务报告和审定财务报表 invokeMap 收藏时

方法重命名( 分数 ~ Lodash)

旧( 低于)新建( 洛达什)
restdrop
indexBykeyBy
invokeinvokeMap (当时已去除-使用) map(中文(简体) )
containsincludes

其他行为变化

  • Collection.prototype.forEach 不再返回过时的项目。 使用 map 换句话说.
  • Model.prototype.set 返回时 null (无) false当验证失败时.
  • Collection.prototype.create 返回时 null (无) boolean关于失败.

版本与发布记录

@converse/skeletor 共发布 23 个版本,首次发布于 2020/06/09;过去 12 个月发布了 14 个版本。

版本发布日期距今
4.0.2latest2026/11/055 天前
4.0.12026/10/2814 天前
4.0.02026/10/2517 天前
3.1.62026/08/063 个月前
3.1.52026/07/223 个月前
3.1.42026/06/234 个月前

关于 @converse/skeletor 的常见问题

@converse/skeletor 是什么?

现代网络应用的模型和收藏

如何安装 @converse/skeletor?

在项目目录运行 npm install @converse/skeletor,或使用 pnpm add / yarn add / bun add。

@converse/skeletor 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@converse/skeletor 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@converse/skeletor 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@converse/skeletor 可以商用吗?

@converse/skeletor 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@converse/skeletor 的下载量有多少?

根据 npm 官方下载统计,@converse/skeletor 在 2026/10/11 – 2026/11/09 这 30 天内被下载 3,324 次,日均约 111 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@converse/skeletor 还在维护吗?

最新版本 4.0.2 发布于 2026/11/05(5 天前);至今共发布 23 个版本,其中过去 12 个月发布了 14 个;首次发布于 2020/06/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。