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
51 changes: 51 additions & 0 deletions .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Deploy API Docs

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
version: 9

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- run: pnpm install --frozen-lockfile

- run: pnpm run build
working-directory: packages/data

- run: cp -r packages/data/dist packages/data/docs/dist

- uses: actions/upload-pages-artifact@v3
with:
path: packages/data/docs

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
119 changes: 18 additions & 101 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ Adobe Data Oriented Programming Library

## Documentation

[Main Page](https://git.corp.adobe.com/pages/neuralfiltersplatform/firefly-data/docs/api/)
[API Reference](https://adobe.github.io/data/)

[ECS Performance Test](https://git.corp.adobe.com/pages/neuralfiltersplatform/firefly-data/docs/perftest.html)
[ECS Performance Test](https://adobe.github.io/data/perftest.html)

## Breaking API Changes

Expand Down Expand Up @@ -76,7 +76,7 @@ An `Observable<T>` is a subscription function that you can pass a callback funct

Your callback function *may* be called back synchronously (before the initial call returns) zero or one times and asynchronously later any number of times.

For more information see the [Observable API documentation](./docs/api/modules/observe.html)
For more information see the [Observable API documentation](https://adobe.github.io/data/)

### Observable Types

Expand Down Expand Up @@ -181,116 +181,33 @@ Contains some standard data type schemas in JSON Schema format for convenience.

## Entity Component System (ECS)

This ECS database is a high performance, strongly typed typescript implementation inspired by the Sanders Mertens C++ based [Flecs](https://www.flecs.dev/flecs/md_docs_2Docs.html).
A high-performance, strongly typed ECS database for TypeScript, inspired by [Flecs](https://www.flecs.dev/flecs/md_docs_2Docs.html). All application state is modeled as composable plugins, and all mutations flow through observable, undoable transactions.

This library provides two main interfaces for ECS operations: **Store** and **Database**. They share the same read API but differ significantly in their approach to writing and observability.

### Store Interface

The **Store** is the foundational, low-level interface for direct ECS data operations.

**Key Characteristics:**
- **Direct Access**: Provides immediate, synchronous read/write access to entities, components, and resources
- **No Transaction Control**: Changes are applied directly without transaction boundaries
- **No Observability**: Changes are not automatically observable or trackable
- **High Performance**: Minimal overhead for direct operations using Structure of Arrays (SoA) with linear memory layout of numeric types for optimal cache performance
- **Core ECS Operations**: Includes entity creation, component updates, archetype querying, and resource management

**Usage**: Ideal for scenarios requiring fast, direct ECS manipulation where you don't need change tracking or transactional safety.
For a complete guide covering plugins, transactions, observability, composition, and transient/ephemeral semantics, see the **[ECS README](./packages/data/src/ecs/README.md)**.

```typescript
// Create a store with components, resources, and archetypes
const store = createStore(
{
position: Vec3.schema,
health: { type: "number" },
player: { const: true }
},
{
gravity: { default: 9.8 as number }
},
{
Player: ["position", "health", "player"],
Particle: ["position"]
}
);

// Direct operations
const playerId = store.archetypes.Player.insert({
position: [0, 0, 0],
health: 100,
player: true
});
store.update(playerId, { position: [1, 1, 1] });
store.resources.gravity = 10.0;
```

### Database Interface

The **Database** wraps a Store to provide **transaction-based operations** with **full observability**.

**Key Characteristics:**
- **Transaction-Based**: All changes must occur within predefined atomic transactions that can be undone.
- **Full Observability**: Every change is observable through the `observe` API
- **Predefined Operations**: Uses predefined transaction functions rather than direct mutations
- **Undo/Redo Support**: Transactions generate undo/redo operations automatically
- **Change Tracking**: Tracks which entities, components, and archetypes changed
- **Event Notifications**: Automatically notifies observers of changes
import { Database } from "@adobe/data/ecs";

**Usage**: Ideal for applications requiring change history, multiplayer synchronization, undo/redo functionality, or reactive UI updates.

**Important Note**: Even when using a Database, transaction functions are written as direct modifications to the underlying Store interface. The Database wraps these operations to provide transactional guarantees and observability.

```typescript
// Create a database with predefined transactions
const database = createDatabase(store, {
createPlayer(t, args: { position: Vector3, health: number }) {
// Transaction function receives Store interface for direct operations
return t.archetypes.Player.insert({
...args,
player: true
});
const myPlugin = Database.Plugin.create({
resources: {
score: { default: 0 as number },
},
movePlayer(t, args: { entity: Entity, position: Vector3 }) {
// Direct Store operations within transaction context
t.update(args.entity, { position: args.position });
transactions: {
addPoints: (t, points: number) => {
t.resources.score += points;
},
},
setGravity(t, gravity: number) {
// Direct resource modification within transaction
t.resources.gravity = gravity;
}
});

// Execute transactions (these provide observability and undo/redo)
const playerId = database.transactions.createPlayer({
position: [10, 20, 0],
health: 100
});
database.transactions.movePlayer({ entity: playerId, position: [15, 25, 5] });

// Observe all changes
database.observe.transactions((result) => {
console.log('Transaction applied:', result);
console.log('Changed entities:', result.changedEntities);
console.log('Undo operations:', result.undo);
});

// Observe specific entities
database.observe.entity(playerId)((entityData) => {
if (entityData) {
console.log('Player moved to:', entityData.position);
}
});
const db = Database.create(myPlugin);
db.observe.resources.score((score) => console.log("Score:", score));
db.transactions.addPoints(10);
```

### What is an ECS?

Sanders Mertens also covers this thoroughly in his ECS FAQ:
Sanders Mertens covers this thoroughly in his ECS FAQ:

[https://github.com/SanderMertens/ecs-faq?tab=readme-ov-file#what-is-ecs](https://github.com/SanderMertens/ecs-faq?tab=readme-ov-file#what-is-ecs)

In addition to the Entity, Component and System definitions which are standard, we also use the term Resource. A Resource is just a value which is defined globally on the ECS itself and not attached to any specific Entity. You can think of them as a singleton Component.

## Performance Test

[Performance Test](https://git.corp.adobe.com/pages/neuralfiltersplatform/firefly-data/docs/perftest.html)
In addition to the standard Entity, Component, and System definitions, we also use the term **Resource** — a global singleton value defined on the ECS itself, not attached to any specific entity.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-monorepo",
"version": "0.9.47",
"version": "0.9.49",
"private": true,
"scripts": {
"build": "pnpm -r run build",
Expand All @@ -9,7 +9,7 @@
"dev:data": "pnpm --filter @adobe/data run dev",
"link": "pnpm -r --filter @adobe/data* run link",
"publish": "sh -c 'for x in \"$@\"; do OTP=\"$x\"; done; export NPM_CONFIG_OTP=\"$OTP\"; pnpm -r --filter @adobe/data --filter @adobe/data-react --filter @adobe/data-lit run publish-public' sh",
"bump": "pnpm version patch --no-git-tag-version && pnpm -r exec -- pnpm version patch --no-git-tag-version",
"bump": "pnpm version patch --no-git-tag-version && V=$(node -p \"require('$PWD/package.json').version\") && pnpm -r exec pnpm version $V --no-git-tag-version --allow-same-version",
"release": "pnpm bump && pnpm publish",
"bp": "pnpm bump && pnpm run publish"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit-tictactoe/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-lit-tictactoe",
"version": "0.9.47",
"version": "0.9.49",
"description": "Tic-Tac-Toe sample - Lit web components with @adobe/data-lit and AgenticService",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit-todo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-lit-todo",
"version": "0.9.45",
"version": "0.9.49",
"description": "Todo sample app demonstrating @adobe/data with Lit",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-lit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-lit",
"version": "0.9.47",
"version": "0.9.49",
"description": "Adobe data Lit bindings - hooks, elements, decorators",
"type": "module",
"private": false,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react-hello/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-react-hello",
"version": "0.9.47",
"version": "0.9.49",
"description": "Hello World sample - click counter using @adobe/data-react",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react-pixie/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "data-react-pixie",
"version": "0.9.47",
"version": "0.9.49",
"description": "PixiJS React sample - ECS sprites (bunny, fox) with @adobe/data-react",
"type": "module",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion packages/data-react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adobe/data-react",
"version": "0.9.47",
"version": "0.9.49",
"description": "Adobe data React bindings — hooks and context for ECS database",
"type": "module",
"private": false,
Expand Down
Loading