@cccteam/resource-firestore

中文文档
0.0.23发布于 2026/11/04TypeScriptES Module构建来源已验证近 30 天下载 5066

The Firestore change feed for live pages over @cccteam/resource

原始使用文档
文档目录4 节
  1. Use
  2. What the feed does
  3. What is configurable
  4. Testing

@cccteam/resource-firestore

The Firestore change feed for live pages over @cccteam/resource. A page that asks for a live list or a live row stays current without polling: the server writes one change document per subscribed user into that user's change set, and this feed is the one listener per tab that reads it and hands each change to the client's live session, which refetches the row or list the change names. It is the only package of the three that depends on the firebase JS SDK; the client stays free of it.

What a page opts into, what it costs, and what it never does are in the client's README under "Live pages". This package adds nothing to that contract; it is one way of delivering the changes, and the client is written so another could replace it.

npm install @cccteam/resource @cccteam/resource-firestore firebase

firebase is a peer dependency: the application installs it once, so one copy of the SDK serves the feed and anything else the application does with Firebase.

Use

Build the feed and hand it to the client's live session once the session is authenticated; stop the session at logout, before the session itself is logged out.

import { firestoreChangeFeed } from '@cccteam/resource-firestore';

const api = createApi({ baseUrl: '/api' });
await api.live.start(firestoreChangeFeed());
// ...
await api.live.stop();

An Angular application provides it instead, and AuthService starts and stops it:

import { CHANGE_FEED } from '@cccteam/resource-angular/types';
import { firestoreChangeFeed } from '@cccteam/resource-firestore';

providers: [{ provide: CHANGE_FEED, useFactory: () => firestoreChangeFeed() }];

What the feed does

start(identity) receives what the server minted for the session's principal at GET <prefix>/live/token: the GCP project, the Firestore database, and either the emulator or a custom token. It initializes a Firebase app of its own for the project (and the web API key, in production), opens the database, and connects as the user: against the emulator, with the SDK's mock user token for the uid (connectFirestoreEmulator(db, host, port, { mockUserToken: { sub: uid, user_id: uid } })); in production, by signing the custom token in through Firebase Auth on an auth held in memory only: the identity is minted for the session and revoked at stop, so nothing of it is written to the browser's storage, and a page load starts with no user to reload. Then it listens to users/{uid}/changes, ordered by at and, once a change has been seen, bounded to the ones after it.

The first snapshot of a listener primes the last change seen and emits nothing. At start, the documents already there predate the page's own first fetch; after an error, the resync the recovery emits already refetches everything. Each later document becomes one ChangeEvent: its kind (row, list, or resource), resource, key, domain, and deleted as the document carries them, and at as unix microseconds in decimal, the version the refetch carries. A document rewritten within its second (the server coalesces writes to one target per second) moves forward and is one more event; a document expiring out of the result set is not.

A quiet stretch is not evidence that anything was missed: the listener keeps its connection and resumes after a drop, and the change documents live ten minutes, so a change is lost only when the listener was down or suspended for longer than that. The feed therefore emits resync on two occasions and no other. When a listener reports an error it delivers nothing more, so the feed starts another after a wait that doubles with each failure (one second, up to thirty), bounded by the last change seen, and the first snapshot of that listener is a resync. And when the page becomes visible again (visibilitychange to visible, or pageshow from the back-forward cache) after having been hidden longer than the change documents live, since browsers throttle or drop a background page's connection, the feed emits a resync. The live session refetches every live row and list by a fresh seed either way, and does the same itself when it starts.

stop() releases the listener, signs the identity out, and deletes the app it initialized. Nothing is remembered across a stop: a later start listens from the beginning again.

The security rules the server leg ships let a user read their own change set and nothing else, and let no client write; the feed never writes.

What is configurable

firestoreChangeFeed(options) takes resyncAfterHidden (how long a page may be hidden before its return is a resync; the change document's life by default), retryDelay and maxRetryDelay (the restart wait), now (the clock), and visibility and page (where the document's visibility and the page's hide and show are heard; the document and the window by default). Every one has a default, and a spec is the usual reason to turn one.

Testing

The specs are written against bun:test and run with bun test projects/resource-firestore/ (the trailing slash keeps bun off the Angular library beside it); bun run typecheck:firestore compiles them with tsc over projects/resource-firestore/tsconfig.spec.json. bun run test:firestore runs both. The specs replace the three SDK modules (firebase/app, firebase/auth, firebase/firestore) with recording stand-ins through mock.module, drive the listener's snapshots and errors by hand, stand in for the document and the window to hide and show the page, and read the events and resyncs back; no Firestore, emulated or real, is involved.

版本与发布记录

@cccteam/resource-firestore 共发布 23 个版本,首次发布于 2026/10/03;过去 12 个月发布了 23 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.0.23latest2026/11/044 天前
0.0.222026/11/035 天前
0.0.212026/11/036 天前
0.0.202026/11/036 天前
0.0.192026/11/027 天前
0.0.182026/10/309 天前

关于 @cccteam/resource-firestore 的常见问题

@cccteam/resource-firestore 是什么?

The Firestore change feed for live pages over @cccteam/resource

如何安装 @cccteam/resource-firestore?

在项目目录运行 npm install @cccteam/resource-firestore,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:firebase(^12.19.0)、@cccteam/resource(^0.0.24)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@cccteam/resource-firestore 支持 TypeScript 吗?

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

@cccteam/resource-firestore 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@cccteam/resource-firestore 可以商用吗?

@cccteam/resource-firestore 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@cccteam/resource-firestore 的下载量有多少?

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

@cccteam/resource-firestore 还在维护吗?

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