@resourcexjs/core 0.0.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.
- package/README.md +122 -0
- package/dist/index.d.ts +156 -0
- package/dist/index.js +197 -0
- package/dist/index.js.map +18 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# @resourcexjs/core
|
|
2
|
+
|
|
3
|
+
Core implementation of Agent Resource Protocol (ARP).
|
|
4
|
+
|
|
5
|
+
> **Note**: For most use cases, use the [`resourcexjs`](https://www.npmjs.com/package/resourcexjs) package instead. This package is for advanced usage and custom extensions.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @resourcexjs/core
|
|
11
|
+
# or
|
|
12
|
+
bun add @resourcexjs/core
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Parse ARP URLs
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { parseARP } from "@resourcexjs/core";
|
|
21
|
+
|
|
22
|
+
const parsed = parseARP("arp:text:https://example.com/file.txt");
|
|
23
|
+
// { semantic: "text", transport: "https", location: "example.com/file.txt" }
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Resolve Resources
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
import { resolve } from "@resourcexjs/core";
|
|
30
|
+
|
|
31
|
+
const resource = await resolve("arp:text:https://example.com/file.txt");
|
|
32
|
+
// { type: "text", content: "...", meta: { ... } }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Custom Transport Handler
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { registerTransportHandler, type TransportHandler } from "@resourcexjs/core";
|
|
39
|
+
|
|
40
|
+
const s3Handler: TransportHandler = {
|
|
41
|
+
protocol: "s3",
|
|
42
|
+
async fetch(location: string): Promise<Buffer> {
|
|
43
|
+
// fetch from S3...
|
|
44
|
+
return buffer;
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
registerTransportHandler(s3Handler);
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Custom Semantic Handler
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { registerSemanticHandler, type SemanticHandler, type Resource } from "@resourcexjs/core";
|
|
55
|
+
|
|
56
|
+
const jsonHandler: SemanticHandler = {
|
|
57
|
+
type: "json",
|
|
58
|
+
parse(content: Buffer, context): Resource {
|
|
59
|
+
return {
|
|
60
|
+
type: "json",
|
|
61
|
+
content: JSON.parse(content.toString("utf-8")),
|
|
62
|
+
meta: {
|
|
63
|
+
/* ... */
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
registerSemanticHandler(jsonHandler);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Exports
|
|
73
|
+
|
|
74
|
+
### Functions
|
|
75
|
+
|
|
76
|
+
- `parseARP(url)` - Parse ARP URL string
|
|
77
|
+
- `resolve(url)` - Resolve ARP URL to resource
|
|
78
|
+
- `getTransportHandler(protocol)` - Get registered transport handler
|
|
79
|
+
- `registerTransportHandler(handler)` - Register custom transport
|
|
80
|
+
- `getSemanticHandler(type)` - Get registered semantic handler
|
|
81
|
+
- `registerSemanticHandler(handler)` - Register custom semantic
|
|
82
|
+
|
|
83
|
+
### Built-in Handlers
|
|
84
|
+
|
|
85
|
+
**Transport:**
|
|
86
|
+
|
|
87
|
+
- `httpsHandler` - HTTPS protocol
|
|
88
|
+
- `httpHandler` - HTTP protocol
|
|
89
|
+
- `fileHandler` - Local file system
|
|
90
|
+
|
|
91
|
+
**Semantic:**
|
|
92
|
+
|
|
93
|
+
- `textHandler` - Plain text
|
|
94
|
+
|
|
95
|
+
### Error Classes
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import {
|
|
99
|
+
ResourceXError, // Base error
|
|
100
|
+
ParseError, // ARP URL parsing failed
|
|
101
|
+
TransportError, // Transport layer failed
|
|
102
|
+
SemanticError, // Semantic layer failed
|
|
103
|
+
} from "@resourcexjs/core";
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Types
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import type {
|
|
110
|
+
ParsedARP,
|
|
111
|
+
Resource,
|
|
112
|
+
ResourceMeta,
|
|
113
|
+
ParseContext,
|
|
114
|
+
TransportHandler,
|
|
115
|
+
SemanticHandler,
|
|
116
|
+
TextResource,
|
|
117
|
+
} from "@resourcexjs/core";
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResourceX Error Types
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base error class for all ResourceX errors
|
|
6
|
+
*/
|
|
7
|
+
declare class ResourceXError extends Error {
|
|
8
|
+
constructor(message: string, options?: ErrorOptions);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Error thrown when ARP URL parsing fails
|
|
12
|
+
*/
|
|
13
|
+
declare class ParseError extends ResourceXError {
|
|
14
|
+
readonly url?: string;
|
|
15
|
+
constructor(message: string, url?: string);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when transport layer fails
|
|
19
|
+
*/
|
|
20
|
+
declare class TransportError extends ResourceXError {
|
|
21
|
+
readonly transport?: string;
|
|
22
|
+
constructor(message: string, transport?: string, options?: ErrorOptions);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Error thrown when semantic layer fails
|
|
26
|
+
*/
|
|
27
|
+
declare class SemanticError extends ResourceXError {
|
|
28
|
+
readonly semantic?: string;
|
|
29
|
+
constructor(message: string, semantic?: string, options?: ErrorOptions);
|
|
30
|
+
}
|
|
31
|
+
interface ParsedARP {
|
|
32
|
+
semantic: string;
|
|
33
|
+
transport: string;
|
|
34
|
+
location: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse an ARP URL into its components
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* parseARP("arp:text:https://example.com/file.txt")
|
|
41
|
+
* // { semantic: "text", transport: "https", location: "example.com/file.txt" }
|
|
42
|
+
*/
|
|
43
|
+
declare function parseARP(url: string): ParsedARP;
|
|
44
|
+
/**
|
|
45
|
+
* Transport Handler Interface
|
|
46
|
+
* Responsible for fetching resource content from various sources
|
|
47
|
+
*/
|
|
48
|
+
interface TransportHandler {
|
|
49
|
+
/**
|
|
50
|
+
* Transport type name (e.g., "https", "file")
|
|
51
|
+
*/
|
|
52
|
+
readonly type: string;
|
|
53
|
+
/**
|
|
54
|
+
* Fetch resource content from the given location
|
|
55
|
+
* @param location - The location string after ://
|
|
56
|
+
* @returns Raw content as Buffer
|
|
57
|
+
*/
|
|
58
|
+
fetch(location: string): Promise<Buffer>;
|
|
59
|
+
}
|
|
60
|
+
declare class HttpTransportHandler implements TransportHandler {
|
|
61
|
+
readonly type: string;
|
|
62
|
+
private readonly protocol;
|
|
63
|
+
constructor(protocol?: "http" | "https");
|
|
64
|
+
fetch(location: string): Promise<Buffer>;
|
|
65
|
+
}
|
|
66
|
+
declare const httpsHandler: HttpTransportHandler;
|
|
67
|
+
declare const httpHandler: HttpTransportHandler;
|
|
68
|
+
declare class FileTransportHandler implements TransportHandler {
|
|
69
|
+
readonly type = "file";
|
|
70
|
+
fetch(location: string): Promise<Buffer>;
|
|
71
|
+
}
|
|
72
|
+
declare const fileHandler: FileTransportHandler;
|
|
73
|
+
/**
|
|
74
|
+
* Get transport handler by type
|
|
75
|
+
*/
|
|
76
|
+
declare function getTransportHandler(type: string): TransportHandler;
|
|
77
|
+
/**
|
|
78
|
+
* Register a custom transport handler
|
|
79
|
+
*/
|
|
80
|
+
declare function registerTransportHandler(handler: TransportHandler): void;
|
|
81
|
+
/**
|
|
82
|
+
* Semantic Handler Interface
|
|
83
|
+
* Responsible for parsing raw content into AI-usable format
|
|
84
|
+
*/
|
|
85
|
+
/**
|
|
86
|
+
* Resource metadata
|
|
87
|
+
*/
|
|
88
|
+
interface ResourceMeta {
|
|
89
|
+
url: string;
|
|
90
|
+
semantic: string;
|
|
91
|
+
transport: string;
|
|
92
|
+
location: string;
|
|
93
|
+
size: number;
|
|
94
|
+
encoding?: string;
|
|
95
|
+
mimeType?: string;
|
|
96
|
+
fetchedAt: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Context passed to semantic handler
|
|
100
|
+
*/
|
|
101
|
+
interface ParseContext {
|
|
102
|
+
url: string;
|
|
103
|
+
semantic: string;
|
|
104
|
+
transport: string;
|
|
105
|
+
location: string;
|
|
106
|
+
fetchedAt: Date;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Base resource interface
|
|
110
|
+
*/
|
|
111
|
+
interface Resource<T = unknown> {
|
|
112
|
+
type: string;
|
|
113
|
+
content: T;
|
|
114
|
+
meta: ResourceMeta;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Semantic handler interface
|
|
118
|
+
*/
|
|
119
|
+
interface SemanticHandler<T = unknown> {
|
|
120
|
+
readonly type: string;
|
|
121
|
+
/**
|
|
122
|
+
* Parse raw content into structured resource
|
|
123
|
+
*/
|
|
124
|
+
parse(content: Buffer, context: ParseContext): Resource<T>;
|
|
125
|
+
}
|
|
126
|
+
interface TextResource extends Resource<string> {
|
|
127
|
+
type: "text";
|
|
128
|
+
content: string;
|
|
129
|
+
}
|
|
130
|
+
declare class TextSemanticHandler implements SemanticHandler<string> {
|
|
131
|
+
readonly type = "text";
|
|
132
|
+
parse(content: Buffer, context: ParseContext): TextResource;
|
|
133
|
+
}
|
|
134
|
+
declare const textHandler: TextSemanticHandler;
|
|
135
|
+
/**
|
|
136
|
+
* Get semantic handler by type
|
|
137
|
+
*/
|
|
138
|
+
declare function getSemanticHandler(type: string): SemanticHandler;
|
|
139
|
+
/**
|
|
140
|
+
* Register a custom semantic handler
|
|
141
|
+
*/
|
|
142
|
+
declare function registerSemanticHandler(handler: SemanticHandler): void;
|
|
143
|
+
/**
|
|
144
|
+
* Resolve an ARP URL to a resource
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* const resource = await resolve("arp:text:https://example.com/file.txt");
|
|
148
|
+
* // { type: "text", content: "...", meta: { ... } }
|
|
149
|
+
*/
|
|
150
|
+
declare function resolve(url: string): Promise<Resource>;
|
|
151
|
+
/**
|
|
152
|
+
* @resourcexjs/core
|
|
153
|
+
* ARP (Agent Resource Protocol) implementation
|
|
154
|
+
*/
|
|
155
|
+
declare const VERSION = "0.0.1";
|
|
156
|
+
export { textHandler, resolve, registerTransportHandler, registerSemanticHandler, parseARP, httpsHandler, httpHandler, getTransportHandler, getSemanticHandler, fileHandler, VERSION, TransportHandler, TransportError, TextResource, SemanticHandler, SemanticError, ResourceXError, ResourceMeta, Resource, ParsedARP, ParseError, ParseContext };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
class ResourceXError extends Error {
|
|
3
|
+
constructor(message, options) {
|
|
4
|
+
super(message, options);
|
|
5
|
+
this.name = "ResourceXError";
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
class ParseError extends ResourceXError {
|
|
10
|
+
url;
|
|
11
|
+
constructor(message, url) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.url = url;
|
|
14
|
+
this.name = "ParseError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class TransportError extends ResourceXError {
|
|
19
|
+
transport;
|
|
20
|
+
constructor(message, transport, options) {
|
|
21
|
+
super(message, options);
|
|
22
|
+
this.transport = transport;
|
|
23
|
+
this.name = "TransportError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
class SemanticError extends ResourceXError {
|
|
28
|
+
semantic;
|
|
29
|
+
constructor(message, semantic, options) {
|
|
30
|
+
super(message, options);
|
|
31
|
+
this.semantic = semantic;
|
|
32
|
+
this.name = "SemanticError";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// src/parser.ts
|
|
36
|
+
function parseARP(url) {
|
|
37
|
+
if (!url.startsWith("arp:")) {
|
|
38
|
+
throw new ParseError(`Invalid ARP URL: must start with "arp:"`, url);
|
|
39
|
+
}
|
|
40
|
+
const content = url.substring(4);
|
|
41
|
+
const separatorIndex = content.indexOf("://");
|
|
42
|
+
if (separatorIndex === -1) {
|
|
43
|
+
throw new ParseError(`Invalid ARP URL: missing "://"`, url);
|
|
44
|
+
}
|
|
45
|
+
const typePart = content.substring(0, separatorIndex);
|
|
46
|
+
const location = content.substring(separatorIndex + 3);
|
|
47
|
+
const colonIndex = typePart.indexOf(":");
|
|
48
|
+
if (colonIndex === -1) {
|
|
49
|
+
throw new ParseError(`Invalid ARP URL: must have exactly 2 types (semantic:transport)`, url);
|
|
50
|
+
}
|
|
51
|
+
const semantic = typePart.substring(0, colonIndex);
|
|
52
|
+
const transport = typePart.substring(colonIndex + 1);
|
|
53
|
+
if (!semantic) {
|
|
54
|
+
throw new ParseError(`Invalid ARP URL: semantic type cannot be empty`, url);
|
|
55
|
+
}
|
|
56
|
+
if (!transport) {
|
|
57
|
+
throw new ParseError(`Invalid ARP URL: transport type cannot be empty`, url);
|
|
58
|
+
}
|
|
59
|
+
if (!location) {
|
|
60
|
+
throw new ParseError(`Invalid ARP URL: location cannot be empty`, url);
|
|
61
|
+
}
|
|
62
|
+
return { semantic, transport, location };
|
|
63
|
+
}
|
|
64
|
+
// src/transport/http.ts
|
|
65
|
+
class HttpTransportHandler {
|
|
66
|
+
type;
|
|
67
|
+
protocol;
|
|
68
|
+
constructor(protocol = "https") {
|
|
69
|
+
this.protocol = protocol;
|
|
70
|
+
this.type = protocol;
|
|
71
|
+
}
|
|
72
|
+
async fetch(location) {
|
|
73
|
+
const url = `${this.protocol}://${location}`;
|
|
74
|
+
try {
|
|
75
|
+
const response = await fetch(url);
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
throw new TransportError(`HTTP ${response.status}: ${response.statusText} - ${url}`, this.type);
|
|
78
|
+
}
|
|
79
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
80
|
+
return Buffer.from(arrayBuffer);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
if (error instanceof TransportError) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
throw new TransportError(`Network error: ${url}`, this.type, { cause: error });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
var httpsHandler = new HttpTransportHandler("https");
|
|
90
|
+
var httpHandler = new HttpTransportHandler("http");
|
|
91
|
+
// src/transport/file.ts
|
|
92
|
+
import { readFile } from "node:fs/promises";
|
|
93
|
+
import { resolve } from "node:path";
|
|
94
|
+
class FileTransportHandler {
|
|
95
|
+
type = "file";
|
|
96
|
+
async fetch(location) {
|
|
97
|
+
const filePath = resolve(process.cwd(), location);
|
|
98
|
+
try {
|
|
99
|
+
return await readFile(filePath);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
const err = error;
|
|
102
|
+
throw new TransportError(`File read error: ${err.code} - ${filePath}`, this.type, {
|
|
103
|
+
cause: err
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
var fileHandler = new FileTransportHandler;
|
|
109
|
+
// src/transport/index.ts
|
|
110
|
+
var handlers = new Map([
|
|
111
|
+
["https", httpsHandler],
|
|
112
|
+
["http", httpHandler],
|
|
113
|
+
["file", fileHandler]
|
|
114
|
+
]);
|
|
115
|
+
function getTransportHandler(type) {
|
|
116
|
+
const handler = handlers.get(type);
|
|
117
|
+
if (!handler) {
|
|
118
|
+
throw new TransportError(`Unsupported transport type: ${type}`, type);
|
|
119
|
+
}
|
|
120
|
+
return handler;
|
|
121
|
+
}
|
|
122
|
+
function registerTransportHandler(handler) {
|
|
123
|
+
handlers.set(handler.type, handler);
|
|
124
|
+
}
|
|
125
|
+
// src/semantic/text.ts
|
|
126
|
+
class TextSemanticHandler {
|
|
127
|
+
type = "text";
|
|
128
|
+
parse(content, context) {
|
|
129
|
+
const text = content.toString("utf-8");
|
|
130
|
+
const meta = {
|
|
131
|
+
url: context.url,
|
|
132
|
+
semantic: context.semantic,
|
|
133
|
+
transport: context.transport,
|
|
134
|
+
location: context.location,
|
|
135
|
+
size: content.length,
|
|
136
|
+
encoding: "utf-8",
|
|
137
|
+
mimeType: "text/plain",
|
|
138
|
+
fetchedAt: context.fetchedAt.toISOString()
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
type: "text",
|
|
142
|
+
content: text,
|
|
143
|
+
meta
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
var textHandler = new TextSemanticHandler;
|
|
148
|
+
// src/semantic/index.ts
|
|
149
|
+
var handlers2 = new Map([["text", textHandler]]);
|
|
150
|
+
function getSemanticHandler(type) {
|
|
151
|
+
const handler = handlers2.get(type);
|
|
152
|
+
if (!handler) {
|
|
153
|
+
throw new SemanticError(`Unsupported semantic type: ${type}`, type);
|
|
154
|
+
}
|
|
155
|
+
return handler;
|
|
156
|
+
}
|
|
157
|
+
function registerSemanticHandler(handler) {
|
|
158
|
+
handlers2.set(handler.type, handler);
|
|
159
|
+
}
|
|
160
|
+
// src/resolve.ts
|
|
161
|
+
async function resolve2(url) {
|
|
162
|
+
const fetchedAt = new Date;
|
|
163
|
+
const parsed = parseARP(url);
|
|
164
|
+
const transportHandler = getTransportHandler(parsed.transport);
|
|
165
|
+
const semanticHandler = getSemanticHandler(parsed.semantic);
|
|
166
|
+
const content = await transportHandler.fetch(parsed.location);
|
|
167
|
+
const context = {
|
|
168
|
+
url,
|
|
169
|
+
semantic: parsed.semantic,
|
|
170
|
+
transport: parsed.transport,
|
|
171
|
+
location: parsed.location,
|
|
172
|
+
fetchedAt
|
|
173
|
+
};
|
|
174
|
+
return semanticHandler.parse(content, context);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/index.ts
|
|
178
|
+
var VERSION = "0.0.1";
|
|
179
|
+
export {
|
|
180
|
+
textHandler,
|
|
181
|
+
resolve2 as resolve,
|
|
182
|
+
registerTransportHandler,
|
|
183
|
+
registerSemanticHandler,
|
|
184
|
+
parseARP,
|
|
185
|
+
httpsHandler,
|
|
186
|
+
httpHandler,
|
|
187
|
+
getTransportHandler,
|
|
188
|
+
getSemanticHandler,
|
|
189
|
+
fileHandler,
|
|
190
|
+
VERSION,
|
|
191
|
+
TransportError,
|
|
192
|
+
SemanticError,
|
|
193
|
+
ResourceXError,
|
|
194
|
+
ParseError
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
//# debugId=7FDB8A773330183C64756E2164756E21
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/parser.ts", "../src/transport/http.ts", "../src/transport/file.ts", "../src/transport/index.ts", "../src/semantic/text.ts", "../src/semantic/index.ts", "../src/resolve.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * ResourceX Error Types\n */\n\n/**\n * Base error class for all ResourceX errors\n */\nexport class ResourceXError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"ResourceXError\";\n }\n}\n\n/**\n * Error thrown when ARP URL parsing fails\n */\nexport class ParseError extends ResourceXError {\n constructor(\n message: string,\n public readonly url?: string\n ) {\n super(message);\n this.name = \"ParseError\";\n }\n}\n\n/**\n * Error thrown when transport layer fails\n */\nexport class TransportError extends ResourceXError {\n constructor(\n message: string,\n public readonly transport?: string,\n options?: ErrorOptions\n ) {\n super(message, options);\n this.name = \"TransportError\";\n }\n}\n\n/**\n * Error thrown when semantic layer fails\n */\nexport class SemanticError extends ResourceXError {\n constructor(\n message: string,\n public readonly semantic?: string,\n options?: ErrorOptions\n ) {\n super(message, options);\n this.name = \"SemanticError\";\n }\n}\n",
|
|
6
|
+
"/**\n * ARP URL Parser\n * Format: arp:{semantic}:{transport}://{location}\n */\n\nimport { ParseError } from \"./errors.js\";\n\nexport interface ParsedARP {\n semantic: string;\n transport: string;\n location: string;\n}\n\n/**\n * Parse an ARP URL into its components\n *\n * @example\n * parseARP(\"arp:text:https://example.com/file.txt\")\n * // { semantic: \"text\", transport: \"https\", location: \"example.com/file.txt\" }\n */\nexport function parseARP(url: string): ParsedARP {\n // 1. Check protocol prefix\n if (!url.startsWith(\"arp:\")) {\n throw new ParseError(`Invalid ARP URL: must start with \"arp:\"`, url);\n }\n\n const content = url.substring(4); // Remove \"arp:\"\n\n // 2. Find :// separator\n const separatorIndex = content.indexOf(\"://\");\n if (separatorIndex === -1) {\n throw new ParseError(`Invalid ARP URL: missing \"://\"`, url);\n }\n\n const typePart = content.substring(0, separatorIndex);\n const location = content.substring(separatorIndex + 3);\n\n // 3. Split type part by :\n const colonIndex = typePart.indexOf(\":\");\n if (colonIndex === -1) {\n throw new ParseError(`Invalid ARP URL: must have exactly 2 types (semantic:transport)`, url);\n }\n\n const semantic = typePart.substring(0, colonIndex);\n const transport = typePart.substring(colonIndex + 1);\n\n // 4. Validate non-empty\n if (!semantic) {\n throw new ParseError(`Invalid ARP URL: semantic type cannot be empty`, url);\n }\n if (!transport) {\n throw new ParseError(`Invalid ARP URL: transport type cannot be empty`, url);\n }\n if (!location) {\n throw new ParseError(`Invalid ARP URL: location cannot be empty`, url);\n }\n\n return { semantic, transport, location };\n}\n",
|
|
7
|
+
"/**\n * HTTP/HTTPS Transport Handler\n */\n\nimport { TransportError } from \"../errors.js\";\nimport type { TransportHandler } from \"./types.js\";\n\nexport class HttpTransportHandler implements TransportHandler {\n readonly type: string;\n private readonly protocol: \"http\" | \"https\";\n\n constructor(protocol: \"http\" | \"https\" = \"https\") {\n this.protocol = protocol;\n this.type = protocol;\n }\n\n async fetch(location: string): Promise<Buffer> {\n const url = `${this.protocol}://${location}`;\n\n try {\n const response = await fetch(url);\n\n if (!response.ok) {\n throw new TransportError(\n `HTTP ${response.status}: ${response.statusText} - ${url}`,\n this.type\n );\n }\n\n const arrayBuffer = await response.arrayBuffer();\n return Buffer.from(arrayBuffer);\n } catch (error) {\n if (error instanceof TransportError) {\n throw error;\n }\n throw new TransportError(`Network error: ${url}`, this.type, { cause: error as Error });\n }\n }\n}\n\nexport const httpsHandler: HttpTransportHandler = new HttpTransportHandler(\"https\");\nexport const httpHandler: HttpTransportHandler = new HttpTransportHandler(\"http\");\n",
|
|
8
|
+
"/**\n * File Transport Handler\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { resolve } from \"node:path\";\nimport { TransportError } from \"../errors.js\";\nimport type { TransportHandler } from \"./types.js\";\n\nexport class FileTransportHandler implements TransportHandler {\n readonly type = \"file\";\n\n async fetch(location: string): Promise<Buffer> {\n const filePath = resolve(process.cwd(), location);\n\n try {\n return await readFile(filePath);\n } catch (error) {\n const err = error as Error & { code?: string };\n throw new TransportError(`File read error: ${err.code} - ${filePath}`, this.type, {\n cause: err,\n });\n }\n }\n}\n\nexport const fileHandler: FileTransportHandler = new FileTransportHandler();\n",
|
|
9
|
+
"/**\n * Transport Handlers Registry\n */\n\nimport { TransportError } from \"../errors.js\";\n\nexport type { TransportHandler } from \"./types.js\";\nexport { HttpTransportHandler, httpsHandler, httpHandler } from \"./http.js\";\nexport { FileTransportHandler, fileHandler } from \"./file.js\";\n\nimport type { TransportHandler } from \"./types.js\";\nimport { httpsHandler, httpHandler } from \"./http.js\";\nimport { fileHandler } from \"./file.js\";\n\nconst handlers = new Map<string, TransportHandler>([\n [\"https\", httpsHandler],\n [\"http\", httpHandler],\n [\"file\", fileHandler],\n]);\n\n/**\n * Get transport handler by type\n */\nexport function getTransportHandler(type: string): TransportHandler {\n const handler = handlers.get(type);\n if (!handler) {\n throw new TransportError(`Unsupported transport type: ${type}`, type);\n }\n return handler;\n}\n\n/**\n * Register a custom transport handler\n */\nexport function registerTransportHandler(handler: TransportHandler): void {\n handlers.set(handler.type, handler);\n}\n",
|
|
10
|
+
"/**\n * Text Semantic Handler\n * Handles plain text resources\n */\n\nimport type { Resource, SemanticHandler, ParseContext, ResourceMeta } from \"./types.js\";\n\nexport interface TextResource extends Resource<string> {\n type: \"text\";\n content: string;\n}\n\nexport class TextSemanticHandler implements SemanticHandler<string> {\n readonly type = \"text\";\n\n parse(content: Buffer, context: ParseContext): TextResource {\n const text = content.toString(\"utf-8\");\n\n const meta: ResourceMeta = {\n url: context.url,\n semantic: context.semantic,\n transport: context.transport,\n location: context.location,\n size: content.length,\n encoding: \"utf-8\",\n mimeType: \"text/plain\",\n fetchedAt: context.fetchedAt.toISOString(),\n };\n\n return {\n type: \"text\",\n content: text,\n meta,\n };\n }\n}\n\nexport const textHandler: TextSemanticHandler = new TextSemanticHandler();\n",
|
|
11
|
+
"/**\n * Semantic Handlers Registry\n */\n\nimport { SemanticError } from \"../errors.js\";\n\nexport type { Resource, SemanticHandler, ResourceMeta, ParseContext } from \"./types.js\";\nexport type { TextResource } from \"./text.js\";\nexport { TextSemanticHandler, textHandler } from \"./text.js\";\n\nimport type { SemanticHandler } from \"./types.js\";\nimport { textHandler } from \"./text.js\";\n\nconst handlers: Map<string, SemanticHandler> = new Map([[\"text\", textHandler]]);\n\n/**\n * Get semantic handler by type\n */\nexport function getSemanticHandler(type: string): SemanticHandler {\n const handler = handlers.get(type);\n if (!handler) {\n throw new SemanticError(`Unsupported semantic type: ${type}`, type);\n }\n return handler;\n}\n\n/**\n * Register a custom semantic handler\n */\nexport function registerSemanticHandler(handler: SemanticHandler): void {\n handlers.set(handler.type, handler);\n}\n",
|
|
12
|
+
"/**\n * Resource Resolution\n * End-to-end flow: URL parse → Transport fetch → Semantic parse\n */\n\nimport { parseARP } from \"./parser.js\";\nimport { getTransportHandler } from \"./transport/index.js\";\nimport { getSemanticHandler, type Resource, type ParseContext } from \"./semantic/index.js\";\n\n/**\n * Resolve an ARP URL to a resource\n *\n * @example\n * const resource = await resolve(\"arp:text:https://example.com/file.txt\");\n * // { type: \"text\", content: \"...\", meta: { ... } }\n */\nexport async function resolve(url: string): Promise<Resource> {\n const fetchedAt = new Date();\n\n // 1. Parse URL\n const parsed = parseARP(url);\n\n // 2. Get handlers\n const transportHandler = getTransportHandler(parsed.transport);\n const semanticHandler = getSemanticHandler(parsed.semantic);\n\n // 3. Fetch raw content\n const content = await transportHandler.fetch(parsed.location);\n\n // 4. Build context for semantic handler\n const context: ParseContext = {\n url,\n semantic: parsed.semantic,\n transport: parsed.transport,\n location: parsed.location,\n fetchedAt,\n };\n\n // 5. Parse and return\n return semanticHandler.parse(content, context);\n}\n",
|
|
13
|
+
"/**\n * @resourcexjs/core\n * ARP (Agent Resource Protocol) implementation\n */\n\nexport const VERSION = \"0.0.1\";\n\n// Errors\nexport { ResourceXError, ParseError, TransportError, SemanticError } from \"./errors.js\";\n\n// Parser\nexport { parseARP, type ParsedARP } from \"./parser.js\";\n\n// Transport\nexport {\n type TransportHandler,\n getTransportHandler,\n registerTransportHandler,\n httpsHandler,\n httpHandler,\n fileHandler,\n} from \"./transport/index.js\";\n\n// Semantic\nexport {\n type Resource,\n type SemanticHandler,\n type ResourceMeta,\n type ParseContext,\n type TextResource,\n getSemanticHandler,\n registerSemanticHandler,\n textHandler,\n} from \"./semantic/index.js\";\n\n// Resolve\nexport { resolve } from \"./resolve.js\";\n"
|
|
14
|
+
],
|
|
15
|
+
"mappings": "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",
|
|
16
|
+
"debugId": "7FDB8A773330183C64756E2164756E21",
|
|
17
|
+
"names": []
|
|
18
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@resourcexjs/core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "ResourceX Core - ARP (Agent Resource Protocol) implementation",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"resourcex",
|
|
7
|
+
"arp",
|
|
8
|
+
"agent",
|
|
9
|
+
"resource",
|
|
10
|
+
"protocol"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/Deepractice/ResourceX.git",
|
|
15
|
+
"directory": "packages/core"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=22.0.0"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist",
|
|
32
|
+
"README.md"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "bun run build.ts",
|
|
36
|
+
"lint": "eslint .",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"test": "bun test",
|
|
39
|
+
"clean": "rm -rf dist"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|