@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 +396 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1185 -94
- package/dist/index.js.map +7 -6
- package/package.json +4 -3
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
|
|
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.
|