@eidos.space/core
v0.28.4
Published
core package for eidos.space
Downloads
243
Maintainers
Readme
@eidos.space/core
[Experimental] Core functionality package for Eidos - A runtime-agnostic personal data management framework
Features
- 🚀 Runtime-agnostic - Works in Deno, Bun, Node.js, Browser, and more
- 🔌 Adapter pattern - Pluggable database and filesystem implementations
- 🗄️ SQLite-powered - Efficient local-first data storage
- 📝 Rich APIs - Table operations, document management, tree structures
- 🎯 Headless mode - Perfect for CLI tools and server-side automation
- 🔒 Type-safe - Written in TypeScript with full type definitions
Installation
# npm
npm install @eidos.space/core
# pnpm
pnpm add @eidos.space/core
# yarn
yarn add @eidos.space/coreQuick Start
Basic Setup
import { DataSpace } from "@eidos.space/core"
// 1. Initialize database adapter (example with your custom adapter)
const db = new YourDatabaseAdapter("./data.sqlite3")
// 2. Create DataSpace instance
const dataSpace = new DataSpace({
db: db,
activeUndoManager: false,
dbName: "my-workspace",
context: {
setInterval: undefined, // Runtime-specific APIs
},
efsManager: new YourFileSystemManager(),
})Working with Tables
// Query all rows from a table
const rows = await dataSpace.table("tasks").rows.query()
// Query with filters
const completedTasks = await dataSpace.table("tasks").rows.query({
where: { status: "completed" },
})
// Create a new row
await dataSpace.table("tasks").rows.create({
title: "New Task",
status: "pending",
priority: "high",
})
// Update a row
await dataSpace.table("tasks").rows.update("row-id", {
status: "completed",
})
// Delete a row
await dataSpace.table("tasks").rows.delete("row-id")Document Management
// Get a document
const doc = await dataSpace.doc.get("document-id")
// Full-text search across documents
const results = await dataSpace.doc.search("project planning")
// Create a document
await dataSpace.doc.create({
title: "Meeting Notes",
content: "...",
})Tree Structure Operations
// List all nodes in the tree
const allNodes = await dataSpace.tree.list()
// Get node details
const node = await dataSpace.tree.getNode("node-id")
// Create a new node
await dataSpace.tree.createNode({
name: "New Folder",
type: "folder",
parentId: "parent-node-id",
})Schema Import / Export (UI Features)
The Eidos UI provides first-class support for sharing table structures without copying data:
Exporting a Schema
Right-click any table in the sidebar → Export → Copy Schema.
This copies a base64-encoded string to your clipboard. The string encodes only the table structure (name + field definitions), not the row data — making it safe and compact to share via chat, email, or a config file.
Internally this calls:
const schema = await eidos.currentSpace.schema.exportSchema(tableId)
// schema: { version: 1, name: string, fields: CreateFieldInput[] }
const encoded = btoa(
encodeURIComponent(JSON.stringify(schema)).replace(
/%([0-9A-F]{2})/g,
(_, p1) => String.fromCharCode(parseInt(p1, 16))
)
)
// encoded: "eyJ2ZXJzaW9uIjox..."Importing a Schema
Press ⌘K / Ctrl+K to open the command palette, then search for "Import Table Schema" and press Enter.
Paste the base64 string into the dialog — you'll see a live preview of the table name and fields before confirming.
Internally this calls:
const schema = JSON.parse(
decodeURIComponent(
atob(encoded)
.split("")
.map((c) => "%" + c.charCodeAt(0).toString(16).padStart(2, "0"))
.join("")
)
)
const table = await eidos.currentSpace.schema.import(schema)Programmatic API (Scripts / Extensions)
Both operations are available as first-class methods on SchemaClient:
// Export
const schema = await eidos.currentSpace.schema.export(tableId)
// Returns: { version: 1, name: string, fields: CreateFieldInput[] }
// Import (creates a new table from the schema)
const table = await eidos.currentSpace.schema.import(schema)
// Optional: override the name
const copy = await eidos.currentSpace.schema.import(schema, "My Copy")API Reference
DataSpace
The main entry point for interacting with your data:
Table Operations
dataSpace.table(tableId)- Get a table instance.rows.query(options?)- Query rows with optional filters.rows.create(data)- Create a new row.rows.update(rowId, data)- Update a row.rows.delete(rowId)- Delete a row
Document Operations
dataSpace.doc.get(docId)- Get a document by IDdataSpace.doc.search(query)- Full-text searchdataSpace.doc.create(data)- Create a new document
Tree Structure
dataSpace.tree.list()- List all nodesdataSpace.tree.listNodes()- Alternative list methoddataSpace.tree.getNode(nodeId)- Get a specific nodedataSpace.tree.createNode(data)- Create a new node
Schema Operations
dataSpace.schema.createTable(input)- Create a new table with fieldsdataSpace.schema.getTable(tableId)- Get table info (name, fields, views)dataSpace.schema.listTables()- List all tablesdataSpace.schema.updateTable(tableId, input)- Rename tabledataSpace.schema.deleteTable(tableId)- Delete tabledataSpace.schema.addField(tableId, input)- Add a field to a tabledataSpace.schema.updateField(tableId, columnName, input)- Update field metadatadataSpace.schema.deleteField(tableId, columnName)- Remove a fielddataSpace.schema.listFields(tableId)- List all fields in a tabledataSpace.schema.createView(tableId, input)- Create a viewdataSpace.schema.listViews(tableId)- List all viewsdataSpace.schema.deleteView(tableId, viewId)- Delete a viewdataSpace.schema.export(tableId)- Export table schema as portableTableSchemaExportobjectdataSpace.schema.import(schema, nameOverride?)- Create a new table from an exported schema
Architecture
BaseServerDatabase Abstract Class
The core abstract class defines standard interfaces for database interactions:
abstract class BaseServerDatabase {
filename?: string
abstract prepare(sql: string): any
abstract close(): void
abstract selectObjects(
sql: string,
bind?: any[]
): Promise<{ [columnName: string]: any }[]>
abstract transaction(func: (db: BaseServerDatabase) => void): any
abstract exec(opts: any): Promise<any>
abstract createFunction(opt: {
name: string
xFunc: (...args: any[]) => any
}): any
}Runtime Adapters
Each JavaScript runtime requires its own adapter implementation:
// Example: Deno adapter
import { Database } from "jsr:@db/[email protected]"
export class DenoServerDatabase implements BaseServerDatabase {
db: Database
constructor(path: string) {
this.db = new Database(path)
}
prepare(sql: string) {
return this.db.prepare(sql)
}
// ... implement other methods
}
// Example: Node.js adapter with better-sqlite3
import Database from "better-sqlite3"
export class NodeServerDatabase implements BaseServerDatabase {
db: Database.Database
constructor(path: string) {
this.db = new Database(path)
}
// ... implement required methods
}Supported Environments
| Runtime | SQLite Library | Status |
| ------------------ | ------------------------- | --------------- |
| Browser | @sqlite.org/sqlite-wasm | ✅ Supported |
| Node.js | better-sqlite3 | ✅ Supported |
| Deno | @db/sqlite | ✅ Supported |
| Bun | bun:sqlite | 🔄 Experimental |
| Cloudflare Workers | D1 | 🔄 Experimental |
Advanced Usage
Custom Database Adapter
Implement the BaseServerDatabase interface for your runtime:
import { BaseServerDatabase } from "@eidos.space/core"
export class CustomDatabaseAdapter extends BaseServerDatabase {
// Implement required methods based on your SQLite library
prepare(sql: string) {
/* ... */
}
close() {
/* ... */
}
selectObjects(sql: string, bind?: any[]) {
/* ... */
}
transaction(func: Function) {
/* ... */
}
exec(opts: any) {
/* ... */
}
createFunction(opt: { name: string; xFunc: Function }) {
/* ... */
}
}Custom Filesystem Manager
Implement filesystem operations for your environment:
export class CustomFileSystemManager {
// Implement file operations
async read(path: string): Promise<Uint8Array> {
/* ... */
}
async write(path: string, data: Uint8Array): Promise<void> {
/* ... */
}
async delete(path: string): Promise<void> {
/* ... */
}
// ... other file operations
}Use Cases
- 📱 CLI Tools - Build command-line tools with local data storage
- 🤖 Automation Scripts - Automate data processing workflows
- 🌐 Server-side Apps - Use as backend data layer
- 📊 Data Analysis - Process and analyze personal data
- 🔄 Data Migration - Move data between different systems
- 🧪 Testing - Create test environments with isolated data
Project Status
⚠️ Experimental - This package is under active development. APIs may change between versions. Use with caution in production environments.
Related Projects
- Eidos - The main Eidos application
- Eidos Desktop - Desktop application
- Eidos Web App - Web application
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Support
- 📖 Documentation
- 💬 Discord Community
- 🐛 Issue Tracker
- 📧 Email: [email protected]
License
MIT License - see the LICENSE file for details.
Copyright (c) 2025 mayneyao
