holosphere 2.0.0-alpha21 → 2.0.0-alpha23
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 +1 -2
- package/dist/cjs/holosphere.cjs +1 -1
- package/dist/esm/holosphere.js +61 -58
- package/dist/{index-B6-8KAQm.js → index-BEkCLOwI.js} +2 -2
- package/dist/{index-B6-8KAQm.js.map → index-BEkCLOwI.js.map} +1 -1
- package/dist/{index-D2WstuZJ.js → index-BEvX6DxG.js} +2 -2
- package/dist/{index-D2WstuZJ.js.map → index-BEvX6DxG.js.map} +1 -1
- package/dist/{index--QsHG_gD.cjs → index-BGTOiJ2Y.cjs} +2 -2
- package/dist/{index--QsHG_gD.cjs.map → index-BGTOiJ2Y.cjs.map} +1 -1
- package/dist/{index-COpLk9gL.cjs → index-BH1woZXL.cjs} +2 -2
- package/dist/{index-COpLk9gL.cjs.map → index-BH1woZXL.cjs.map} +1 -1
- package/dist/{index-BHptWysv.js → index-Cvxov2jv.js} +2970 -7753
- package/dist/index-Cvxov2jv.js.map +1 -0
- package/dist/index-vTKI_BAX.cjs +29 -0
- package/dist/index-vTKI_BAX.cjs.map +1 -0
- package/dist/{indexeddb-storage-wKG4mICM.cjs → indexeddb-storage-BmnCNnSg.cjs} +2 -2
- package/dist/{indexeddb-storage-wKG4mICM.cjs.map → indexeddb-storage-BmnCNnSg.cjs.map} +1 -1
- package/dist/{indexeddb-storage-kQ53UHEE.js → indexeddb-storage-MIFisaPy.js} +2 -2
- package/dist/{indexeddb-storage-kQ53UHEE.js.map → indexeddb-storage-MIFisaPy.js.map} +1 -1
- package/dist/{memory-storage-CGC8xM2G.cjs → memory-storage-BJjK3F4r.cjs} +2 -2
- package/dist/{memory-storage-CGC8xM2G.cjs.map → memory-storage-BJjK3F4r.cjs.map} +1 -1
- package/dist/{memory-storage-DnXCSbBl.js → memory-storage-DhHXdKQ-.js} +2 -2
- package/dist/{memory-storage-DnXCSbBl.js.map → memory-storage-DhHXdKQ-.js.map} +1 -1
- package/examples/demo.html +2 -29
- package/package.json +3 -8
- package/src/content/social-protocols.js +3 -59
- package/src/core/holosphere.js +16 -554
- package/src/crypto/nostr-utils.js +98 -1
- package/src/crypto/secp256k1.js +4 -393
- package/src/federation/discovery.js +7 -75
- package/src/federation/handshake.js +69 -202
- package/src/federation/hologram.js +222 -298
- package/src/federation/index.js +2 -9
- package/src/federation/registry.js +67 -1257
- package/src/federation/request-card.js +21 -35
- package/src/hierarchical/upcast.js +4 -9
- package/src/index.js +145 -296
- package/src/lib/federation-methods.js +370 -909
- package/src/storage/global-tables.js +1 -1
- package/src/storage/nostr-wrapper.js +9 -5
- package/src/subscriptions/manager.js +1 -1
- package/types/index.d.ts +145 -37
- package/bin/holosphere-activitypub.js +0 -158
- package/dist/2019-BzVkRcax.js +0 -6680
- package/dist/2019-BzVkRcax.js.map +0 -1
- package/dist/2019-C1hPR_Os.cjs +0 -8
- package/dist/2019-C1hPR_Os.cjs.map +0 -1
- package/dist/browser-BcmACE3G.js +0 -3058
- package/dist/browser-BcmACE3G.js.map +0 -1
- package/dist/browser-DaqYUTcG.cjs +0 -2
- package/dist/browser-DaqYUTcG.cjs.map +0 -1
- package/dist/index-BHptWysv.js.map +0 -1
- package/dist/index-CDlhzxT2.cjs +0 -29
- package/dist/index-CDlhzxT2.cjs.map +0 -1
- package/src/federation/capabilities.js +0 -46
- package/src/storage/backend-factory.js +0 -130
- package/src/storage/backend-interface.js +0 -161
- package/src/storage/backends/activitypub/server.js +0 -675
- package/src/storage/backends/activitypub-backend.js +0 -295
- package/src/storage/backends/gundb-backend.js +0 -875
- package/src/storage/backends/nostr-backend.js +0 -251
- package/src/storage/gun-async.js +0 -341
- package/src/storage/gun-auth.js +0 -373
- package/src/storage/gun-federation.js +0 -785
- package/src/storage/gun-references.js +0 -209
- package/src/storage/gun-schema.js +0 -306
- package/src/storage/gun-wrapper.js +0 -642
- package/src/storage/migration.js +0 -351
- package/src/storage/unified-storage.js +0 -161
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module storage/global-tables
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { write, read, readAll, update, deleteData, deleteAll, subscribe } from './
|
|
11
|
+
import { write, read, readAll, update, deleteData, deleteAll, subscribe } from './nostr-wrapper.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Write data to global table
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Nostr Storage Wrapper.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* High-level CRUD API for Nostr-based distributed P2P storage.
|
|
5
5
|
* Handles path construction and CRUD operations using Nostr relays
|
|
6
6
|
* for distributed P2P storage.
|
|
7
7
|
*
|
|
@@ -62,6 +62,7 @@ export async function write(client, path, data, options = {}) {
|
|
|
62
62
|
const putOptions = {
|
|
63
63
|
...(options.signingKey && { signingKey: options.signingKey }),
|
|
64
64
|
...(options.waitForRelays && { waitForRelays: options.waitForRelays }),
|
|
65
|
+
...(options.lensKey && { lensKey: options.lensKey }),
|
|
65
66
|
};
|
|
66
67
|
const result = await nostrPut(client, path, data, putOptions);
|
|
67
68
|
// Check if at least one relay accepted the event
|
|
@@ -126,9 +127,9 @@ export async function readAll(client, path, options = {}) {
|
|
|
126
127
|
* @param {Object} updates - Fields to update
|
|
127
128
|
* @returns {Promise<boolean>} Success indicator
|
|
128
129
|
*/
|
|
129
|
-
export async function update(client, path, updates) {
|
|
130
|
+
export async function update(client, path, updates, options = {}) {
|
|
130
131
|
try {
|
|
131
|
-
const existing = await nostrGet(client, path);
|
|
132
|
+
const existing = await nostrGet(client, path, 30000, options);
|
|
132
133
|
|
|
133
134
|
if (!existing || !existing.id || existing._deleted) {
|
|
134
135
|
return false; // Not found or deleted
|
|
@@ -141,8 +142,11 @@ export async function update(client, path, updates) {
|
|
|
141
142
|
if (!merged._meta) merged._meta = {};
|
|
142
143
|
merged._meta.timestamp = Date.now();
|
|
143
144
|
|
|
144
|
-
// Write merged data
|
|
145
|
-
const
|
|
145
|
+
// Write merged data (pass lensKey for re-encryption)
|
|
146
|
+
const putOptions = {
|
|
147
|
+
...(options.lensKey && { lensKey: options.lensKey }),
|
|
148
|
+
};
|
|
149
|
+
const result = await nostrPut(client, path, merged, putOptions);
|
|
146
150
|
// If no relays (testing mode), consider it successful if event was created
|
|
147
151
|
const success = result.results.length === 0 ? true : result.results.some(r => r.status === 'fulfilled');
|
|
148
152
|
return success;
|
package/types/index.d.ts
CHANGED
|
@@ -1,56 +1,91 @@
|
|
|
1
1
|
// Type declarations for holosphere
|
|
2
|
-
// This file tells TypeScript to skip type checking the bundled JS files
|
|
3
2
|
|
|
4
3
|
declare module 'holosphere' {
|
|
5
4
|
export class HoloSphere {
|
|
6
5
|
constructor(config?: any);
|
|
7
6
|
init(): Promise<void>;
|
|
7
|
+
ready(): Promise<void>;
|
|
8
8
|
|
|
9
9
|
// Core CRUD operations
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
write(holonId: string, lens: string, data: any, options?: any): Promise<boolean>;
|
|
11
|
+
read(holonId: string, lens: string, key?: string, options?: any): Promise<any>;
|
|
12
|
+
update(holonId: string, lens: string, dataId: string, updates: any, options?: any): Promise<boolean>;
|
|
13
|
+
delete(holonId: string, lens: string, key?: string, options?: any): Promise<boolean>;
|
|
14
|
+
deleteAll(holonId: string, lens: string, options?: any): Promise<boolean>;
|
|
15
|
+
|
|
16
|
+
// CRUD aliases (same as above)
|
|
17
|
+
put(holonId: string, lens: string, data: any, options?: any): Promise<boolean>;
|
|
18
|
+
get(holonId: string, lens: string, key?: string, options?: any): Promise<any>;
|
|
19
|
+
getAll(holonId: string, lens: string, options?: any): Promise<any[]>;
|
|
20
|
+
remove(holonId: string, lens: string, key?: string, options?: any): Promise<boolean>;
|
|
16
21
|
|
|
17
22
|
// Subscription
|
|
18
|
-
subscribe(holonId: string, lens: string, callback: (data: any, key: string) => void):
|
|
23
|
+
subscribe(holonId: string, lens: string, callback: (data: any, key: string) => void, options?: any): { unsubscribe: () => void };
|
|
19
24
|
|
|
20
25
|
// Profile operations
|
|
21
26
|
getHolonProfile(holonId: string): Promise<any>;
|
|
22
27
|
setHolonProfile(holonId: string, profile: any): Promise<void>;
|
|
23
28
|
|
|
24
29
|
// Federation operations
|
|
25
|
-
federate(
|
|
26
|
-
|
|
30
|
+
federate(source: string, target: string, lensName: string, options?: any): Promise<any>;
|
|
31
|
+
unfederate(source: string, target: string, lensName: string): Promise<boolean>;
|
|
32
|
+
federateHolon(holonId: string, targetHolonId: string, options?: any): Promise<boolean>;
|
|
33
|
+
unfederateHolon(holonId: string, targetHolonId: string): Promise<boolean>;
|
|
27
34
|
getFederation(holonId: string): Promise<any>;
|
|
35
|
+
addFederatedHolosphere(pubKey: string, options?: any): Promise<boolean>;
|
|
36
|
+
removeFederatedHolosphere(pubKey: string): Promise<boolean>;
|
|
37
|
+
getFederatedHolospheres(): Promise<string[]>;
|
|
38
|
+
getFederationRegistry(): Promise<any>;
|
|
39
|
+
isFederated(pubKey: string): Promise<boolean>;
|
|
40
|
+
|
|
41
|
+
// Share protocol (Hologram DM as Federation)
|
|
42
|
+
share(target: string, lens: string, item?: string | null, opts?: {
|
|
43
|
+
keys?: Array<{ path: string; key: string }>;
|
|
44
|
+
msg?: string;
|
|
45
|
+
sourceHolon?: string;
|
|
46
|
+
}): Promise<{ success: boolean; error?: string }>;
|
|
47
|
+
accept(sharePayload: SharePayload, senderPubKey: string, opts?: {
|
|
48
|
+
holonId?: string;
|
|
49
|
+
msg?: string;
|
|
50
|
+
}): Promise<{ success: boolean; error?: string }>;
|
|
51
|
+
reject(sharePayload: SharePayload, senderPubKey: string, opts?: {
|
|
52
|
+
msg?: string;
|
|
53
|
+
}): Promise<{ success: boolean; error?: string }>;
|
|
54
|
+
|
|
55
|
+
// Propagation
|
|
28
56
|
propagate(holonId: string, lens: string, key: string, value: any): Promise<void>;
|
|
29
|
-
propagateData(
|
|
57
|
+
propagateData(data: any, sourceHolon: string, targetHolon: string, lensName: string, options?: any): Promise<any>;
|
|
30
58
|
|
|
31
59
|
// Global operations
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
60
|
+
writeGlobal(table: string, data: any): Promise<void>;
|
|
61
|
+
readGlobal(table: string, key?: string): Promise<any>;
|
|
62
|
+
updateGlobal(table: string, key: string, updates: any): Promise<void>;
|
|
63
|
+
deleteGlobal(table: string, key: string): Promise<void>;
|
|
64
|
+
getAllGlobal(table: string): Promise<Record<string, any>>;
|
|
65
|
+
|
|
66
|
+
// Encryption
|
|
67
|
+
handleReceivedKeyShare(keyShare: any, senderPubKey: string): boolean;
|
|
68
|
+
hasLensKey(holonId: string, lensName: string): boolean;
|
|
69
|
+
isOwnLensKey(holonId: string, lensName: string): boolean;
|
|
70
|
+
getEncryptionStats(): { ownKeyCount: number; receivedKeyCount: number; totalPartnerGrants: number };
|
|
71
|
+
|
|
72
|
+
// Configuration and internal properties
|
|
73
|
+
config?: { appName: string; [key: string]: any };
|
|
74
|
+
client?: { publicKey: string; privateKey?: Uint8Array; [key: string]: any };
|
|
75
|
+
keyStore?: any;
|
|
39
76
|
}
|
|
40
77
|
|
|
41
|
-
export class
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
78
|
+
export class LensKeyStore {
|
|
79
|
+
getOrCreateKey(lensPath: string, privateKey: string, publicKey: string): { key: Uint8Array; isNew: boolean; wrappedForSelf?: string };
|
|
80
|
+
getKey(lensPath: string): Uint8Array | null;
|
|
81
|
+
hasKey(lensPath: string): boolean;
|
|
82
|
+
isOwnKey(lensPath: string): boolean;
|
|
83
|
+
storeOwnKey(lensPath: string, key: Uint8Array, wrappedForSelf: string): void;
|
|
84
|
+
receiveKey(lensPath: string, wrappedKey: string, recipientPrivKey: string, senderPubKey: string): Uint8Array;
|
|
85
|
+
getStats(): { ownKeyCount: number; receivedKeyCount: number; totalPartnerGrants: number };
|
|
49
86
|
}
|
|
50
87
|
|
|
51
|
-
export
|
|
52
|
-
export class MemoryStorage extends PersistentStorage {}
|
|
53
|
-
export class FileSystemStorage extends PersistentStorage {}
|
|
88
|
+
export function buildLensPath(appName: string, holonId: string, lensName: string): string;
|
|
54
89
|
|
|
55
90
|
export class ChainManager {
|
|
56
91
|
constructor(config?: any);
|
|
@@ -79,27 +114,100 @@ declare module 'holosphere' {
|
|
|
79
114
|
export const ContractABIs: any;
|
|
80
115
|
export const NETWORKS: any;
|
|
81
116
|
|
|
117
|
+
export interface SharePayload {
|
|
118
|
+
id: string;
|
|
119
|
+
type: 'share';
|
|
120
|
+
source: string;
|
|
121
|
+
lens: string;
|
|
122
|
+
item: string | null;
|
|
123
|
+
author: string;
|
|
124
|
+
keys?: Array<{ path: string; key: string }>;
|
|
125
|
+
msg?: string;
|
|
126
|
+
timestamp?: number;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface ShareAckPayload {
|
|
130
|
+
id: string;
|
|
131
|
+
type: 'share_ack';
|
|
132
|
+
source: string;
|
|
133
|
+
lens: string;
|
|
134
|
+
item: string | null;
|
|
135
|
+
author: string;
|
|
136
|
+
status: 'accepted' | 'rejected';
|
|
137
|
+
msg?: string;
|
|
138
|
+
timestamp?: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
82
141
|
export class AuthorizationError extends Error {}
|
|
83
142
|
export class ValidationError extends Error {}
|
|
84
143
|
|
|
85
144
|
export const crypto: any;
|
|
86
145
|
export const federation: any;
|
|
87
146
|
export const handshake: {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
147
|
+
// Request/Response lifecycle
|
|
148
|
+
initiateFederationHandshake(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; requestId?: string; error?: string }>;
|
|
149
|
+
acceptFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; requestId?: string; receivedHolograms?: any; error?: string }>;
|
|
150
|
+
rejectFederationRequest(holosphere: HoloSphere, privateKey: string, params: any): Promise<{ success: boolean; error?: string }>;
|
|
151
|
+
processFederationResponse(holosphere: HoloSphere, response: any, responderPubKey: string, options?: any): Promise<{ success: boolean; receivedHolograms?: any; error?: string }>;
|
|
152
|
+
|
|
153
|
+
// DM operations
|
|
154
|
+
subscribeToFederationDMs(client: any, privateKey: string, publicKey: string, handlers: any, options?: any): () => void;
|
|
155
|
+
createFederationResponse(params: any): any;
|
|
156
|
+
sendFederationResponse(client: any, privateKey: string, recipientPubKey: string, response: any): Promise<boolean>;
|
|
157
|
+
|
|
158
|
+
// Validation helpers
|
|
159
|
+
isFederationRequest(payload: any): boolean;
|
|
160
|
+
isFederationResponse(payload: any): boolean;
|
|
161
|
+
normalizeLensConfig(lensConfig: any): any;
|
|
162
|
+
};
|
|
163
|
+
export const registry: {
|
|
164
|
+
addFederatedPartner(client: any, appname: string, partnerPubKey: string, options?: any): Promise<boolean>;
|
|
165
|
+
removeFederatedPartner(client: any, appname: string, partnerPubKey: string): Promise<boolean>;
|
|
166
|
+
getFederatedAuthors(client: any, appname: string): Promise<string[]>;
|
|
167
|
+
getFederationRegistry(client: any, appname: string, options?: any): Promise<any>;
|
|
168
|
+
isFederated(client: any, appname: string, pubKey: string): Promise<boolean>;
|
|
169
|
+
getFederatedPartner(client: any, appname: string, partnerPubKey: string): Promise<any>;
|
|
170
|
+
addCapabilityWriter(client: any, appname: string, writerPubKey: string): Promise<boolean>;
|
|
171
|
+
getCapabilityWriters(client: any, appname: string): Promise<string[]>;
|
|
172
|
+
removeCapabilityWriter(client: any, appname: string, writerPubKey: string): Promise<boolean>;
|
|
173
|
+
};
|
|
174
|
+
export const nostrUtils: {
|
|
175
|
+
// npub utilities
|
|
176
|
+
parseNpubOrHex(input: string): { valid: boolean; hexPubKey?: string; error?: string };
|
|
177
|
+
hexToNpub(hexPubKey: string): string;
|
|
178
|
+
npubToHex(npub: string): string | null;
|
|
179
|
+
isValidNpub(str: string): boolean;
|
|
180
|
+
shortenNpub(npub: string): string;
|
|
181
|
+
shortenPubKey(pubKey: string): string;
|
|
182
|
+
// nsec utilities
|
|
183
|
+
parseNsecOrHex(input: string): { valid: boolean; hexPrivKey?: string; error?: string };
|
|
184
|
+
hexToNsec(hexPrivKey: string): string;
|
|
185
|
+
nsecToHex(nsec: string): string | null;
|
|
186
|
+
isValidNsec(str: string): boolean;
|
|
187
|
+
// Key operations
|
|
188
|
+
generatePrivateKey(): string;
|
|
189
|
+
getPublicKey(privateKey: string): string;
|
|
190
|
+
isValidHexPubKey(str: string): boolean;
|
|
191
|
+
// Byte conversion
|
|
192
|
+
hexToBytes(hex: string): Uint8Array;
|
|
193
|
+
bytesToHex(bytes: Uint8Array): string;
|
|
194
|
+
[key: string]: any;
|
|
92
195
|
};
|
|
93
|
-
export const hierarchical: any;
|
|
94
|
-
export const nostrUtils: any;
|
|
95
196
|
export const schema: any;
|
|
96
197
|
export const social: any;
|
|
97
198
|
export const spatial: any;
|
|
98
199
|
export const storage: any;
|
|
99
|
-
export const subscriptions:
|
|
200
|
+
export const subscriptions: {
|
|
201
|
+
createSubscription(client: any, path: string, callback: (data: any, key?: string) => void, options?: any): Promise<{ path: string; unsubscribe: () => void }>;
|
|
202
|
+
};
|
|
100
203
|
export const networks: any;
|
|
204
|
+
export const hierarchical: any;
|
|
101
205
|
|
|
102
206
|
export function createHologram(config?: any): any;
|
|
207
|
+
export function createLensHologram(sourceHolon: string, lensName: string, appname: string, options: { author: string }): any;
|
|
208
|
+
export function isLensHologram(data: any): boolean;
|
|
209
|
+
export function sendShare(client: any, privateKey: string, targetPubKey: string, payload: any): Promise<boolean>;
|
|
210
|
+
export function sendAck(client: any, privateKey: string, targetPubKey: string, payload: any): Promise<boolean>;
|
|
103
211
|
export function createAIServices(config?: any): any;
|
|
104
212
|
export function getNetwork(name: string): any;
|
|
105
213
|
export function getNetworksByType(type: string): any[];
|
|
@@ -107,7 +215,7 @@ declare module 'holosphere' {
|
|
|
107
215
|
export function isNetworkSupported(name: string): boolean;
|
|
108
216
|
export function getAddressUrl(network: string, address: string): string;
|
|
109
217
|
export function getTxUrl(network: string, txHash: string): string;
|
|
110
|
-
export function
|
|
218
|
+
export function dismissRequest(client: any, appname: string, requestId: string): Promise<void>;
|
|
111
219
|
|
|
112
220
|
// AI-related exports
|
|
113
221
|
export class Classifier {}
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* HoloSphere ActivityPub Server CLI
|
|
5
|
-
*
|
|
6
|
-
* Starts a self-hosted ActivityPub server for HoloSphere federation.
|
|
7
|
-
*
|
|
8
|
-
* Usage:
|
|
9
|
-
* holosphere-activitypub [options]
|
|
10
|
-
*
|
|
11
|
-
* Options:
|
|
12
|
-
* -p, --port <port> Port to listen on (default: 3000)
|
|
13
|
-
* -d, --domain <domain> Domain name for federation (default: localhost)
|
|
14
|
-
* --data-dir <dir> Data directory for storage
|
|
15
|
-
* --protocol <protocol> Protocol: http or https (default: http)
|
|
16
|
-
* -h, --help Show this help message
|
|
17
|
-
*
|
|
18
|
-
* Environment Variables:
|
|
19
|
-
* HOLOSPHERE_AP_PORT Port to listen on
|
|
20
|
-
* HOLOSPHERE_AP_DOMAIN Domain name
|
|
21
|
-
* HOLOSPHERE_AP_DATADIR Data directory
|
|
22
|
-
* HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { ActivityPubServer } from '../src/storage/backends/activitypub/server.js';
|
|
26
|
-
|
|
27
|
-
function parseArgs(args) {
|
|
28
|
-
const config = {
|
|
29
|
-
port: parseInt(process.env.HOLOSPHERE_AP_PORT) || 3000,
|
|
30
|
-
domain: process.env.HOLOSPHERE_AP_DOMAIN || 'localhost',
|
|
31
|
-
dataDir: process.env.HOLOSPHERE_AP_DATADIR,
|
|
32
|
-
protocol: process.env.HOLOSPHERE_AP_PROTOCOL || 'http',
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < args.length; i++) {
|
|
36
|
-
const arg = args[i];
|
|
37
|
-
const next = args[i + 1];
|
|
38
|
-
|
|
39
|
-
switch (arg) {
|
|
40
|
-
case '-p':
|
|
41
|
-
case '--port':
|
|
42
|
-
config.port = parseInt(next);
|
|
43
|
-
i++;
|
|
44
|
-
break;
|
|
45
|
-
case '-d':
|
|
46
|
-
case '--domain':
|
|
47
|
-
config.domain = next;
|
|
48
|
-
i++;
|
|
49
|
-
break;
|
|
50
|
-
case '--data-dir':
|
|
51
|
-
config.dataDir = next;
|
|
52
|
-
i++;
|
|
53
|
-
break;
|
|
54
|
-
case '--protocol':
|
|
55
|
-
config.protocol = next;
|
|
56
|
-
i++;
|
|
57
|
-
break;
|
|
58
|
-
case '-h':
|
|
59
|
-
case '--help':
|
|
60
|
-
showHelp();
|
|
61
|
-
process.exit(0);
|
|
62
|
-
default:
|
|
63
|
-
if (arg.startsWith('-')) {
|
|
64
|
-
console.error(`Unknown option: ${arg}`);
|
|
65
|
-
showHelp();
|
|
66
|
-
process.exit(1);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return config;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function showHelp() {
|
|
75
|
-
console.log(`
|
|
76
|
-
HoloSphere ActivityPub Server
|
|
77
|
-
|
|
78
|
-
Starts a self-hosted ActivityPub server for HoloSphere federation.
|
|
79
|
-
This server can federate with Mastodon, Pleroma, and other ActivityPub servers.
|
|
80
|
-
|
|
81
|
-
Usage:
|
|
82
|
-
holosphere-activitypub [options]
|
|
83
|
-
|
|
84
|
-
Options:
|
|
85
|
-
-p, --port <port> Port to listen on (default: 3000)
|
|
86
|
-
-d, --domain <domain> Domain name for federation (default: localhost)
|
|
87
|
-
--data-dir <dir> Data directory for persistent storage
|
|
88
|
-
--protocol <protocol> Protocol: http or https (default: http)
|
|
89
|
-
-h, --help Show this help message
|
|
90
|
-
|
|
91
|
-
Environment Variables:
|
|
92
|
-
HOLOSPHERE_AP_PORT Port to listen on
|
|
93
|
-
HOLOSPHERE_AP_DOMAIN Domain name
|
|
94
|
-
HOLOSPHERE_AP_DATADIR Data directory
|
|
95
|
-
HOLOSPHERE_AP_PROTOCOL Protocol (http/https)
|
|
96
|
-
|
|
97
|
-
Examples:
|
|
98
|
-
# Start server on default port
|
|
99
|
-
holosphere-activitypub
|
|
100
|
-
|
|
101
|
-
# Start server on port 8080 with custom domain
|
|
102
|
-
holosphere-activitypub -p 8080 -d myholosphere.example.com
|
|
103
|
-
|
|
104
|
-
# Start with persistent data directory
|
|
105
|
-
holosphere-activitypub --data-dir ./data --domain myserver.local
|
|
106
|
-
|
|
107
|
-
Federation Notes:
|
|
108
|
-
For federation with other ActivityPub servers (Mastodon, etc.):
|
|
109
|
-
1. Your server must be accessible via the domain you specify
|
|
110
|
-
2. HTTPS is recommended for production federation
|
|
111
|
-
3. Set up proper DNS records pointing to your server
|
|
112
|
-
4. WebFinger discovery is available at /.well-known/webfinger
|
|
113
|
-
`);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function main() {
|
|
117
|
-
const args = process.argv.slice(2);
|
|
118
|
-
const config = parseArgs(args);
|
|
119
|
-
|
|
120
|
-
console.log('\n========================================');
|
|
121
|
-
console.log(' HoloSphere ActivityPub Server');
|
|
122
|
-
console.log('========================================');
|
|
123
|
-
console.log(` Port: ${config.port}`);
|
|
124
|
-
console.log(` Domain: ${config.domain}`);
|
|
125
|
-
console.log(` Protocol: ${config.protocol}`);
|
|
126
|
-
console.log(` Data Dir: ${config.dataDir || '(default)'}`);
|
|
127
|
-
console.log('========================================\n');
|
|
128
|
-
|
|
129
|
-
const server = new ActivityPubServer(config);
|
|
130
|
-
|
|
131
|
-
// Handle shutdown gracefully
|
|
132
|
-
process.on('SIGINT', () => {
|
|
133
|
-
console.log('\nShutting down...');
|
|
134
|
-
server.stop();
|
|
135
|
-
process.exit(0);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
process.on('SIGTERM', () => {
|
|
139
|
-
console.log('\nShutting down...');
|
|
140
|
-
server.stop();
|
|
141
|
-
process.exit(0);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
await server.start();
|
|
146
|
-
console.log('\nServer endpoints:');
|
|
147
|
-
console.log(` WebFinger: ${config.protocol}://${config.domain}:${config.port}/.well-known/webfinger`);
|
|
148
|
-
console.log(` Actors: ${config.protocol}://${config.domain}:${config.port}/actor/{name}`);
|
|
149
|
-
console.log(` API: ${config.protocol}://${config.domain}:${config.port}/api/data`);
|
|
150
|
-
console.log(` Health: ${config.protocol}://${config.domain}:${config.port}/health`);
|
|
151
|
-
console.log('\nPress Ctrl+C to stop the server\n');
|
|
152
|
-
} catch (error) {
|
|
153
|
-
console.error('Failed to start server:', error);
|
|
154
|
-
process.exit(1);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
main();
|