@synap-core/sdk 0.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,173 @@
1
+ # @synap/sdk
2
+
3
+ High-level SDK for Synap - Event-sourced personal data platform
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @synap/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { SynapSDK } from '@synap/sdk';
15
+
16
+ // Initialize SDK
17
+ const synap = new SynapSDK({
18
+ url: 'https://api.synap.app',
19
+ apiKey: 'your-api-key'
20
+ });
21
+
22
+ // Create entity (event-sourced)
23
+ const { entityId } = await synap.entities.create({
24
+ type: 'task',
25
+ title: 'Call Marie tomorrow',
26
+ metadata: {
27
+ dueDate: '2024-12-20',
28
+ priority: 'high'
29
+ }
30
+ });
31
+
32
+ // Create relationship (event-sourced)
33
+ await synap.relations.create(entityId, personId, 'assigned_to');
34
+
35
+ // Query data (direct reads)
36
+ const tasks = await synap.entities.list({ type: 'task' });
37
+ const history = await synap.events.getHistory(entityId);
38
+ ```
39
+
40
+ ## Architecture
41
+
42
+ ### Event Sourcing
43
+
44
+ All **mutations** go through event sourcing:
45
+ - `entities.create/update/delete` → `events.log` → Inngest worker → Database
46
+ - `relations.create/delete` → `events.log` → Inngest worker → Database
47
+
48
+ All **queries** are direct database reads:
49
+ - `entities.get/list/search` → Direct query
50
+ - `relations.get/getRelated` → Direct query
51
+ - `events.getHistory` → Direct query
52
+
53
+ ### Benefits
54
+
55
+ - **Audit trail**: Every change logged as immutable event
56
+ - **Time travel**: Replay events to see past states
57
+ - **Reliability**: Workers handle async processing with retries
58
+ - **Real-time**: Events trigger webhooks and SSE broadcasts
59
+
60
+ ## API Reference
61
+
62
+ ### Entities API
63
+
64
+ ```typescript
65
+ // Create
66
+ const { entityId } = await synap.entities.create({
67
+ type: 'note',
68
+ title: 'Meeting Notes',
69
+ content: '# Discussion points...'
70
+ });
71
+
72
+ // Update
73
+ await synap.entities.update(entityId, {
74
+ title: 'Updated Title'
75
+ });
76
+
77
+ // Delete (soft delete)
78
+ await synap.entities.delete(entityId);
79
+
80
+ // Get
81
+ const entity = await synap.entities.get(entityId);
82
+
83
+ // List
84
+ const notes = await synap.entities.list({
85
+ type: 'note',
86
+ limit: 20
87
+ });
88
+
89
+ // Search
90
+ const results = await synap.entities.search({
91
+ query: 'project planning',
92
+ types: ['note', 'task']
93
+ });
94
+ ```
95
+
96
+ ### Relations API
97
+
98
+ ```typescript
99
+ // Create relationship
100
+ await synap.relations.create(
101
+ sourceEntityId,
102
+ targetEntityId,
103
+ 'assigned_to'
104
+ );
105
+
106
+ // Get relations
107
+ const relations = await synap.relations.get(entityId, {
108
+ type: 'assigned_to',
109
+ direction: 'both' // 'source' | 'target' | 'both'
110
+ });
111
+
112
+ // Get related entities
113
+ const people = await synap.relations.getRelated(taskId, {
114
+ type: 'assigned_to',
115
+ direction: 'source'
116
+ });
117
+
118
+ // Get statistics
119
+ const stats = await synap.relations.getStats(entityId);
120
+ // Returns: { total, outgoing, incoming, byType }
121
+
122
+ // Delete relationship
123
+ await synap.relations.delete(relationId);
124
+ ```
125
+
126
+ ### Events API
127
+
128
+ ```typescript
129
+ // Get entity history
130
+ const history = await synap.events.getHistory(entityId, {
131
+ eventTypes: ['entities.create.validated'],
132
+ limit: 100
133
+ });
134
+
135
+ // Get user timeline
136
+ const timeline = await synap.events.getTimeline({
137
+ limit: 50
138
+ });
139
+
140
+ // Replay events to rebuild state
141
+ const state = await synap.events.replay(entityId);
142
+ ```
143
+
144
+ ## Entity Types
145
+
146
+ ```typescript
147
+ type EntityType =
148
+ | 'task'
149
+ | 'note'
150
+ | 'person'
151
+ | 'event'
152
+ | 'file';
153
+ ```
154
+
155
+ ## Relation Types
156
+
157
+ ```typescript
158
+ type RelationType =
159
+ | 'assigned_to' // Task → Person
160
+ | 'mentions' // Note → Entity
161
+ | 'links_to' // Note → Note
162
+ | 'parent_of' // Project → Task
163
+ | 'relates_to' // Generic
164
+ | 'tagged_with' // Entity → Tag
165
+ | 'created_by' // Entity → Person
166
+ | 'attended_by' // Event → Person
167
+ | 'depends_on' // Task → Task
168
+ | 'blocks'; // Task → Task
169
+ ```
170
+
171
+ ## License
172
+
173
+ AGPL-3.0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * SynapSDK - Main SDK Client
3
+ *
4
+ * Provides high-level APIs for interacting with Synap Data Pod.
5
+ * All mutations go through event sourcing, all queries are direct reads.
6
+ */
7
+ import { type SynapClient as TRPCClient } from '@synap/client';
8
+ import { EntitiesAPI } from './resources/entities.js';
9
+ import { RelationsAPI } from './resources/relations.js';
10
+ import { EventsAPI } from './resources/events.js';
11
+ /**
12
+ * SDK Configuration
13
+ */
14
+ export interface SynapSDKConfig {
15
+ /**
16
+ * Base URL for the Synap API
17
+ * @example 'https://api.synap.app' or 'http://localhost:3000'
18
+ */
19
+ url: string;
20
+ /**
21
+ * API key or authentication token
22
+ * Either provide apiKey OR headers function
23
+ */
24
+ apiKey?: string;
25
+ /**
26
+ * Custom headers function for dynamic authentication
27
+ * @example () => ({ Authorization: `Bearer ${getToken()}` })
28
+ */
29
+ headers?: () => Record<string, string> | Promise<Record<string, string>>;
30
+ /**
31
+ * Custom fetch implementation (for React Native, etc.)
32
+ */
33
+ fetch?: typeof globalThis.fetch;
34
+ }
35
+ /**
36
+ * Synap SDK - High-Level Client
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const synap = new SynapSDK({
41
+ * url: 'https://api.synap.app',
42
+ * apiKey: 'sk_...'
43
+ * });
44
+ *
45
+ * // Use resource APIs
46
+ * const task = await synap.entities.create({ type: 'task', title: 'Call Marie' });
47
+ * await synap.relations.create(task.id, personId, 'assigned_to');
48
+ * const history = await synap.events.getHistory(task.id);
49
+ * ```
50
+ */
51
+ export declare class SynapSDK {
52
+ /** Internal tRPC client */
53
+ private readonly trpc;
54
+ /** Entities API - Generic entity operations */
55
+ readonly entities: EntitiesAPI;
56
+ /** Relations API - Relationship management */
57
+ readonly relations: RelationsAPI;
58
+ /** Events API - Event history and replay */
59
+ readonly events: EventsAPI;
60
+ constructor(config: SynapSDKConfig);
61
+ /**
62
+ * Get direct access to underlying tRPC client
63
+ * Use this for advanced operations not covered by SDK APIs
64
+ */
65
+ get client(): TRPCClient;
66
+ }
67
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAqB,KAAK,WAAW,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAEzE;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACjC;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,QAAQ;IACnB,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAElC,+CAA+C;IAC/C,SAAgB,QAAQ,EAAE,WAAW,CAAC;IAEtC,8CAA8C;IAC9C,SAAgB,SAAS,EAAE,YAAY,CAAC;IAExC,4CAA4C;IAC5C,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,MAAM,EAAE,cAAc;IAgBlC;;;OAGG;IACH,IAAI,MAAM,IAAI,UAAU,CAEvB;CACF"}
package/dist/client.js ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * SynapSDK - Main SDK Client
3
+ *
4
+ * Provides high-level APIs for interacting with Synap Data Pod.
5
+ * All mutations go through event sourcing, all queries are direct reads.
6
+ */
7
+ import { createSynapClient } from '@synap/client';
8
+ import { EntitiesAPI } from './resources/entities.js';
9
+ import { RelationsAPI } from './resources/relations.js';
10
+ import { EventsAPI } from './resources/events.js';
11
+ /**
12
+ * Synap SDK - High-Level Client
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const synap = new SynapSDK({
17
+ * url: 'https://api.synap.app',
18
+ * apiKey: 'sk_...'
19
+ * });
20
+ *
21
+ * // Use resource APIs
22
+ * const task = await synap.entities.create({ type: 'task', title: 'Call Marie' });
23
+ * await synap.relations.create(task.id, personId, 'assigned_to');
24
+ * const history = await synap.events.getHistory(task.id);
25
+ * ```
26
+ */
27
+ export class SynapSDK {
28
+ /** Internal tRPC client */
29
+ trpc;
30
+ /** Entities API - Generic entity operations */
31
+ entities;
32
+ /** Relations API - Relationship management */
33
+ relations;
34
+ /** Events API - Event history and replay */
35
+ events;
36
+ constructor(config) {
37
+ // Create underlying tRPC client
38
+ this.trpc = createSynapClient({
39
+ url: config.url,
40
+ headers: config.apiKey
41
+ ? { Authorization: `Bearer ${config.apiKey}` }
42
+ : config.headers,
43
+ fetch: config.fetch,
44
+ });
45
+ // Initialize resource APIs
46
+ this.entities = new EntitiesAPI(this.trpc);
47
+ this.relations = new RelationsAPI(this.trpc);
48
+ this.events = new EventsAPI(this.trpc);
49
+ }
50
+ /**
51
+ * Get direct access to underlying tRPC client
52
+ * Use this for advanced operations not covered by SDK APIs
53
+ */
54
+ get client() {
55
+ return this.trpc;
56
+ }
57
+ }
58
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,iBAAiB,EAAkC,MAAM,eAAe,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AA8BlD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,QAAQ;IACnB,2BAA2B;IACV,IAAI,CAAa;IAElC,+CAA+C;IAC/B,QAAQ,CAAc;IAEtC,8CAA8C;IAC9B,SAAS,CAAe;IAExC,4CAA4C;IAC5B,MAAM,CAAY;IAElC,YAAY,MAAsB;QAChC,gCAAgC;QAChC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;YAC5B,GAAG,EAAE,MAAM,CAAC,GAAG;YACf,OAAO,EAAE,MAAM,CAAC,MAAM;gBACpB,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE,EAAE;gBAC9C,CAAC,CAAC,MAAM,CAAC,OAAO;YAClB,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC,CAAC;QAEH,2BAA2B;QAC3B,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @synap/sdk - High-Level SDK for Synap
3
+ *
4
+ * Event-sourced personal data platform SDK with type-safe APIs.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { SynapSDK } from '@synap/sdk';
9
+ *
10
+ * const synap = new SynapSDK({
11
+ * url: 'https://api.synap.app',
12
+ * apiKey: 'your-api-key'
13
+ * });
14
+ *
15
+ * // Create entity (event-sourced)
16
+ * const task = await synap.entities.create({
17
+ * type: 'task',
18
+ * title: 'Call Marie',
19
+ * metadata: { dueDate: '2024-12-20', priority: 'high' }
20
+ * });
21
+ *
22
+ * // Create relationship (event-sourced)
23
+ * await synap.relations.create(taskId, personId, 'assigned_to');
24
+ *
25
+ * // Query data (direct read)
26
+ * const tasks = await synap.entities.list({ type: 'task' });
27
+ * const history = await synap.events.getHistory(taskId);
28
+ * ```
29
+ */
30
+ export { SynapSDK, type SynapSDKConfig } from './client.js';
31
+ export { EntitiesAPI } from './resources/entities.js';
32
+ export { RelationsAPI } from './resources/relations.js';
33
+ export { EventsAPI } from './resources/events.js';
34
+ export type { EntityType, EntityMetadata, Entity, NewEntity, UpdateEntity, } from '@synap/types/entities';
35
+ export type { Relation, RelationType, } from './types/relations.js';
36
+ export type { Event, EventFilter, } from './types/events.js';
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGlD,YAAY,EACV,UAAU,EACV,cAAc,EACd,MAAM,EACN,SAAS,EACT,YAAY,GACb,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,QAAQ,EACR,YAAY,GACb,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,KAAK,EACL,WAAW,GACZ,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @synap/sdk - High-Level SDK for Synap
3
+ *
4
+ * Event-sourced personal data platform SDK with type-safe APIs.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { SynapSDK } from '@synap/sdk';
9
+ *
10
+ * const synap = new SynapSDK({
11
+ * url: 'https://api.synap.app',
12
+ * apiKey: 'your-api-key'
13
+ * });
14
+ *
15
+ * // Create entity (event-sourced)
16
+ * const task = await synap.entities.create({
17
+ * type: 'task',
18
+ * title: 'Call Marie',
19
+ * metadata: { dueDate: '2024-12-20', priority: 'high' }
20
+ * });
21
+ *
22
+ * // Create relationship (event-sourced)
23
+ * await synap.relations.create(taskId, personId, 'assigned_to');
24
+ *
25
+ * // Query data (direct read)
26
+ * const tasks = await synap.entities.list({ type: 'task' });
27
+ * const history = await synap.events.getHistory(taskId);
28
+ * ```
29
+ */
30
+ export { SynapSDK } from './client.js';
31
+ export { EntitiesAPI } from './resources/entities.js';
32
+ export { RelationsAPI } from './resources/relations.js';
33
+ export { EventsAPI } from './resources/events.js';
34
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Entities API - Generic Entity Operations
3
+ *
4
+ * ALL MUTATIONS are event-sourced (go through events.log)
5
+ * ALL QUERIES are direct reads (fast)
6
+ */
7
+ import type { SynapClient } from '@synap/client';
8
+ import type { EntityType } from '@synap/types/entities';
9
+ export interface CreateEntityInput<T extends EntityType = EntityType> {
10
+ type: T;
11
+ title: string;
12
+ preview?: string;
13
+ content?: string;
14
+ metadata?: Record<string, unknown>;
15
+ }
16
+ export interface UpdateEntityInput {
17
+ title?: string;
18
+ preview?: string;
19
+ content?: string;
20
+ metadata?: Record<string, unknown>;
21
+ }
22
+ export interface ListEntitiesOptions {
23
+ type?: EntityType;
24
+ limit?: number;
25
+ }
26
+ export interface SearchOptions {
27
+ query: string;
28
+ types?: EntityType[];
29
+ limit?: number;
30
+ }
31
+ /**
32
+ * Entities API
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * // Create task (event-sourced)
37
+ * const task = await sdk.entities.create({
38
+ * type: 'task',
39
+ * title: 'Call Marie',
40
+ * metadata: { dueDate: '2024-12-20', priority: 'high' }
41
+ * });
42
+ *
43
+ * // Get entity (direct read)
44
+ * const entity = await sdk.entities.get(task.id);
45
+ *
46
+ * // List entities (direct read)
47
+ * const tasks = await sdk.entities.list({ type: 'task' });
48
+ * ```
49
+ */
50
+ export declare class EntitiesAPI {
51
+ private readonly client;
52
+ constructor(client: SynapClient);
53
+ /**
54
+ * Create entity (event-sourced)
55
+ *
56
+ * Publishes `entities.create.requested` event → entitiesWorker → DB
57
+ */
58
+ create<T extends EntityType>(input: CreateEntityInput<T>): Promise<{
59
+ entityId: string;
60
+ }>;
61
+ /**
62
+ * Update entity (event-sourced)
63
+ *
64
+ * Publishes `entities.update.requested` event → entitiesWorker → DB
65
+ */
66
+ update(id: string, input: UpdateEntityInput): Promise<{
67
+ success: boolean;
68
+ }>;
69
+ /**
70
+ * Delete entity (event-sourced soft delete)
71
+ *
72
+ * Publishes `entities.delete.requested` event → entitiesWorker → DB
73
+ */
74
+ delete(id: string): Promise<{
75
+ success: boolean;
76
+ }>;
77
+ /**
78
+ * Get entity by ID (direct read)
79
+ */
80
+ get(id: string): Promise<{
81
+ type: string;
82
+ userId: string;
83
+ version: number;
84
+ id: string;
85
+ title: string | null;
86
+ preview: string | null;
87
+ documentId: string | null;
88
+ fileUrl: string | null;
89
+ filePath: string | null;
90
+ fileSize: number | null;
91
+ fileType: string | null;
92
+ checksum: string | null;
93
+ createdAt: string;
94
+ updatedAt: string;
95
+ deletedAt: string | null;
96
+ metadata?: unknown;
97
+ }>;
98
+ /**
99
+ * List entities (direct read)
100
+ */
101
+ list(options?: ListEntitiesOptions): Promise<{
102
+ type: string;
103
+ userId: string;
104
+ version: number;
105
+ id: string;
106
+ title: string | null;
107
+ preview: string | null;
108
+ documentId: string | null;
109
+ fileUrl: string | null;
110
+ filePath: string | null;
111
+ fileSize: number | null;
112
+ fileType: string | null;
113
+ checksum: string | null;
114
+ createdAt: string;
115
+ updatedAt: string;
116
+ deletedAt: string | null;
117
+ metadata?: unknown;
118
+ }[]>;
119
+ /**
120
+ * Search entities (direct read)
121
+ */
122
+ search(options: SearchOptions): Promise<{
123
+ type: string;
124
+ userId: string;
125
+ version: number;
126
+ id: string;
127
+ title: string | null;
128
+ preview: string | null;
129
+ documentId: string | null;
130
+ fileUrl: string | null;
131
+ filePath: string | null;
132
+ fileSize: number | null;
133
+ fileType: string | null;
134
+ checksum: string | null;
135
+ createdAt: string;
136
+ updatedAt: string;
137
+ deletedAt: string | null;
138
+ metadata?: unknown;
139
+ }[]>;
140
+ }
141
+ //# sourceMappingURL=entities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/resources/entities.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGxD,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IAClE,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,WAAW;IAEhD;;;;OAIG;IACG,MAAM,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAwB9F;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAiBjF;;;;OAIG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAgBvD;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;IAKpB;;OAEG;IACG,IAAI,CAAC,OAAO,GAAE,mBAAwB;;;;;;;;;;;;;;;;;;IAQ5C;;OAEG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa;;;;;;;;;;;;;;;;;;CAQpC"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Entities API - Generic Entity Operations
3
+ *
4
+ * ALL MUTATIONS are event-sourced (go through events.log)
5
+ * ALL QUERIES are direct reads (fast)
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ /**
9
+ * Entities API
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Create task (event-sourced)
14
+ * const task = await sdk.entities.create({
15
+ * type: 'task',
16
+ * title: 'Call Marie',
17
+ * metadata: { dueDate: '2024-12-20', priority: 'high' }
18
+ * });
19
+ *
20
+ * // Get entity (direct read)
21
+ * const entity = await sdk.entities.get(task.id);
22
+ *
23
+ * // List entities (direct read)
24
+ * const tasks = await sdk.entities.list({ type: 'task' });
25
+ * ```
26
+ */
27
+ export class EntitiesAPI {
28
+ client;
29
+ constructor(client) {
30
+ this.client = client;
31
+ }
32
+ /**
33
+ * Create entity (event-sourced)
34
+ *
35
+ * Publishes `entities.create.requested` event → entitiesWorker → DB
36
+ */
37
+ async create(input) {
38
+ const entityId = randomUUID();
39
+ // Call events.log to publish create event
40
+ await this.client.events.log.mutate({
41
+ aggregateId: entityId,
42
+ aggregateType: 'entity',
43
+ eventType: 'entities.create.requested',
44
+ data: {
45
+ id: entityId,
46
+ entityType: input.type,
47
+ title: input.title,
48
+ preview: input.preview,
49
+ content: input.content,
50
+ metadata: input.metadata,
51
+ },
52
+ metadata: {},
53
+ version: 1,
54
+ source: 'api',
55
+ });
56
+ return { entityId };
57
+ }
58
+ /**
59
+ * Update entity (event-sourced)
60
+ *
61
+ * Publishes `entities.update.requested` event → entitiesWorker → DB
62
+ */
63
+ async update(id, input) {
64
+ await this.client.events.log.mutate({
65
+ aggregateId: id,
66
+ aggregateType: 'entity',
67
+ eventType: 'entities.update.requested',
68
+ data: {
69
+ entityId: id,
70
+ ...input,
71
+ },
72
+ metadata: {},
73
+ version: 1, // TODO: Get actual version
74
+ source: 'api',
75
+ });
76
+ return { success: true };
77
+ }
78
+ /**
79
+ * Delete entity (event-sourced soft delete)
80
+ *
81
+ * Publishes `entities.delete.requested` event → entitiesWorker → DB
82
+ */
83
+ async delete(id) {
84
+ await this.client.events.log.mutate({
85
+ aggregateId: id,
86
+ aggregateType: 'entity',
87
+ eventType: 'entities.delete.requested',
88
+ data: {
89
+ entityId: id,
90
+ },
91
+ metadata: {},
92
+ version: 1,
93
+ source: 'api',
94
+ });
95
+ return { success: true };
96
+ }
97
+ /**
98
+ * Get entity by ID (direct read)
99
+ */
100
+ async get(id) {
101
+ const result = await this.client.entities.get.query({ id });
102
+ return result.entity;
103
+ }
104
+ /**
105
+ * List entities (direct read)
106
+ */
107
+ async list(options = {}) {
108
+ const result = await this.client.entities.list.query({
109
+ type: options.type, // Type cast because router has different enum
110
+ limit: options.limit || 50,
111
+ });
112
+ return result.entities;
113
+ }
114
+ /**
115
+ * Search entities (direct read)
116
+ */
117
+ async search(options) {
118
+ const result = await this.client.entities.search.query({
119
+ query: options.query,
120
+ type: options.types?.[0], // Type cast because router has different enum
121
+ limit: options.limit || 10,
122
+ });
123
+ return result.entities;
124
+ }
125
+ }
126
+ //# sourceMappingURL=entities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entities.js","sourceRoot":"","sources":["../../src/resources/entities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Events API - Event History and Replay
3
+ *
4
+ * ALL OPERATIONS are direct reads (query event log)
5
+ */
6
+ import type { SynapClient } from '@synap/client';
7
+ import type { Event, EventFilter } from '../types/events.js';
8
+ /**
9
+ * Events API
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Get event history for an entity
14
+ * const history = await sdk.events.getHistory(taskId);
15
+ *
16
+ * // Get user's event timeline
17
+ * const timeline = await sdk.events.getTimeline({
18
+ * limit: 100,
19
+ * after: new Date('2024-01-01')
20
+ * });
21
+ *
22
+ * // Filter by event types
23
+ * const creates = await sdk.events.getHistory(entityId, {
24
+ * eventTypes: ['entities.create.validated', 'entities.update.validated']
25
+ * });
26
+ * ```
27
+ */
28
+ export declare class EventsAPI {
29
+ private readonly client;
30
+ constructor(client: SynapClient);
31
+ /**
32
+ * Get event history for a specific subject (entity, relation, etc.)
33
+ *
34
+ * Returns all events related to the subject in chronological order
35
+ */
36
+ getHistory(subjectId: string, options?: Omit<EventFilter, 'subjectId'>): Promise<Event[]>;
37
+ /**
38
+ * Get user's complete event timeline
39
+ *
40
+ * Returns all events for the current user
41
+ */
42
+ getTimeline(options?: EventFilter): Promise<Event[]>;
43
+ /**
44
+ * Replay events to rebuild entity state
45
+ *
46
+ * Note: This is a client-side replay for now.
47
+ * For production, server-side projector rebuild is recommended.
48
+ */
49
+ replay(subjectId: string): Promise<any>;
50
+ }
51
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/resources/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,WAAW;IAEhD;;;;OAIG;IACG,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAM,GAC3C,OAAO,CAAC,KAAK,EAAE,CAAC;IAmBnB;;;;OAIG;IACG,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAS9D;;;;;OAKG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;CAyB9C"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Events API - Event History and Replay
3
+ *
4
+ * ALL OPERATIONS are direct reads (query event log)
5
+ */
6
+ /**
7
+ * Events API
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * // Get event history for an entity
12
+ * const history = await sdk.events.getHistory(taskId);
13
+ *
14
+ * // Get user's event timeline
15
+ * const timeline = await sdk.events.getTimeline({
16
+ * limit: 100,
17
+ * after: new Date('2024-01-01')
18
+ * });
19
+ *
20
+ * // Filter by event types
21
+ * const creates = await sdk.events.getHistory(entityId, {
22
+ * eventTypes: ['entities.create.validated', 'entities.update.validated']
23
+ * });
24
+ * ```
25
+ */
26
+ export class EventsAPI {
27
+ client;
28
+ constructor(client) {
29
+ this.client = client;
30
+ }
31
+ /**
32
+ * Get event history for a specific subject (entity, relation, etc.)
33
+ *
34
+ * Returns all events related to the subject in chronological order
35
+ */
36
+ async getHistory(subjectId, options = {}) {
37
+ const events = await this.client.events.list.query({
38
+ // Note: The current events.list doesn't support subjectId filter
39
+ // For now, we'll get all events and filter client-side
40
+ // TODO: Enhance events.list router to support subjectId
41
+ limit: options.limit || 50,
42
+ type: options.eventTypes?.[0], // Current API only supports single type
43
+ });
44
+ // Client-side filter by subjectId
45
+ // TODO: Move this to server-side once router enhanced
46
+ // Type cast to any because Event shape from router doesn't match our SDK Event type
47
+ return events.filter((event) => event.data?.entityId === subjectId ||
48
+ event.data?.relationId === subjectId ||
49
+ event.data?.subjectId === subjectId);
50
+ }
51
+ /**
52
+ * Get user's complete event timeline
53
+ *
54
+ * Returns all events for the current user
55
+ */
56
+ async getTimeline(options = {}) {
57
+ const events = await this.client.events.list.query({
58
+ limit: options.limit || 50,
59
+ type: options.eventTypes?.[0],
60
+ });
61
+ return events;
62
+ }
63
+ /**
64
+ * Replay events to rebuild entity state
65
+ *
66
+ * Note: This is a client-side replay for now.
67
+ * For production, server-side projector rebuild is recommended.
68
+ */
69
+ async replay(subjectId) {
70
+ const events = await this.getHistory(subjectId);
71
+ // Simple event replay (can be enhanced)
72
+ let state = {};
73
+ for (const event of events) {
74
+ switch (event.type) {
75
+ case 'entity.created':
76
+ case 'entities.create.validated':
77
+ state = { ...event.data };
78
+ break;
79
+ case 'entity.updated':
80
+ case 'entities.update.validated':
81
+ state = { ...state, ...event.data };
82
+ break;
83
+ case 'entity.deleted':
84
+ case 'entities.delete.validated':
85
+ state.deletedAt = event.timestamp;
86
+ break;
87
+ }
88
+ }
89
+ return state;
90
+ }
91
+ }
92
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/resources/events.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,SAAS;IACS;IAA7B,YAA6B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;IAAG,CAAC;IAEpD;;;;OAIG;IACH,KAAK,CAAC,UAAU,CACd,SAAiB,EACjB,UAA0C,EAAE;QAE5C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YACjD,iEAAiE;YACjE,uDAAuD;YACvD,wDAAwD;YACxD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,wCAAwC;SACxE,CAAC,CAAC;QAEH,kCAAkC;QAClC,sDAAsD;QACtD,oFAAoF;QACpF,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAU,EAAE,EAAE,CAClC,KAAK,CAAC,IAAI,EAAE,QAAQ,KAAK,SAAS;YAClC,KAAK,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;YACpC,KAAK,CAAC,IAAI,EAAE,SAAS,KAAK,SAAS,CAC3B,CAAC;IACb,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,UAAuB,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;YACjD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;SAC9B,CAAC,CAAC;QAEH,OAAO,MAAe,CAAC;IACzB,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,MAAM,CAAC,SAAiB;QAC5B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAEhD,wCAAwC;QACxC,IAAI,KAAK,GAAQ,EAAE,CAAC;QAEpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,gBAAgB,CAAC;gBACtB,KAAK,2BAA2B;oBAC9B,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;oBAC1B,MAAM;gBACR,KAAK,gBAAgB,CAAC;gBACtB,KAAK,2BAA2B;oBAC9B,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;oBACpC,MAAM;gBACR,KAAK,gBAAgB,CAAC;gBACtB,KAAK,2BAA2B;oBAC9B,KAAK,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;oBAClC,MAAM;YACV,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Relations API - Universal Relationship Management
3
+ *
4
+ * ALL MUTATIONS are event-sourced (go through events.log)
5
+ * ALL QUERIES are direct reads (fast)
6
+ */
7
+ import type { SynapClient } from '@synap/client';
8
+ import type { RelationType, Relation, RelationFilter } from '../types/relations.js';
9
+ /**
10
+ * Relations API
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Create relationship (event-sourced)
15
+ * await sdk.relations.create(taskId, personId, 'assigned_to');
16
+ *
17
+ * // Get relations (direct read)
18
+ * const relations = await sdk.relations.get(entityId, {
19
+ * type: 'assigned_to',
20
+ * direction: 'both'
21
+ * });
22
+ *
23
+ * // Get related entities (direct read)
24
+ * const people = await sdk.relations.getRelated(taskId, {
25
+ * type: 'assigned_to',
26
+ * direction: 'source'
27
+ * });
28
+ * ```
29
+ */
30
+ export declare class RelationsAPI {
31
+ private readonly client;
32
+ constructor(client: SynapClient);
33
+ /**
34
+ * Create relationship (event-sourced)
35
+ *
36
+ * Publishes `relations.create.requested` event → relationsWorker → DB
37
+ *
38
+ * @param sourceId - Source entity ID
39
+ * @param targetId - Target entity ID
40
+ * @param type - Relationship type
41
+ * @param metadata - Optional metadata
42
+ */
43
+ create(sourceId: string, targetId: string, type: RelationType | string, metadata?: Record<string, unknown>): Promise<{
44
+ relationId: string;
45
+ }>;
46
+ /**
47
+ * Delete relationship (event-sourced)
48
+ *
49
+ * Publishes `relations.delete.requested` event → relationsWorker → DB
50
+ */
51
+ delete(relationId: string): Promise<{
52
+ success: boolean;
53
+ }>;
54
+ /**
55
+ * Get relations for an entity (direct read)
56
+ *
57
+ * Returns relationship records (not the related entities themselves)
58
+ */
59
+ get(entityId: string, options?: Omit<RelationFilter, 'entityId'>): Promise<Relation[]>;
60
+ /**
61
+ * Get related entities (direct read with join)
62
+ *
63
+ * Returns the actual entity objects that are related
64
+ */
65
+ getRelated(entityId: string, options?: Omit<RelationFilter, 'entityId'>): Promise<any>;
66
+ /**
67
+ * Get relation statistics for an entity (direct read)
68
+ */
69
+ getStats(entityId: string): Promise<any>;
70
+ }
71
+ //# sourceMappingURL=relations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/resources/relations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGpF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,WAAW;IAEhD;;;;;;;;;OASG;IACG,MAAM,CACV,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,YAAY,GAAG,MAAM,EAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAsBlC;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAgB/D;;;;OAIG;IACG,GAAG,CACP,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAM,GAC7C,OAAO,CAAC,QAAQ,EAAE,CAAC;IAYtB;;;;OAIG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,UAAU,CAAM;IAahD;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM;CAKhC"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Relations API - Universal Relationship Management
3
+ *
4
+ * ALL MUTATIONS are event-sourced (go through events.log)
5
+ * ALL QUERIES are direct reads (fast)
6
+ */
7
+ import { randomUUID } from 'node:crypto';
8
+ /**
9
+ * Relations API
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Create relationship (event-sourced)
14
+ * await sdk.relations.create(taskId, personId, 'assigned_to');
15
+ *
16
+ * // Get relations (direct read)
17
+ * const relations = await sdk.relations.get(entityId, {
18
+ * type: 'assigned_to',
19
+ * direction: 'both'
20
+ * });
21
+ *
22
+ * // Get related entities (direct read)
23
+ * const people = await sdk.relations.getRelated(taskId, {
24
+ * type: 'assigned_to',
25
+ * direction: 'source'
26
+ * });
27
+ * ```
28
+ */
29
+ export class RelationsAPI {
30
+ client;
31
+ constructor(client) {
32
+ this.client = client;
33
+ }
34
+ /**
35
+ * Create relationship (event-sourced)
36
+ *
37
+ * Publishes `relations.create.requested` event → relationsWorker → DB
38
+ *
39
+ * @param sourceId - Source entity ID
40
+ * @param targetId - Target entity ID
41
+ * @param type - Relationship type
42
+ * @param metadata - Optional metadata
43
+ */
44
+ async create(sourceId, targetId, type, metadata) {
45
+ const relationId = randomUUID();
46
+ await this.client.events.log.mutate({
47
+ aggregateId: relationId,
48
+ aggregateType: 'relation',
49
+ eventType: 'relations.create.requested',
50
+ data: {
51
+ id: relationId,
52
+ sourceEntityId: sourceId,
53
+ targetEntityId: targetId,
54
+ type,
55
+ metadata,
56
+ },
57
+ metadata: {},
58
+ version: 1,
59
+ source: 'api',
60
+ });
61
+ return { relationId };
62
+ }
63
+ /**
64
+ * Delete relationship (event-sourced)
65
+ *
66
+ * Publishes `relations.delete.requested` event → relationsWorker → DB
67
+ */
68
+ async delete(relationId) {
69
+ await this.client.events.log.mutate({
70
+ aggregateId: relationId,
71
+ aggregateType: 'relation',
72
+ eventType: 'relations.delete.requested',
73
+ data: {
74
+ relationId,
75
+ },
76
+ metadata: {},
77
+ version: 1,
78
+ source: 'api',
79
+ });
80
+ return { success: true };
81
+ }
82
+ /**
83
+ * Get relations for an entity (direct read)
84
+ *
85
+ * Returns relationship records (not the related entities themselves)
86
+ */
87
+ async get(entityId, options = {}) {
88
+ // Type assertion needed because relations router not in AppRouter type yet
89
+ const result = await this.client.relations.get.query({
90
+ entityId,
91
+ type: options.type,
92
+ direction: options.direction || 'both',
93
+ limit: options.limit || 50,
94
+ });
95
+ return result.relations;
96
+ }
97
+ /**
98
+ * Get related entities (direct read with join)
99
+ *
100
+ * Returns the actual entity objects that are related
101
+ */
102
+ async getRelated(entityId, options = {}) {
103
+ // Type assertion needed because relations router not in AppRouter type yet
104
+ const result = await this.client.relations.getRelated.query({
105
+ entityId,
106
+ type: options.type,
107
+ direction: options.direction || 'both',
108
+ limit: options.limit || 50,
109
+ });
110
+ return result.entities;
111
+ }
112
+ /**
113
+ * Get relation statistics for an entity (direct read)
114
+ */
115
+ async getStats(entityId) {
116
+ // Type assertion needed because relations router not in AppRouter type yet
117
+ const result = await this.client.relations.getStats.query({ entityId });
118
+ return result;
119
+ }
120
+ }
121
+ //# sourceMappingURL=relations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/resources/relations.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,MAAmB;QAAnB,WAAM,GAAN,MAAM,CAAa;IAAG,CAAC;IAEpD;;;;;;;;;OASG;IACH,KAAK,CAAC,MAAM,CACV,QAAgB,EAChB,QAAgB,EAChB,IAA2B,EAC3B,QAAkC;QAElC,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;QAEhC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YAClC,WAAW,EAAE,UAAU;YACvB,aAAa,EAAE,UAAU;YACzB,SAAS,EAAE,4BAA4B;YACvC,IAAI,EAAE;gBACJ,EAAE,EAAE,UAAU;gBACd,cAAc,EAAE,QAAQ;gBACxB,cAAc,EAAE,QAAQ;gBACxB,IAAI;gBACJ,QAAQ;aACT;YACD,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,OAAO,EAAE,UAAU,EAAE,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM,CAAC,UAAkB;QAC7B,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC;YAClC,WAAW,EAAE,UAAU;YACvB,aAAa,EAAE,UAAU;YACzB,SAAS,EAAE,4BAA4B;YACvC,IAAI,EAAE;gBACJ,UAAU;aACX;YACD,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAG,CACP,QAAgB,EAChB,UAA4C,EAAE;QAE9C,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,MAAc,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;YAC5D,QAAQ;YACR,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM;YACtC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;SAC3B,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,SAAuB,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CACd,QAAgB,EAChB,UAA4C,EAAE;QAE9C,6EAA6E;QAC7E,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,MAAc,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC;YACnE,QAAQ;YACR,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,MAAM;YACtC,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;SAC3B,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,QAAgB;QAC7B,2EAA2E;QAC3E,MAAM,MAAM,GAAG,MAAO,IAAI,CAAC,MAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjF,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Event Types
3
+ */
4
+ export interface Event {
5
+ id: string;
6
+ timestamp: Date;
7
+ type: string;
8
+ subjectId: string;
9
+ subjectType: string;
10
+ data: Record<string, unknown>;
11
+ metadata?: Record<string, unknown>;
12
+ source: string;
13
+ correlationId?: string;
14
+ userId: string;
15
+ }
16
+ export interface EventFilter {
17
+ subjectId?: string;
18
+ subjectType?: string;
19
+ eventTypes?: string[];
20
+ limit?: number;
21
+ after?: Date;
22
+ before?: Date;
23
+ }
24
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,IAAI,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,MAAM,CAAC,EAAE,IAAI,CAAC;CACf"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Event Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Relation Types
3
+ */
4
+ export type RelationType = 'assigned_to' | 'mentions' | 'links_to' | 'parent_of' | 'relates_to' | 'tagged_with' | 'created_by' | 'attended_by' | 'depends_on' | 'blocks';
5
+ export interface Relation {
6
+ id: string;
7
+ userId: string;
8
+ sourceEntityId: string;
9
+ targetEntityId: string;
10
+ type: RelationType | string;
11
+ createdAt: Date;
12
+ }
13
+ export interface NewRelation {
14
+ id?: string;
15
+ sourceEntityId: string;
16
+ targetEntityId: string;
17
+ type: RelationType | string;
18
+ metadata?: Record<string, unknown>;
19
+ }
20
+ export interface RelationFilter {
21
+ entityId: string;
22
+ type?: RelationType | string;
23
+ direction?: 'source' | 'target' | 'both';
24
+ limit?: number;
25
+ }
26
+ //# sourceMappingURL=relations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/types/relations.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,YAAY,GACpB,aAAa,GACb,UAAU,GACV,UAAU,GACV,WAAW,GACX,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,QAAQ,CAAC;AAEb,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC;IAC5B,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAC7B,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Relation Types
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=relations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relations.js","sourceRoot":"","sources":["../../src/types/relations.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@synap-core/sdk",
3
+ "version": "0.1.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "High-level SDK for Synap - Event-sourced personal data platform",
8
+ "type": "module",
9
+ "main": "./dist/index.js",
10
+ "module": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "require": "./dist/index.cjs"
17
+ }
18
+ },
19
+ "keywords": [
20
+ "synap",
21
+ "sdk",
22
+ "event-sourcing",
23
+ "personal-data",
24
+ "knowledge-graph"
25
+ ],
26
+ "author": "Synap Team",
27
+ "license": "AGPL-3.0",
28
+ "dependencies": {
29
+ "@synap-core/client": "^0.1.0",
30
+ "@synap-core/types": "^0.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.10.0",
34
+ "typescript": "^5.3.3"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md"
39
+ ],
40
+ "repository": {
41
+ "type": "git",
42
+ "url": "https://github.com/synap-core/synap-backend",
43
+ "directory": "packages/sdk"
44
+ },
45
+ "homepage": "https://github.com/synap-core/synap-backend#readme",
46
+ "scripts": {
47
+ "build": "tsc -p tsconfig.json",
48
+ "dev": "tsc -p tsconfig.json --watch",
49
+ "clean": "rm -rf dist",
50
+ "typecheck": "tsc --noEmit"
51
+ }
52
+ }