☰
TinyBase 创建 Store 实战指南:createStore 用法与源码级原理解析
2026/10/13 6:34:06 网站建设 项目流程
  • 数据库
  • 后端
  • 前端

【免费下载链接】tinybase

A reactive data store & sync engine.

项目地址:https://gitcode.com/gh_mirrors/ti/tinybase
点击查看免费下载

本指南是 TinyBase 入门系列的基础一环,围绕官方文档 Creating A Store 展开:教你用一行createStore()调用创建出全新的 Store 实例,验证其初始的空状态,并深入源码理解 Store 在 TinyBase 内部是如何被构建出来的。读完本指南,你将掌握创建 Store 的标准姿势、Store 的数据模型(Tables 与 Values),以及 Store 接口提供的完整方法家族,为后续的读写、监听与持久化打好基础。

环境准备:从哪里导入 createStore

createStore是 TinyBase 的核心入口函数,从tinybase包(即本仓库的 package.json 所定义的模块)顶层即可导入。仓库根入口 src/index.ts 显式地 re-export 了./store/index.ts,因此:

import {createStore} from 'tinybase'; const store = createStore();

就这么简单——创建 Store 只需要这一次函数调用,不需要任何配置参数或初始化选项。返回的store是一个完整可用的 Store 实例,初始数据自然是空的。官方入门指南 Getting Started 给出了三种搭建运行环境的方式:

  • 模板脚手架:npm create tinybase@latest,可生成 Todos、Chat、Drawing、Charting、Tic-tac-toe 等示例应用,并可选 TypeScript/JavaScript、SQLite/PGlite 持久化、远程同步等配置;
  • 浏览器 CDN:在 HTML 中用<script type="importmap">声明{"imports": {"tinybase": "https://esm.sh/tinybase@"}},即可在模块脚本里正常import {createStore} from 'tinybase';
  • Node 应用:npm install tinybase后,在.mjs模块脚本中直接导入使用。

官方要求环境较为现代(Node 16 及以上或常更新的浏览器),因为 TinyBase 大量使用了当代 JavaScript 特性;如需更老的兼容目标,发行包里还提供了es6目录下的额外转译产物。

验证空 Store:getValues 与 getTables

创建完成后,Store 中没有任何数据。用读取方法即可验证:

console.log(store.getValues()); // -> {} console.log(store.getTables()); // -> {}

getValues()返回键值型数据集合(Values),getTables()返回表格型数据集合(Tables),初始都为空对象。这两个方法是 Store 接口中最基础的读取入口,其声明位于 Store 接口 中。

Store 的数据模型:两层数据结构

要理解"空"的含义,先要明白 Store 里能装什么。从类型声明 src/@types/store/index.d.ts 可以看到,Store 的内容(Content)由两部分组成:

export type Content = [Tables, Values]; export type Tables = {[tableId: Id]: Table}; export type Table = {[rowId: Id]: Row}; export type Row = {[cellId: Id]: Cell}; export type Cell = string | number | boolean | null | AnyObject | AnyArray; export type Values = {[valueId: Id]: Value}; export type Value = string | number | boolean | null | AnyObject | AnyArray;

其中Id即字符串类型(见 common 类型)。用官方文档 Writing To Stores 的层次化描述来理解:

  • Values(键值数据):Id/值 的简单键值对集合;
  • Tables(表格数据):四层嵌套结构——Store 的 Tables 对象包含多个 Table,每个 Table 包含多个 Row,每个 Row 包含多个 Cell。

Cell 和 Value 的取值可以是字符串、数字、布尔值或null;更丰富的数据可以存为普通 JavaScript 对象或数组,TinyBase 内部会将其编码为 JSON 字符串(此细节详见 Writing To Stores 指南中的编码与校验规则)。正因为新创建的 Store 里这两层容器都是空对象,所以getValues()与getTables()才分别返回{}。

源码级解析:createStore 到底做了什么

createStore的实现位于 src/store/index.ts,它是一个典型的工厂闭包:调用时不接收任何参数,返回一个通过闭包持有全部内部状态的对象字面量。类型声明侧(src/@types/store/index.d.ts)同样印证了这一点:

export function createStore(): Store;

从源码结构可以推断,createStore内部初始化了大量以mapNew()/setNew()方式创建的空映射,例如:

  • tablesMap、valuesMap——实际数据存储容器;
  • tablesSchemaMap、valuesSchemaMap——Schema 校验与默认值缓存;
  • 一系列*Listeners集合与Pair<IdSet>结构——为监听器系统(addListener/callListeners/delListenerImpl)准备的注册表;
  • changedTableIds、changedRowIds、changedCellIds、changedValues等——事务期间变更追踪用的临时结构;
  • middleware数组、internalListeners数组——中间件与内部钩子的挂载点。

