Skip to content

Commit e375c70

Browse files
deepracticexsclaude
andcommitted
refactor(storex): clean API — hide CASRegistry from consumers
createStoreX now accepts { blobStore, manifestStore } directly. CASRegistry is created internally — callers never see it. Only export: createStoreX, StoreX, SPI types, and Memory stores for testing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b99df50 commit e375c70

4 files changed

Lines changed: 35 additions & 28 deletions

File tree

.changeset/storex-clean-api.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"storexjs": minor
3+
---
4+
5+
refactor: clean API — accept blobStore/manifestStore instead of CASRegistry
6+
7+
createStoreX now takes { blobStore, manifestStore } directly.
8+
CASRegistry is created internally — callers never see it.
9+
Removed CASRegistry from public exports.

packages/storex/src/StoreX.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
* ResourceX is for AI agents (add, resolve, ingest, push, pull).
99
*/
1010

11-
import type { CASRegistry, RXM, RXR, StoredRXM } from "@resourcexjs/core";
12-
import { parse } from "@resourcexjs/core";
11+
import type { RXAStore, RXMStore, StoredRXM } from "@resourcexjs/core";
12+
import { CASRegistry, parse } from "@resourcexjs/core";
1313

1414
/**
1515
* File metadata returned by list operations.
@@ -28,8 +28,10 @@ export interface ResourceInfo {
2828
* StoreX configuration.
2929
*/
3030
export interface StoreXConfig {
31-
/** CASRegistry instance (the storage backend) */
32-
registry: CASRegistry;
31+
/** Blob storage backend (R2, filesystem, memory, etc.) */
32+
blobStore: RXAStore;
33+
/** Manifest storage backend (SQLite, D1, memory, etc.) */
34+
manifestStore: RXMStore;
3335
}
3436

3537
/**
@@ -39,7 +41,7 @@ export class StoreX {
3941
private readonly cas: CASRegistry;
4042

4143
constructor(config: StoreXConfig) {
42-
this.cas = config.registry;
44+
this.cas = new CASRegistry(config.blobStore, config.manifestStore);
4345
}
4446

4547
/**

packages/storex/src/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
* ResourceX is for AI agents.
66
*/
77

8-
// Re-export store SPI types for implementors
8+
// SPI types for platform implementors (R2RXAStore, DORXMStore, etc.)
99
export type { RXAStore, RXMStore, StoredRXM } from "@resourcexjs/core";
10-
export { CASRegistry, MemoryRXAStore, MemoryRXMStore } from "@resourcexjs/core";
10+
// Memory implementations — for testing only
11+
export { MemoryRXAStore, MemoryRXMStore } from "@resourcexjs/core";
1112
export type { ResourceInfo, StoreXConfig } from "./StoreX.js";
13+
// StoreX API
1214
export { createStoreX, StoreX } from "./StoreX.js";

packages/storex/tests/StoreX.test.ts

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
11
import { beforeEach, describe, expect, it } from "bun:test";
2-
import {
3-
archive,
4-
CASRegistry,
5-
MemoryRXAStore,
6-
MemoryRXMStore,
7-
manifest,
8-
resource,
9-
} from "@resourcexjs/core";
10-
import { createStoreX, type StoreX } from "../src/index";
2+
import { archive, manifest, resource } from "@resourcexjs/core";
3+
import { createStoreX, MemoryRXAStore, MemoryRXMStore, type StoreX } from "../src/index";
114

125
describe("StoreX", () => {
136
let store: StoreX;
14-
let cas: CASRegistry;
157

168
beforeEach(() => {
17-
cas = new CASRegistry(new MemoryRXAStore(), new MemoryRXMStore());
18-
store = createStoreX({ registry: cas });
9+
store = createStoreX({
10+
blobStore: new MemoryRXAStore(),
11+
manifestStore: new MemoryRXMStore(),
12+
});
1913
});
2014

2115
describe("list", () => {
2216
it("lists all resources", async () => {
23-
await cas.put(
17+
await store.put(
2418
resource(
2519
manifest({ name: "img-pack", type: "binary", tag: "latest" }),
2620
await archive({ "photo.png": Buffer.from("png-data") })
@@ -35,13 +29,13 @@ describe("StoreX", () => {
3529
});
3630

3731
it("filters by query", async () => {
38-
await cas.put(
32+
await store.put(
3933
resource(
4034
manifest({ name: "issue-5-files", type: "binary", tag: "latest" }),
4135
await archive({ "a.png": Buffer.from("a") })
4236
)
4337
);
44-
await cas.put(
38+
await store.put(
4539
resource(
4640
manifest({ name: "my-skill", type: "skill", tag: "latest" }),
4741
await archive({ "SKILL.md": Buffer.from("# Skill") })
@@ -56,7 +50,7 @@ describe("StoreX", () => {
5650

5751
describe("getFile", () => {
5852
it("retrieves a single file by locator and path", async () => {
59-
await cas.put(
53+
await store.put(
6054
resource(
6155
manifest({ name: "attachments", type: "binary", tag: "latest" }),
6256
await archive({ "screenshot.png": Buffer.from("image-bytes") })
@@ -68,7 +62,7 @@ describe("StoreX", () => {
6862
});
6963

7064
it("returns null for non-existent file", async () => {
71-
await cas.put(
65+
await store.put(
7266
resource(
7367
manifest({ name: "attachments", type: "binary", tag: "latest" }),
7468
await archive({ "a.txt": Buffer.from("a") })
@@ -82,7 +76,7 @@ describe("StoreX", () => {
8276

8377
describe("append", () => {
8478
it("appends files to an existing resource", async () => {
85-
await cas.put(
79+
await store.put(
8680
resource(
8781
manifest({ name: "issue-3", type: "binary", tag: "latest" }),
8882
await archive({ "img1.png": Buffer.from("first") })
@@ -105,7 +99,7 @@ describe("StoreX", () => {
10599

106100
describe("getManifest", () => {
107101
it("returns manifest metadata", async () => {
108-
await cas.put(
102+
await store.put(
109103
resource(
110104
manifest({ name: "docs", type: "text", tag: "1.0.0", description: "My docs" }),
111105
await archive({ "readme.md": Buffer.from("Hello") })
@@ -126,7 +120,7 @@ describe("StoreX", () => {
126120

127121
describe("has", () => {
128122
it("returns true for existing resource", async () => {
129-
await cas.put(
123+
await store.put(
130124
resource(
131125
manifest({ name: "exists", type: "text", tag: "latest" }),
132126
await archive({ "a.txt": Buffer.from("a") })
@@ -157,7 +151,7 @@ describe("StoreX", () => {
157151

158152
describe("remove", () => {
159153
it("removes a resource", async () => {
160-
await cas.put(
154+
await store.put(
161155
resource(
162156
manifest({ name: "temp", type: "text", tag: "latest" }),
163157
await archive({ "a.txt": Buffer.from("a") })

0 commit comments

Comments
 (0)