@delma/fylo 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,113 +1,3 @@
1
- # FYLO Project Guidelines
1
+ Follow the shared workspace instructions in `../instructions.md` and shared context in `../memory.md`.
2
2
 
3
- ## Overview
4
-
5
- FYLO (`@vyckr/fylo`) is an S3-backed NoSQL document store with SQL parsing, Redis pub/sub for real-time events, and a CLI. Documents are stored as S3 key paths — not as file contents — with dual key layouts for data access and indexed queries.
6
-
7
- **Assume a serverless deployment model** (e.g., AWS Lambda, Cloudflare Workers). This means:
8
- - No persistent in-memory state across invocations — every request starts cold
9
- - Distributed coordination (e.g., TTID uniqueness) must use external stores like Redis, not in-process caches
10
- - Avoid long-lived connections, background threads, or singleton patterns that assume process longevity
11
- - Keep cold-start overhead minimal — lazy initialization over eager setup
12
-
13
- ## Architecture
14
-
15
- ### Key Storage Format
16
-
17
- - **Data keys**: `{ttid}/{field}/{value}` — keyed by document ID for full-doc retrieval
18
- - **Index keys**: `{field}/{value}/{ttid}` — keyed by field for query lookups
19
- - Nested objects flatten to path segments: `address/city/Toronto`
20
- - Forward slashes in values are escaped with an ASCII substitute
21
-
22
- ### Core Modules
23
-
24
- | Module | Responsibility |
25
- |--------|---------------|
26
- | `src/index.ts` | Main `Fylo` class — CRUD, SQL execution, joins, bulk ops |
27
- | `src/core/parser.ts` | SQL lexer/parser — tokenizes SQL into query objects |
28
- | `src/core/query.ts` | Converts `$ops` into glob patterns for S3 key matching |
29
- | `src/core/walker.ts` | S3 key traversal, document data retrieval, Redis event streaming |
30
- | `src/core/directory.ts` | Key extraction, reconstruction, rollback tracking |
31
- | `src/core/format.ts` | Console formatting for query output |
32
- | `src/adapters/s3.ts` | S3 adapter (Bun S3Client) |
33
- | `src/adapters/redis.ts` | Redis adapter (Bun RedisClient) |
34
- | `src/cli/index.ts` | CLI entry point (`fylo.query`) |
35
-
36
- ### Folder Structure
37
-
38
- ```
39
- src/
40
- index.ts # Public API — main Fylo class
41
- adapters/ # I/O boundary abstractions (S3, Redis)
42
- core/ # Internal domain logic (parser, query, walker, directory)
43
- cli/ # CLI entry point
44
- types/ # Type declarations (.d.ts only — separate from implementation)
45
- tests/
46
- data.ts # Shared test data URLs
47
- index.ts # Test barrel
48
- mocks/ # Mock adapters (S3, Redis) for testing
49
- schemas/ # CHEX-generated test schemas (.d.ts + .json)
50
- integration/ # End-to-end tests (CRUD, operators, joins, edge cases)
51
- ```
52
-
53
- ### Dependencies
54
-
55
- - **`@vyckr/ttid`** — Time-based unique ID system. `TTID.generate()` creates new IDs; `TTID.generate(existingId)` creates a versioned ID sharing the same creation-time prefix.
56
- - **`@vyckr/chex`** — Schema validation. Generates `interface` declarations in `.d.ts` files. Generic constraints must use `Record<string, any>` (not `Record<string, unknown>`) to accept these interfaces.
57
- - **`Bun.Glob`** — Pattern matching for queries. Does NOT support negation extglob `!(pattern)`. Operators like `$ne`, `$gt`, `$lt` use broad globs with post-filtering instead.
58
-
59
- ## Engineering Standards
60
-
61
- - **SOLID principles**: Single responsibility per class/method, depend on abstractions (e.g., S3/Redis adapters), open for extension without modifying core logic
62
- - **Clean code**: Descriptive naming, small focused functions, no dead code or commented-out blocks, DRY without premature abstraction
63
- - **Test discipline**: When changing `src/` code, update or add corresponding tests in `tests/` — never leave tests stale after a behaviour change
64
- - **Error handling**: Fail fast with meaningful errors at system boundaries; use rollback mechanisms for partial writes
65
- - **No magic values**: Use constants or environment variables; avoid hardcoded strings/numbers in logic
66
- - **Type safety**: Leverage TypeScript's type system fully — avoid `any` in implementation code, prefer narrow types, and validate at I/O boundaries
67
-
68
- ## Code Style
69
-
70
- - **Runtime**: Bun (ESNext target, ES modules)
71
- - **Strict TypeScript**: `strict: true`, `noImplicitReturns`, `isolatedModules`
72
- - **ESLint** enforces `@typescript-eslint/no-explicit-any` in `src/` and `tests/` — use it only in type declarations (`.d.ts`)
73
- - **No default exports** except the main `Fylo` class
74
- - Prefer `class` with `static` methods for modules (no standalone functions)
75
- - Use `_ttid` branded type for document IDs — never plain `string`
76
- - Prefix internal/test type names with underscore: `_post`, `_album`, `_storeQuery`
77
- - Type declarations live in `src/types/*.d.ts` — keep separate from implementation
78
-
79
- ## Build & Test
80
-
81
- ```bash
82
- bun test # Run all tests
83
- bun run build # Compile TypeScript
84
- bun run typecheck # Type-check without emitting
85
- bun run lint # ESLint
86
- ```
87
-
88
- - Tests use `bun:test` — `describe`, `test`, `expect`, `mock`, `beforeAll`, `afterAll`
89
- - S3 and Redis are mocked via `mock.module()` in every test file using `tests/mocks/s3.ts` and `tests/mocks/redis.ts`
90
- - Test schemas live in `tests/schemas/*.d.ts` as global `interface` declarations (generated by CHEX)
91
- - Test data URLs are centralized in `tests/data.ts`
92
-
93
- ## Conventions
94
-
95
- - Collection names may contain hyphens (e.g., `ec-test`, `jm-album`) — the parser supports this
96
- - Nested field access in SQL uses dot notation (`address.city`) which the parser converts to slash-separated paths (`address/city`)
97
- - `putData` creates documents; `patchDoc` updates them (deletes old keys, writes new ones)
98
- - `getDocData` retrieves keys for a specific TTID — filters by exact ID, not just prefix
99
- - Query `$ops` use OR semantics — a document matches if it satisfies at least one operator
100
- - `$limit` on queries without `$ops` uses S3 `maxKeys`; with `$ops` it post-filters after glob matching
101
-
102
- ## Environment Variables
103
-
104
- | Variable | Purpose |
105
- |----------|---------|
106
- | `BUCKET_PREFIX` | S3 bucket name prefix |
107
- | `S3_ACCESS_KEY_ID` / `AWS_ACCESS_KEY_ID` | S3 credentials |
108
- | `S3_SECRET_ACCESS_KEY` / `AWS_SECRET_ACCESS_KEY` | S3 credentials |
109
- | `S3_REGION` / `AWS_REGION` | S3 region |
110
- | `S3_ENDPOINT` / `AWS_ENDPOINT` | S3 endpoint (for compatible stores) |
111
- | `REDIS_URL` | Redis connection URL |
112
- | `LOGGING` | Enable debug logging |
113
- | `STRICT` | Enable schema validation via CHEX |
3
+ If a repo-local instruction file adds stricter rules, follow the repo-local rule.
package/AGENTS.md ADDED
@@ -0,0 +1,3 @@
1
+ Follow the shared workspace instructions in [../instructions.md](../instructions.md) and shared context in [../memory.md](../memory.md).
2
+
3
+ Repo-local rules may add to or override the shared files when explicitly stated.
package/CLAUDE.md ADDED
@@ -0,0 +1,3 @@
1
+ Follow the shared workspace instructions in [../instructions.md](../instructions.md) and shared context in [../memory.md](../memory.md).
2
+
3
+ Repo-local rules may add to or override the shared files when explicitly stated.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delma/fylo",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/types/index.d.ts",
6
6
  "bin": {
@@ -25,8 +25,8 @@
25
25
  "prettier": "^3.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@vyckr/ttid": "1.3.1",
29
- "@vyckr/chex": "0.3.0"
28
+ "@delma/ttid": "1.3.4",
29
+ "@delma/chex": "0.3.3"
30
30
  },
