Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lazy-trees-lie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'fireworkers': minor
---

feat: add batch write operations and unit test suite
5 changes: 5 additions & 0 deletions .firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "test-project"
}
}
37 changes: 34 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,42 @@ name: CI

on:
pull_request:
branches:
- master
Comment thread
besart-finsweet marked this conversation as resolved.
- main

jobs:
Lint:
uses: finsweet/workflow-ci-lint/.github/workflows/lint.yml@main

# Comment this job out if your project doesn't have any tests.
# Tests:
# uses: finsweet/workflow-ci-test/.github/workflows/test.yml@main
Typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm check

Unit-Tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 10
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 21
- run: pnpm install --frozen-lockfile
- run: pnpm test:unit
79 changes: 79 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,85 @@ const todos = await Firestore.query(db, {
});
```

### batch(db)

Creates a write batch, used for performing multiple writes as a single atomic unit.

Implements the same functionality as Firestore's [writeBatch](https://firebase.google.com/docs/reference/js/firestore_.md#writebatch).

#### db

Type: `DB`

The DB instance.

#### batch.set(paths, fields, options?)

Adds a set operation to the batch. If the document does not yet exist, it will be created. If you provide `merge: true`, the provided fields will be merged into the existing document.

- `paths` — Type: `string[]` — The path segments to the document (e.g. `['todos', 'my-id']`).
- `fields` — Type: `Record<string, any>` — The fields to write.
- `options.merge` — Type: `boolean` (optional) — If `true`, merges into an existing document.

#### batch.update(paths, fields)

Adds an update operation to the batch. The document must already exist.

- `paths` — Type: `string[]` — The path segments to the document.
- `fields` — Type: `Record<string, any>` — The fields to update.

#### batch.delete(paths)

Adds a delete operation to the batch.

- `paths` — Type: `string[]` — The path segments to the document.

#### batch.commit()

Commits all of the writes in this write batch as a single atomic unit. Returns a `CommitResponse` with `writeResults` and `commitTime`.

A batch can only be committed once. After `commit()` is called, any further calls to `set`, `update`, `delete`, or `commit` will throw an error.

```typescript
const b = Firestore.batch(db);

b.set(['todos', 'todo-1'], { title: 'First', completed: false });
b.set(['todos', 'todo-2'], { title: 'Second', completed: true });
b.update(['todos', 'existing-id'], { completed: true });
b.delete(['todos', 'old-id']);

const response = await b.commit();
```

---

## Testing

Unit tests run against the [Firebase Emulator Suite](https://firebase.google.com/docs/emulator-suite) using [Vitest](https://vitest.dev/).

### Prerequisites

- [Java](https://www.java.com/) (required by the Firebase Emulator)
- [Firebase CLI](https://firebase.google.com/docs/cli) (installed as a dev dependency)

### Running tests

Run the full test suite (starts the emulator automatically):

```bash
pnpm test:unit
```

Run tests in watch mode (requires the emulator to be running separately):

```bash
# Terminal 1 — start the emulator
pnpm emulators

# Terminal 2 — run tests in watch mode
pnpm test:unit:watch
```

## TypeScript

This library has first-class TypeScript support.
Expand Down
15 changes: 15 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"firestore": {
"rules": "firestore.rules"
},
"emulators": {
"firestore": {
"port": 8080,
"host": "127.0.0.1"
},
"ui": {
"enabled": true,
"port": 4000
}
}
}
8 changes: 8 additions & 0 deletions firestore.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,15 @@
"format": "prettier --write ./src",
"test": "pnpm playwright test",
"test:headed": "pnpm playwright test --headed",
"test:unit": "firebase emulators:exec --only firestore --project test-project \"vitest run\"",
"test:unit:watch": "vitest",
"emulators": "firebase emulators:start --only firestore --project test-project",
"release": "changeset publish",
"update": "pnpm update -i -L -r"
},
"devDependencies": {
"firebase-tools": "15.15.0",
"vitest": "3.0.0",
"@changesets/changelog-git": "^0.2.0",
"@changesets/cli": "^2.27.12",
"@eslint/js": "^9.19.0",
Expand Down
Loading
Loading