同时它会通过getListenerFunctions(() => store)构建监听器工具函数,并定义whileMutating、whileAcceptingEncodedData等执行上下文包装器。也就是说,一次createStore()调用就把数据存储、Schema 校验、监听器注册表、事务追踪、中间件插槽、JSON 编解码等整套运行时基础设施一次性搭好,Store 的"响应式"能力(事件通知)从出生那一刻起就已就位。

最终函数返回一个对象字面量,把getTables/getValues/setTables/transaction/addCellListener等约几十个方法逐一挂到store上,并在_字段中放置一组"受保护方法"(ProtectedMethods),供 TinyBase 内部其他模块(如持久化、同步)通过受控通道调用;同时显式声明isMergeable: () => false——普通 Store 并非可合并(mergeable)类型,需要合并能力时得使用独立的mergeable-store模块。

Store 接口方法全景

一旦 Store 创建完成,即可使用其全部方法。以接口声明 src/@types/store/index.d.ts 为准,可以按职责分为几类:

  • 读取:getContent()、getTables()、getTable()、getRow()、getCell()、getValues()、getValue(),以及getTableIds()、getRowIds()、getCellIds()、getValueIds()等 Id 枚举方法;
  • 写入:setContent()、setTables()、setTable()、setRow()、setCell()、setValues()、setValue(),配合setPartialRow()、setPartialValues()、addRow()等便捷方法(详见 Writing To Stores 指南);
  • 删除:delTables()、delTable()、delRow()、delCell()、delValues()、delValue();
  • 事务:transaction()、startTransaction()、finishTransaction()、getTransactionChanges()、getTransactionLog()(详见 Transactions 指南);
  • 监听:addValuesListener()、addTableListener()、addCellListener()、addRowListener()、addStartTransactionListener()、addDidFinishTransactionListener()等,以及delListener()、getListenerStats()(详见 Listening To Stores 指南);
  • Schema 与 JSON:setTablesSchema()、setValuesSchema()、setSchema()、getTablesSchema(),以及getJson()、setJson()、setTablesJson()等序列化入口;
  • 遍历与杂项:forEachTable()、forEachRow()、forEachCell()、forEachValue()、clear()、getListenerStats()、isMergeable()。

其中所有 setter 方法都遵循链式调用约定(返回this),这一点在实现源码中随处可见,例如 src/store/index.ts 的setTablesJson、src/store/index.ts 的delListener等都以return store结尾,方便连续书写。单元测试中也大量使用了这种链式写法,例如 store-advanced.test.ts 中的createStore().setTables({...}),可直接作为用法参考。

创建之后的下一步

Store 创建完成、数据模型了然于胸之后,本仓库的入门系列已经为你规划好了完整的学习路线:

  1. 写入数据:Writing To Stores——用setValues/setTables及各级 setter 填充数据,理解删除与级联删除规则;
  2. 读取数据:Reading From Stores——用各级 getter 取回数据;
  3. 响应变更:Listening To Stores——注册监听器让 UI 随数据变化自动更新,这正是 TinyBase 被称为"reactive data store"的原因;
  4. 批量操作:Transactions——把多个写操作打包成原子事务;
  5. 进阶话题:Importing TinyBase、TinyBase And TypeScript、Architectural Options。

小结

创建 Store 是使用 TinyBase 的第一步,也是构建响应式数据应用的地基:import {createStore} from 'tinybase'之后,你便拥有一个自带事件系统、事务机制、Schema 校验与 JSON 编解码能力的空数据容器。本指南不仅复现了官方文档的完整操作,还从 src/store/index.ts 的工厂实现与 Store 类型声明 出发,揭示了createStore的内部构建逻辑与 Store 的完整方法面。接下来,请按上面的路线图继续探索写入与读取,让数据真正流动起来。

  • 数据库
  • 后端
  • 前端

【免费下载链接】tinybase

A reactive data store & sync engine.

项目地址:https://gitcode.com/gh_mirrors/ti/tinybase
点击查看免费下载

相关推荐

上一篇:定制 EcoPaste 本地 Trellis 工程规范结构:新增 Spec 层、调整包映射与任务上下文
下一篇:Flink DataStream 连接器容错保证全解析:从 Source 状态更新到 Sink 端到端精确一次

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询