31
31
  "type": "module",
32
32
  "peerDependencies": {
@@ -36,7 +36,7 @@
36
36
  "type": "git",
37
37
  "url": "git+https://github.com/Chidelma/Fylo.git"
38
38
  },
39
- "homepage": "https://fylo.vyckr.com",
39
+ "homepage": "https://fylo.del.ma",
40
40
  "license": "MIT",
41
41
  "keywords": [
42
42
  "storage",
@@ -1,5 +1,5 @@
1
1
  import { Walker } from "./walker"
2
- import TTID from "@vyckr/ttid"
2
+ import TTID from "@delma/ttid"
3
3
  import { S3 } from "../adapters/s3"
4
4
  import { Redis } from "../adapters/redis"
5
5
  import { Cipher } from "../adapters/cipher"
@@ -1,4 +1,4 @@
1
- import TTID from '@vyckr/ttid'
1
+ import TTID from '@delma/ttid'
2
2
 
3
3
  class Format {
4
4
  static table(docs: Record<string, any>) {
@@ -1,5 +1,5 @@
1
1
  import { S3 } from "../adapters/s3"
2
- import TTID from "@vyckr/ttid"
2
+ import TTID from "@delma/ttid"
3
3
  import { Redis } from "../adapters/redis"
4
4
 
5
5
  export class Walker {
package/src/index.ts CHANGED
@@ -2,8 +2,8 @@
2
2
  import { Query } from './core/query'
3
3
  import { Parser } from './core/parser'
4
4
  import { Dir } from "./core/directory";
5
- import TTID from '@vyckr/ttid';
6
- import Gen from "@vyckr/chex"
5
+ import TTID from '@delma/ttid';
6
+ import Gen from "@delma/chex"
7
7
  import { Walker } from './core/walker';
8
8
  import { S3 } from "./adapters/s3"
9
9
  import { Cipher } from "./adapters/cipher"
@@ -26,7 +26,7 @@ interface Console {
26
26
 
27
27
  type _joinDocs<T, U> = _ttid[] | Record<string, _ttid[]> | Record<string, Record<_ttid, Partial<T | U>>> | Record<`${_ttid}, ${_ttid}`, T | U | (T & U) | (Partial<T> & Partial<U>)>
28
28
 
29
- declare module "@vyckr/fylo" {
29
+ declare module "@delma/fylo" {
30
30
 
31
31
  export default class {
32
32
 
@@ -1,3 +1,3 @@
1
1
  /// <reference path="./query.d.ts" />
2
2
  /// <reference path="./fylo.d.ts" />
3
- /// <reference types="@vyckr/ttid" />
3
+ /// <reference types="@delma/ttid" />
@@ -0,0 +1,31 @@
1
+ declare module "@delma/ttid" {
2
+
3
+ export type _ttid = string | `${string}-${string}` | `${string}-${string}-${string}`
4
+
5
+ export interface _timestamps {
6
+ createdAt: number
7
+ updatedAt?: number
8
+ deletedAt?: number
9
+ }
10
+
11
+ export default class TTID {
12
+ static isTTID(_id: string): Date | null
13
+ static isUUID(_id: string): RegExpMatchArray | null
14
+ static generate(_id?: string, del?: boolean): _ttid
15
+ static decodeTime(_id: string): _timestamps
16
+ }
17
+ }
18
+
19
+ declare module "@delma/chex" {
20
+
21
+ export default class Gen {
22
+ static generateDeclaration(json: unknown, interfaceName?: string): string
23
+ static sanitizePropertyName(key: string): string
24
+ static fromJsonString(jsonString: string, interfaceName?: string): string
25
+ static fromObject(obj: unknown, interfaceName?: string): string
26
+ static validateData<T extends Record<string, unknown>>(collection: string, data: T): Promise<T>
27
+ }
28
+ }
29
+
30
+ type _ttid = import("@delma/ttid")._ttid
31
+ type _timestamps = import("@delma/ttid")._timestamps
package/tests/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Redis } from '../src/adapters/redis'
2
- import ttid from '@vyckr/ttid'
2
+ import ttid from '@delma/ttid'
3
3
 
4
4
  const redisPub = new Redis()
5
5
  const redisSub = new Redis()
@@ -16,4 +16,4 @@ await Bun.sleep(1000)
16
16
 
17
17
  for await (const data of redisSub.subscribe("bun")) {
18
18
  console.log("Received:", data)
19
- }
19
+ }
@@ -1,6 +1,6 @@
1
1
  import { test, expect, describe, beforeAll, afterAll, mock } from 'bun:test'
2
2
  import Fylo from '../../src'
3
- import TTID from '@vyckr/ttid'
3
+ import TTID from '@delma/ttid'
4
4
  import S3Mock from '../mocks/s3'
5
5
  import RedisMock from '../mocks/redis'
6
6
 
package/tsconfig.json CHANGED
@@ -12,8 +12,8 @@
12
12
  "noFallthroughCasesInSwitch": true,
13
13
  "noImplicitReturns": true,
14
14
  "forceConsistentCasingInFileNames": true,
15
- "types": ["bun-types", "node", "@vyckr/ttid"],
15
+ "types": ["bun-types", "node"],
16
16
  "isolatedModules": true,
17
17
  "skipLibCheck": true
18
18
  }
19
- }
19
+ }