@resourcexjs/registry 0.9.0 → 1.1.0

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.
package/README.md ADDED
@@ -0,0 +1,396 @@
1
+ # @resourcexjs/registry
2
+
3
+ Resource registry for ResourceX - storage and retrieval of resources.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @resourcexjs/registry
9
+ ```
10
+
11
+ ## Overview
12
+
13
+ The `@resourcexjs/registry` package provides a Maven-style registry for storing and resolving resources locally.
14
+
15
+ ### Key Concepts
16
+
17
+ - **Registry**: Interface for resource storage and retrieval
18
+ - **ARPRegistry**: Implementation using ARP (Agent Resource Protocol) for I/O
19
+ - **Local-first**: Resources cached locally at `~/.resourcex`
20
+ - **Maven-style**: Organized by `domain/path/name.type@version`
21
+
22
+ ## Usage
23
+
24
+ ### Create Registry
25
+
26
+ ```typescript
27
+ import { createRegistry } from "@resourcexjs/registry";
28
+
29
+ // Default configuration (~/.resourcex)
30
+ const registry = createRegistry();
31
+
32
+ // Custom path
33
+ const registry = createRegistry({
34
+ path: "./my-registry",
35
+ });
36
+
37
+ // With extension types
38
+ import { promptType } from "@my-org/types";
39
+
40
+ const registry = createRegistry({
41
+ types: [promptType],
42
+ });
43
+ ```
44
+
45
+ ### Link Resource
46
+
47
+ Link a resource to local registry for development or caching:
48
+
49
+ ```typescript
50
+ import { loadResource } from "@resourcexjs/loader";
51
+ import { createRegistry } from "@resourcexjs/registry";
52
+
53
+ // Load resource from folder
54
+ const rxr = await loadResource("./my-prompt");
55
+
56
+ // Link to registry
57
+ const registry = createRegistry();
58
+ await registry.link(rxr);
59
+
60
+ // Now available at: ~/.resourcex/localhost/my-prompt.text@1.0.0/
61
+ ```
62
+
63
+ ### Resolve Resource
64
+
65
+ Retrieve a resource by its locator:
66
+
67
+ ```typescript
68
+ const registry = createRegistry();
69
+
70
+ // Resolve by full locator
71
+ const rxr = await registry.resolve("localhost/my-prompt.text@1.0.0");
72
+
73
+ console.log(rxr.manifest.name); // "my-prompt"
74
+ console.log(await rxr.content.text()); // Content
75
+ ```
76
+
77
+ ### Check Existence
78
+
79
+ ```typescript
80
+ const registry = createRegistry();
81
+
82
+ if (await registry.exists("localhost/my-prompt.text@1.0.0")) {
83
+ console.log("Resource exists");
84
+ }
85
+ ```
86
+
87
+ ### Delete Resource
88
+
89
+ ```typescript
90
+ const registry = createRegistry();
91
+
92
+ await registry.delete("localhost/my-prompt.text@1.0.0");
93
+ ```
94
+
95
+ ## API Reference
96
+
97
+ ### `createRegistry(config?)`
98
+
99
+ Create a new registry instance.
100
+
101
+ **Parameters:**
102
+
103
+ - `config?: RegistryConfig`
104
+ - `path?: string` - Storage path (default: `~/.resourcex`)
105
+ - `types?: ResourceType[]` - Extension types to register globally
106
+
107
+ **Returns**: `Registry`
108
+
109
+ ```typescript
110
+ const registry = createRegistry({
111
+ path: "./custom-registry",
112
+ types: [promptType, toolType],
113
+ });
114
+ ```
115
+
116
+ ### Registry Interface
117
+
118
+ #### `link(resource: RXR): Promise<void>`
119
+
120
+ Link a resource to local registry.
121
+
122
+ **Parameters:**
123
+
124
+ - `resource: RXR` - Complete resource object
125
+
126
+ ```typescript
127
+ await registry.link(rxr);
128
+ ```
129
+
130
+ #### `resolve(locator: string): Promise<RXR>`
131
+
132
+ Resolve a resource by locator.
133
+
134
+ **Parameters:**
135
+
136
+ - `locator: string` - Full resource locator
137
+
138
+ **Returns**: `Promise<RXR>`
139
+
140
+ **Throws**: `RegistryError` if resource not found
141
+
142
+ ```typescript
143
+ const rxr = await registry.resolve("localhost/my-prompt.text@1.0.0");
144
+ ```
145
+
146
+ #### `exists(locator: string): Promise<boolean>`
147
+
148
+ Check if resource exists in registry.
149
+
150
+ **Parameters:**
151
+
152
+ - `locator: string` - Full resource locator
153
+
154
+ **Returns**: `Promise<boolean>`
155
+
156
+ ```typescript
157
+ if (await registry.exists("localhost/my-prompt.text@1.0.0")) {
158
+ // Resource exists
159
+ }
160
+ ```
161
+
162
+ #### `delete(locator: string): Promise<void>`
163
+
164
+ Delete resource from local registry.
165
+
166
+ **Parameters:**
167
+
168
+ - `locator: string` - Full resource locator
169
+
170
+ ```typescript
171
+ await registry.delete("localhost/my-prompt.text@1.0.0");
172
+ ```
173
+
174
+ #### `publish(resource: RXR): Promise<void>`
175
+
176
+ Publish resource to remote registry (TODO: not yet implemented).
177
+
178
+ #### `search(query: string): Promise<RXL[]>`
179
+
180
+ Search for resources (TODO: not yet implemented).
181
+
182
+ ## Storage Structure
183
+
184
+ Resources are stored in Maven-style structure:
185
+
186
+ ```
187
+ ~/.resourcex/
188
+ └── {domain}/
189
+ └── {path}/
190
+ └── {name}.{type}@{version}/
191
+ ├── manifest.json # RXM metadata
192
+ └── content # Serialized content
193
+ ```
194
+
195
+ ### Example
196
+
197
+ For resource `deepractice.ai/prompts/assistant.prompt@1.0.0`:
198
+
199
+ ```
200
+ ~/.resourcex/
201
+ └── deepractice.ai/
202
+ └── prompts/
203
+ └── assistant.prompt@1.0.0/
204
+ ├── manifest.json
205
+ └── content
206
+ ```
207
+
208
+ **manifest.json:**
209
+
210
+ ```json
211
+ {
212
+ "domain": "deepractice.ai",
213
+ "path": "prompts",
214
+ "name": "assistant",
215
+ "type": "prompt",
216
+ "version": "1.0.0"
217
+ }
218
+ ```
219
+
220
+ **content:** (serialized by type's serializer)
221
+
222
+ ## Extension Types
223
+
224
+ Register extension types globally when creating registry:
225
+
226
+ ```typescript
227
+ import { createRegistry } from "@resourcexjs/registry";
228
+ import type { ResourceType } from "@resourcexjs/type";
229
+
230
+ const promptType: ResourceType<string> = {
231
+ name: "prompt",
232
+ description: "AI Prompt template",
233
+ serializer: {
234
+ async serialize(rxr) {
235
+ const text = await rxr.content.text();
236
+ return Buffer.from(text, "utf-8");
237
+ },
238
+ async deserialize(data, manifest) {
239
+ // ... implementation
240
+ },
241
+ },
242
+ resolver: {
243
+ async resolve(rxr) {
244
+ return rxr.content.text();
245
+ },
246
+ },
247
+ };
248
+
249
+ // Register when creating registry
250
+ const registry = createRegistry({
251
+ types: [promptType],
252
+ });
253
+
254
+ // Now can link/resolve prompt resources
255
+ ```
256
+
257
+ ## Error Handling
258
+
259
+ ```typescript
260
+ import { RegistryError } from "@resourcexjs/registry";
261
+
262
+ try {
263
+ const rxr = await registry.resolve("localhost/not-exist.text@1.0.0");
264
+ } catch (error) {
265
+ if (error instanceof RegistryError) {
266
+ console.error("Registry error:", error.message);
267
+ // "Resource not found: localhost/not-exist.text@1.0.0"
268
+ }
269
+ }
270
+ ```
271
+
272
+ ### Common Errors
273
+
274
+ **Resource not found:**
275
+
276
+ ```
277
+ RegistryError: Resource not found: localhost/my-prompt.text@1.0.0
278
+ ```
279
+
280
+ **Unsupported type:**
281
+
282
+ ```
283
+ RegistryError: Unsupported resource type 'unknown'
284
+ ```
285
+
286
+ ## Examples
287
+
288
+ ### Complete Workflow
289
+
290
+ ```typescript
291
+ import { loadResource } from "@resourcexjs/loader";
292
+ import { createRegistry } from "@resourcexjs/registry";
293
+
294
+ // 1. Load resource from folder
295
+ const rxr = await loadResource("./my-prompts/assistant");
296
+
297
+ // 2. Create registry
298
+ const registry = createRegistry();
299
+
300
+ // 3. Link to local registry
301
+ await registry.link(rxr);
302
+
303
+ // 4. Resolve later
304
+ const resolved = await registry.resolve("localhost/assistant.prompt@1.0.0");
305
+
306
+ // 5. Use content
307
+ const text = await resolved.content.text();
308
+ console.log(text);
309
+ ```
310
+
311
+ ### Versioning
312
+
313
+ ```typescript
314
+ const registry = createRegistry();
315
+
316
+ // Link multiple versions
317
+ await registry.link(promptV1); // v1.0.0
318
+ await registry.link(promptV2); // v2.0.0
319
+ await registry.link(promptV3); // v3.0.0
320
+
321
+ // Resolve specific version
322
+ const v1 = await registry.resolve("localhost/prompt.text@1.0.0");
323
+ const v2 = await registry.resolve("localhost/prompt.text@2.0.0");
324
+ const latest = await registry.resolve("localhost/prompt.text@3.0.0");
325
+ ```
326
+
327
+ ### Custom Storage Path
328
+
329
+ ```typescript
330
+ // Project-local registry
331
+ const registry = createRegistry({
332
+ path: "./project-registry",
333
+ });
334
+
335
+ await registry.link(rxr);
336
+ // Stored at: ./project-registry/localhost/...
337
+ ```
338
+
339
+ ### With Custom Types
340
+
341
+ ```typescript
342
+ import { promptType, toolType, agentType } from "@my-org/ai-types";
343
+
344
+ const registry = createRegistry({
345
+ types: [promptType, toolType, agentType],
346
+ });
347
+
348
+ // Now can handle these custom types
349
+ await registry.link(promptResource);
350
+ await registry.link(toolResource);
351
+ await registry.link(agentResource);
352
+ ```
353
+
354
+ ## Resolution Strategy
355
+
356
+ 1. **Check local registry** (`~/.resourcex` or custom path)
357
+ 2. **If not found**: (TODO) Fetch from remote registry based on domain
358
+ 3. **Cache locally** after fetching
359
+ 4. **Return** resource
360
+
361
+ Currently only local resolution is implemented. Remote fetching is planned.
362
+
363
+ ## Architecture
364
+
365
+ ```
366
+ ┌─────────────────────────────────────┐
367
+ │ Registry Interface │
368
+ └──────────────┬──────────────────────┘
369
+
370
+ ┌──────▼──────┐
371
+ │ARPRegistry │
372
+ │(implements) │
373
+ └──────┬──────┘
374
+
375
+ ┌─────────┴─────────┐
376
+ │ │
377
+ ┌────▼────┐ ┌──────▼──────┐
378
+ │ ARP │ │TypeHandler │
379
+ │(I/O) │ │Chain │
380
+ └─────────┘ └─────────────┘
381
+ ```
382
+
383
+ ## Type Safety
384
+
385
+ All operations are fully typed:
386
+
387
+ ```typescript
388
+ import type { RXR, Registry } from "@resourcexjs/registry";
389
+
390
+ const registry: Registry = createRegistry();
391
+ const rxr: RXR = await registry.resolve("localhost/test.text@1.0.0");
392
+ ```
393
+
394
+ ## License
395
+
396
+ MIT
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { RXR, RXL, ResourceType } from "@resourcexjs/core";
1
+ import { RXR, RXL } from "@resourcexjs/core";
2
+ import { ResourceType } from "@resourcexjs/type";
2
3
  /**
3
4
  * Registry configuration options.
4
5
  */
@@ -54,12 +55,11 @@ import { RXR as RXR2, RXL as RXL2 } from "@resourcexjs/core";
54
55
  /**
55
56
  * ARP-based registry implementation.
56
57
  * Uses ARP protocol for atomic I/O operations.
57
- * Uses TypeHandlerChain for serialization/deserialization.
58
+ * Uses global TypeHandlerChain for serialization/deserialization.
58
59
  */
59
60
  declare class ARPRegistry implements Registry {
60
61
  private readonly arp;
61
62
  private readonly basePath;
62
- private readonly typeChain;
63
63
  constructor(config?: RegistryConfig);
64
64
  /**
65
65
  * Build ARP URL for a resource file.