@ibgib/web-gib 0.0.52 → 0.0.55
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/CHANGELOG.md +7 -0
- package/dist/AUTO-GENERATED-version.d.mts +1 -1
- package/dist/AUTO-GENERATED-version.mjs +1 -1
- package/dist/api/commands/chat/hello-world.mjs.map +1 -1
- package/dist/api/commands/command-constants.d.mts +4 -4
- package/dist/api/commands/command-constants.d.mts.map +1 -1
- package/dist/api/commands/command-service-v1.d.mts.map +1 -1
- package/dist/api/commands/command-service-v1.mjs.map +1 -1
- package/dist/api/commands/ibgib/get-ibgibs.d.mts.map +1 -1
- package/dist/api/commands/ibgib/get-ibgibs.mjs.map +1 -1
- package/dist/api/ibgib-api-bridge.d.mts +81 -0
- package/dist/api/ibgib-api-bridge.d.mts.map +1 -0
- package/dist/api/ibgib-api-bridge.mjs +259 -0
- package/dist/api/ibgib-api-bridge.mjs.map +1 -0
- package/dist/app-bootstrap/init-orchestration.d.mts +1 -1
- package/dist/app-bootstrap/init-orchestration.d.mts.map +1 -1
- package/dist/app-bootstrap/init-orchestration.mjs +17 -3
- package/dist/app-bootstrap/init-orchestration.mjs.map +1 -1
- package/dist/assets/fullscreen-dialog.html +18 -0
- package/dist/assumptions.respec.mjs.map +1 -1
- package/dist/common/settings/settings-constants.d.mts.map +1 -1
- package/dist/helpers.d.mts.map +1 -1
- package/dist/helpers.mjs.map +1 -1
- package/dist/helpers.web.d.mts.map +1 -1
- package/dist/helpers.web.mjs.map +1 -1
- package/dist/helpers.web.respec.mjs.map +1 -1
- package/dist/identity/keystone-sync-service.d.mts +37 -0
- package/dist/identity/keystone-sync-service.d.mts.map +1 -0
- package/dist/identity/keystone-sync-service.mjs +211 -0
- package/dist/identity/keystone-sync-service.mjs.map +1 -0
- package/dist/identity/sso/sso-custodian-service.d.mts.map +1 -1
- package/dist/identity/sso/sso-custodian-service.mjs.map +1 -1
- package/dist/identity/sso/sso-custodian-service.respec.mjs.map +1 -1
- package/dist/index.d.mts +17 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +21 -26
- package/dist/index.mjs.map +1 -1
- package/dist/storage/storage-helpers.web.mjs.map +1 -1
- package/dist/ui/component/common-component-styles.css +270 -0
- package/dist/ui/component/ibgib-component-service.d.mts.map +1 -1
- package/dist/ui/component/ibgib-dynamic-component-bases.d.mts.map +1 -1
- package/dist/ui/component/ibgib-dynamic-component-bases.mjs.map +1 -1
- package/dist/ui/component/identity/add-device/add-device.css +133 -0
- package/dist/ui/component/identity/add-device/add-device.d.mts +49 -0
- package/dist/ui/component/identity/add-device/add-device.d.mts.map +1 -0
- package/dist/ui/component/identity/add-device/add-device.html +52 -0
- package/dist/ui/component/identity/add-device/add-device.mjs +321 -0
- package/dist/ui/component/identity/add-device/add-device.mjs.map +1 -0
- package/dist/ui/component/identity/identity-header/identity-header.css +317 -0
- package/dist/ui/component/identity/identity-header/identity-header.d.mts +85 -0
- package/dist/ui/component/identity/identity-header/identity-header.d.mts.map +1 -0
- package/dist/ui/component/identity/identity-header/identity-header.html +72 -0
- package/dist/ui/component/identity/identity-header/identity-header.mjs +546 -0
- package/dist/ui/component/identity/identity-header/identity-header.mjs.map +1 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.css +178 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.d.mts +76 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.d.mts.map +1 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.html +19 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.mjs +591 -0
- package/dist/ui/component/identity/identity-manager/identity-manager.mjs.map +1 -0
- package/dist/ui/component/identity/index.d.mts +17 -0
- package/dist/ui/component/identity/index.d.mts.map +1 -0
- package/dist/ui/component/identity/index.mjs +34 -0
- package/dist/ui/component/identity/index.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.css +97 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts +58 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.html +51 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs +410 -0
- package/dist/ui/component/identity/keystone-creator/keystone-creator.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.css +621 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.d.mts +98 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.html +154 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.mjs +1377 -0
- package/dist/ui/component/identity/keystone-details/keystone-details.mjs.map +1 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.css +46 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.d.mts +64 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.d.mts.map +1 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.html +15 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.mjs +300 -0
- package/dist/ui/component/identity/keystone-scrubber/keystone-scrubber.mjs.map +1 -0
- package/dist/ui/component/identity/remove-device/remove-device.css +118 -0
- package/dist/ui/component/identity/remove-device/remove-device.d.mts +50 -0
- package/dist/ui/component/identity/remove-device/remove-device.d.mts.map +1 -0
- package/dist/ui/component/identity/remove-device/remove-device.html +31 -0
- package/dist/ui/component/identity/remove-device/remove-device.mjs +188 -0
- package/dist/ui/component/identity/remove-device/remove-device.mjs.map +1 -0
- package/dist/ui/ui-constants.d.mts +1 -0
- package/dist/ui/ui-constants.d.mts.map +1 -1
- package/dist/ui/ui-constants.mjs +1 -0
- package/dist/ui/ui-constants.mjs.map +1 -1
- package/dist/ui/ui-types.d.mts +7 -0
- package/dist/ui/ui-types.d.mts.map +1 -1
- package/dist/witness/agent/agent-constants.d.mts.map +1 -1
- package/dist/witness/agent/agent-helpers.mjs.map +1 -1
- package/dist/witness/agent/agent-one-file.d.mts.map +1 -1
- package/dist/witness/agent/agent-one-file.mjs.map +1 -1
- package/dist/witness/agent/agents-service-v1.d.mts.map +1 -1
- package/dist/witness/agent/agents-service-v1.mjs.map +1 -1
- package/dist/witness/agent/gemini/agent-witness-gemini-v1.d.mts.map +1 -1
- package/dist/witness/agent/gemini/gemini-agent-factory.d.mts.map +1 -1
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.d.mts.map +1 -1
- package/dist/witness/live-proxy-ibgib/live-proxy-ibgib-one-file.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace-helper.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts +4 -0
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.d.mts.map +1 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs +40 -1
- package/dist/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mjs.map +1 -1
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-types.d.mts.map +1 -1
- package/dist/witness/space/web-filesystem-space/web-filesystem-space-v1.d.mts.map +1 -1
- package/package.json +2 -2
- package/src/AUTO-GENERATED-version.mts +1 -1
- package/src/api/ibgib-api-bridge.mts +292 -0
- package/src/app-bootstrap/init-orchestration.mts +17 -6
- package/src/custom.d.ts +11 -0
- package/src/identity/keystone-sync-service.mts +257 -0
- package/src/index.mts +24 -25
- package/src/ui/component/README.md +82 -5
- package/src/ui/component/common-component-styles.css +270 -0
- package/src/ui/component/identity/add-device/add-device.css +133 -0
- package/src/ui/component/identity/add-device/add-device.html +52 -0
- package/src/ui/component/identity/add-device/add-device.mts +397 -0
- package/src/ui/component/identity/identity-header/IMPLEMENTATION.md +45 -0
- package/src/ui/component/identity/identity-header/identity-header.css +317 -0
- package/src/ui/component/identity/identity-header/identity-header.html +72 -0
- package/src/ui/component/identity/identity-header/identity-header.mts +651 -0
- package/src/ui/component/identity/identity-manager/IMPLEMENTATION.md +100 -0
- package/src/ui/component/identity/identity-manager/identity-manager.css +178 -0
- package/src/ui/component/identity/identity-manager/identity-manager.html +19 -0
- package/src/ui/component/identity/identity-manager/identity-manager.mts +675 -0
- package/src/ui/component/identity/index.mts +36 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.css +97 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.html +51 -0
- package/src/ui/component/identity/keystone-creator/keystone-creator.mts +497 -0
- package/src/ui/component/identity/keystone-details/keystone-details.css +621 -0
- package/src/ui/component/identity/keystone-details/keystone-details.html +154 -0
- package/src/ui/component/identity/keystone-details/keystone-details.mts +1506 -0
- package/src/ui/component/identity/keystone-scrubber/SCRUBBER_IMPLEMENTATION.md +33 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.css +46 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.html +15 -0
- package/src/ui/component/identity/keystone-scrubber/keystone-scrubber.mts +355 -0
- package/src/ui/component/identity/remove-device/remove-device.css +118 -0
- package/src/ui/component/identity/remove-device/remove-device.html +31 -0
- package/src/ui/component/identity/remove-device/remove-device.mts +247 -0
- package/src/ui/ui-constants.mts +1 -0
- package/src/ui/ui-types.mts +8 -0
- package/src/witness/space/metaspace/metaspace-webspace/metaspace-webspace.mts +42 -1
- package/tools/auto-generated-agent-skills/skills/ibgib-dependency-graph/SKILL.md +209 -0
- package/tools/auto-generated-agent-skills/skills/ibgib-implementation-plan/SKILL.md +102 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module api/ibgib-api-bridge
|
|
3
|
+
*
|
|
4
|
+
* Base REST API bridge class for interacting with serve-gib endpoints from browser clients.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
8
|
+
import { IbGib_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
9
|
+
|
|
10
|
+
const logalot = false;
|
|
11
|
+
|
|
12
|
+
export class IbGibApiBridge {
|
|
13
|
+
protected lc: string = `[${IbGibApiBridge.name}]`;
|
|
14
|
+
|
|
15
|
+
protected async parseResponseJson<T = any>(response: Response, url: string): Promise<T> {
|
|
16
|
+
const contentType = response.headers.get('content-type') || '';
|
|
17
|
+
if (!contentType.includes('application/json')) {
|
|
18
|
+
const text = await response.text();
|
|
19
|
+
if (text.trim().toLowerCase().startsWith('<!doctype html') || text.includes('<html')) {
|
|
20
|
+
throw new Error(`API request to '${url}' failed (${response.status} ${response.statusText}): Received HTML fallback instead of JSON. Check API route matching and parameters.`);
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`API request to '${url}' failed (${response.status} ${response.statusText}): Returned non-JSON content type '${contentType}': ${text.slice(0, 150)}`);
|
|
23
|
+
}
|
|
24
|
+
return await response.json();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Posts a single genesis keystone ibgib to the server to create a new domain.
|
|
29
|
+
*/
|
|
30
|
+
public async postGenesisKeystone(keystoneIbGib: IbGib_V1): Promise<{ success: boolean; message?: string; addr?: string }> {
|
|
31
|
+
const lc = `${this.lc}[${this.postGenesisKeystone.name}]`;
|
|
32
|
+
try {
|
|
33
|
+
if (logalot) { console.log(`${lc} starting... (I: eecd082fc4a4381c8857928e8b090826)`); }
|
|
34
|
+
|
|
35
|
+
const url = '/api/keystone/genesis';
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
'Content-Type': 'application/json',
|
|
40
|
+
},
|
|
41
|
+
body: JSON.stringify({ keystoneIbGib }),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const data = await this.parseResponseJson(response, url);
|
|
45
|
+
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
48
|
+
console.error(`${lc} server rejected genesis keystone: ${errorMsg}`);
|
|
49
|
+
return { success: false, message: errorMsg, addr: data.addr };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (logalot) { console.log(`${lc} genesis keystone posted successfully.`); }
|
|
53
|
+
return { success: true, addr: data.addr };
|
|
54
|
+
|
|
55
|
+
} catch (error) {
|
|
56
|
+
const errorMsg = extractErrorMsg(error);
|
|
57
|
+
console.error(`${lc} error: ${errorMsg}`);
|
|
58
|
+
return { success: false, message: errorMsg };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* PUTs an evolved domain keystone and any related keystones to the server.
|
|
64
|
+
*/
|
|
65
|
+
public async putEvolveKeystone({
|
|
66
|
+
domainAddr,
|
|
67
|
+
keystoneIbGib,
|
|
68
|
+
relatedKeystoneIbGibs = [],
|
|
69
|
+
revokeTokens
|
|
70
|
+
}: {
|
|
71
|
+
domainAddr: string;
|
|
72
|
+
keystoneIbGib: IbGib_V1;
|
|
73
|
+
relatedKeystoneIbGibs?: IbGib_V1[];
|
|
74
|
+
revokeTokens?: Record<string, string>;
|
|
75
|
+
}): Promise<{ success: boolean; message?: string }> {
|
|
76
|
+
const lc = `${this.lc}[${this.putEvolveKeystone.name}]`;
|
|
77
|
+
try {
|
|
78
|
+
if (logalot) { console.log(`${lc} posting evolved keystone...`); }
|
|
79
|
+
|
|
80
|
+
const url = `/api/keystone/evolve/${encodeURIComponent(domainAddr)}`;
|
|
81
|
+
const response = await fetch(url, {
|
|
82
|
+
method: 'PUT',
|
|
83
|
+
headers: {
|
|
84
|
+
'Content-Type': 'application/json',
|
|
85
|
+
},
|
|
86
|
+
body: JSON.stringify({
|
|
87
|
+
keystoneIbGib,
|
|
88
|
+
relatedKeystoneIbGibs,
|
|
89
|
+
revokeTokens
|
|
90
|
+
}),
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const data = await this.parseResponseJson(response, url);
|
|
94
|
+
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
97
|
+
console.error(`${lc} server rejected keystone evolution: ${errorMsg}`);
|
|
98
|
+
return { success: false, message: errorMsg };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (logalot) { console.log(`${lc} keystone evolution accepted by server.`); }
|
|
102
|
+
return { success: true };
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
const errorMsg = extractErrorMsg(error);
|
|
106
|
+
console.error(`${lc} fetch error: ${errorMsg}`);
|
|
107
|
+
return { success: false, message: errorMsg };
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Looks up a primary identity keystone on the server by username or email.
|
|
113
|
+
*/
|
|
114
|
+
public async lookupPrimaryKeystone({ identifier }: { identifier: string }): Promise<{ success: boolean; message?: string; tjpAddr?: string; primaryKeystoneIbGib?: IbGib_V1 }> {
|
|
115
|
+
const lc = `${this.lc}[${this.lookupPrimaryKeystone.name}]`;
|
|
116
|
+
try {
|
|
117
|
+
const url = '/api/keystone/lookup';
|
|
118
|
+
const response = await fetch(url, {
|
|
119
|
+
method: 'POST',
|
|
120
|
+
headers: {
|
|
121
|
+
'Content-Type': 'application/json',
|
|
122
|
+
},
|
|
123
|
+
body: JSON.stringify({ identifier }),
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const data = await this.parseResponseJson(response, url);
|
|
127
|
+
|
|
128
|
+
if (!response.ok) {
|
|
129
|
+
const errorMsg = data.message || data.error || 'Identity not found';
|
|
130
|
+
console.error(`${lc} server lookup failed: ${errorMsg}`);
|
|
131
|
+
return { success: false, message: errorMsg };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
tjpAddr: data.tjpAddr,
|
|
137
|
+
primaryKeystoneIbGib: data.primaryKeystoneIbGib
|
|
138
|
+
};
|
|
139
|
+
} catch (error) {
|
|
140
|
+
const errorMsg = extractErrorMsg(error);
|
|
141
|
+
console.error(`${lc} lookup fetch error: ${errorMsg}`);
|
|
142
|
+
return { success: false, message: errorMsg };
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Checks if an email address is available on the server before local genesis.
|
|
148
|
+
*/
|
|
149
|
+
public async checkEmailAvailability({ email }: { email: string }): Promise<{ available: boolean; message?: string }> {
|
|
150
|
+
const lc = `${this.lc}[${this.checkEmailAvailability.name}]`;
|
|
151
|
+
try {
|
|
152
|
+
const url = `/api/keystone/check-email?email=${encodeURIComponent(email)}`;
|
|
153
|
+
const response = await fetch(url, {
|
|
154
|
+
method: 'GET',
|
|
155
|
+
headers: {
|
|
156
|
+
'Content-Type': 'application/json',
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const data = await this.parseResponseJson(response, url);
|
|
161
|
+
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
const errorMsg = data.message || data.error || 'Server check failed';
|
|
164
|
+
console.error(`${lc} email check failed: ${errorMsg}`);
|
|
165
|
+
return { available: false, message: errorMsg };
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
available: data.available ?? true,
|
|
170
|
+
message: data.message
|
|
171
|
+
};
|
|
172
|
+
} catch (error) {
|
|
173
|
+
const errorMsg = extractErrorMsg(error);
|
|
174
|
+
console.error(`${lc} check email error: ${errorMsg}`);
|
|
175
|
+
return { available: true }; // network error fallback
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
public async getKeystoneGraph(domainAddr: string): Promise<{ success: boolean; message?: string; graph?: Record<string, any> }> {
|
|
179
|
+
const lc = `${this.lc}[${this.getKeystoneGraph.name}]`;
|
|
180
|
+
try {
|
|
181
|
+
if (logalot) { console.log(`${lc} fetching keystone graph...`); }
|
|
182
|
+
|
|
183
|
+
const url = `/api/keystone/${encodeURIComponent(domainAddr)}?getLatest=true&getGraph=true`;
|
|
184
|
+
const response = await fetch(url, {
|
|
185
|
+
method: 'GET',
|
|
186
|
+
headers: {
|
|
187
|
+
'Accept': 'application/json',
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const data = await this.parseResponseJson(response, url);
|
|
192
|
+
|
|
193
|
+
if (!response.ok) {
|
|
194
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
195
|
+
console.error(`${lc} server rejected keystone graph get: ${errorMsg}`);
|
|
196
|
+
return { success: false, message: errorMsg };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return { success: true, graph: data.domainGraph };
|
|
200
|
+
|
|
201
|
+
} catch (error) {
|
|
202
|
+
const errorMsg = extractErrorMsg(error);
|
|
203
|
+
console.error(`${lc} fetch error: ${errorMsg}`);
|
|
204
|
+
return { success: false, message: errorMsg };
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* GETs a single ibGib frame from the server's domain space.
|
|
210
|
+
*/
|
|
211
|
+
public async getIbGib(domainAddr: string, ibGibAddr: string, getLatest = false): Promise<{ success: boolean; message?: string; ibGib?: IbGib_V1 }> {
|
|
212
|
+
const lc = `${this.lc}[${this.getIbGib.name}]`;
|
|
213
|
+
try {
|
|
214
|
+
if (logalot) { console.log(`${lc} fetching single ibGib frame...`); }
|
|
215
|
+
|
|
216
|
+
const url = `/api/ibgib/${encodeURIComponent(domainAddr)}/${encodeURIComponent(ibGibAddr)}?getLatest=${getLatest}&getGraph=false`;
|
|
217
|
+
const response = await fetch(url, {
|
|
218
|
+
method: 'GET',
|
|
219
|
+
headers: {
|
|
220
|
+
'Accept': 'application/json',
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const data = await this.parseResponseJson(response, url);
|
|
225
|
+
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
228
|
+
console.error(`${lc} server rejected ibGib get: ${errorMsg}`);
|
|
229
|
+
return { success: false, message: errorMsg };
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return { success: true, ibGib: data };
|
|
233
|
+
|
|
234
|
+
} catch (error) {
|
|
235
|
+
const errorMsg = extractErrorMsg(error);
|
|
236
|
+
console.error(`${lc} fetch error: ${errorMsg}`);
|
|
237
|
+
return { success: false, message: errorMsg };
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* GETs the full dependency graph of an ibGib from the server's domain space.
|
|
243
|
+
*/
|
|
244
|
+
public async getIbGibGraph(domainAddr: string, ibGibAddr: string, getLatest = false): Promise<{ success: boolean; message?: string; graph?: Record<string, IbGib_V1>; addr?: string }> {
|
|
245
|
+
const lc = `${this.lc}[${this.getIbGibGraph.name}]`;
|
|
246
|
+
try {
|
|
247
|
+
if (logalot) { console.log(`${lc} fetching ibGib graph...`); }
|
|
248
|
+
|
|
249
|
+
const url = `/api/ibgib/${encodeURIComponent(domainAddr)}/${encodeURIComponent(ibGibAddr)}?getLatest=${getLatest}&getGraph=true`;
|
|
250
|
+
const response = await fetch(url, {
|
|
251
|
+
method: 'GET',
|
|
252
|
+
headers: {
|
|
253
|
+
'Accept': 'application/json',
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
const data = await response.json();
|
|
258
|
+
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
const errorMsg = data.message || data.error || 'Unknown error';
|
|
261
|
+
console.error(`${lc} server rejected ibGib graph get: ${errorMsg}`);
|
|
262
|
+
return { success: false, message: errorMsg };
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return { success: true, graph: data.graph, addr: data.addr };
|
|
266
|
+
|
|
267
|
+
} catch (error) {
|
|
268
|
+
const errorMsg = extractErrorMsg(error);
|
|
269
|
+
console.error(`${lc} fetch error: ${errorMsg}`);
|
|
270
|
+
return { success: false, message: errorMsg };
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
let _apiBridge: IbGibApiBridge | undefined;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Returns the global API bridge instance, creating a default IbGibApiBridge if not set.
|
|
279
|
+
*/
|
|
280
|
+
export function getApiBridge(): IbGibApiBridge {
|
|
281
|
+
if (!_apiBridge) {
|
|
282
|
+
_apiBridge = new IbGibApiBridge();
|
|
283
|
+
}
|
|
284
|
+
return _apiBridge;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* Registers a custom API bridge instance (e.g. SpaceGibApiBridge or app-specific subclass).
|
|
289
|
+
*/
|
|
290
|
+
export function setApiBridge(bridge: IbGibApiBridge): void {
|
|
291
|
+
_apiBridge = bridge;
|
|
292
|
+
}
|
|
@@ -213,7 +213,7 @@ export async function dynamicallyLoadBootstrapScript(
|
|
|
213
213
|
* @param globalThisKey The per-app namespace key used to find the bootstrap
|
|
214
214
|
* promise on globalThis.
|
|
215
215
|
*/
|
|
216
|
-
export function getComponentCtorArg(globalThisKey
|
|
216
|
+
export function getComponentCtorArg(globalThisKey?: string): IbGibDynamicComponentMetaCtorOpts {
|
|
217
217
|
const fnGetMetaspace = async () => getGlobalMetaspace_waitIfNeeded();
|
|
218
218
|
|
|
219
219
|
const bootstrapPromiseWrapper = new Promise<void>(async (resolve, reject) => {
|
|
@@ -222,16 +222,27 @@ export function getComponentCtorArg(globalThisKey: string): IbGibDynamicComponen
|
|
|
222
222
|
let counter = 0;
|
|
223
223
|
let bootstrapPromise: Promise<void> | undefined;
|
|
224
224
|
do {
|
|
225
|
-
|
|
226
|
-
getIbGibGlobalThis_IbGibApp(globalThisKey)?.bootstrapPromise;
|
|
225
|
+
if (globalThisKey) {
|
|
226
|
+
bootstrapPromise = getIbGibGlobalThis_IbGibApp(globalThisKey)?.bootstrapPromise;
|
|
227
|
+
} else {
|
|
228
|
+
bootstrapPromise = (globalThis as any).ibgib?.bootstrapPromise;
|
|
229
|
+
if (!bootstrapPromise && (globalThis as any).ibgib) {
|
|
230
|
+
const keys = Object.keys((globalThis as any).ibgib);
|
|
231
|
+
for (const k of keys) {
|
|
232
|
+
if ((globalThis as any).ibgib[k]?.bootstrapPromise) {
|
|
233
|
+
bootstrapPromise = (globalThis as any).ibgib[k].bootstrapPromise;
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
227
239
|
counter++;
|
|
228
240
|
if (counter > maxTries) { break; }
|
|
229
241
|
await delay(10);
|
|
230
242
|
} while (bootstrapPromise === undefined);
|
|
231
243
|
if (!bootstrapPromise) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
);
|
|
244
|
+
resolve();
|
|
245
|
+
return;
|
|
235
246
|
}
|
|
236
247
|
await bootstrapPromise;
|
|
237
248
|
resolve();
|
package/src/custom.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Tell TypeScript that importing a .html file will return a string.
|
|
2
|
+
declare module '*.html' {
|
|
3
|
+
const value: string;
|
|
4
|
+
export default value;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Tell TypeScript that importing a .css file will return a string.
|
|
8
|
+
declare module '*.css' {
|
|
9
|
+
const value: string;
|
|
10
|
+
export default value;
|
|
11
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module identity/keystone-sync-service
|
|
3
|
+
*
|
|
4
|
+
* On-Demand Keystone Sync Service.
|
|
5
|
+
* Provides functions to check for keystone updates on the server and sync updated keystone DAG graphs locally.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { extractErrorMsg } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
9
|
+
import { getIbAndGib, getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
10
|
+
import { getGibInfo } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
|
|
11
|
+
import { KeystoneIbGib_V1 } from "@ibgib/core-gib/dist/keystone/keystone-types.mjs";
|
|
12
|
+
import { getTimelinesGroupedByTjp, getTjpAddr, toDto } from "@ibgib/core-gib/dist/common/other/ibgib-helper.mjs";
|
|
13
|
+
import { updateSpecialIndex } from "@ibgib/core-gib/dist/timeline/timeline-api.mjs";
|
|
14
|
+
import { getApiBridge } from "../api/ibgib-api-bridge.mjs";
|
|
15
|
+
import { getGlobalMetaspace_waitIfNeeded } from "../helpers.mjs";
|
|
16
|
+
import { EVENT_IBGIB_IDENTITY_UPDATE_AVAILABLE } from "../ui/ui-constants.mjs";
|
|
17
|
+
import { EventIbGibIdentityUpdateAvailableDetail } from "../ui/ui-types.mjs";
|
|
18
|
+
|
|
19
|
+
export interface KeystoneUpdateCheckResult {
|
|
20
|
+
hasUpdate: boolean;
|
|
21
|
+
serverN: number;
|
|
22
|
+
localN: number;
|
|
23
|
+
serverLatestAddr: string;
|
|
24
|
+
graph: Record<string, KeystoneIbGib_V1>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class KeystoneSyncService {
|
|
28
|
+
protected lc: string = `[KeystoneSyncService]`;
|
|
29
|
+
|
|
30
|
+
private dispatchUpdateAvailableEvent(detail: EventIbGibIdentityUpdateAvailableDetail): void {
|
|
31
|
+
if (typeof window !== 'undefined') {
|
|
32
|
+
window.dispatchEvent(new CustomEvent(EVENT_IBGIB_IDENTITY_UPDATE_AVAILABLE, {
|
|
33
|
+
detail,
|
|
34
|
+
bubbles: true,
|
|
35
|
+
composed: true,
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Checks if a server update exists for the given active primary keystone address.
|
|
42
|
+
*/
|
|
43
|
+
public async checkForKeystoneUpdate({
|
|
44
|
+
activePrimaryAddr,
|
|
45
|
+
metaspace,
|
|
46
|
+
space
|
|
47
|
+
}: {
|
|
48
|
+
activePrimaryAddr: string;
|
|
49
|
+
metaspace?: any;
|
|
50
|
+
space?: any;
|
|
51
|
+
}): Promise<KeystoneUpdateCheckResult> {
|
|
52
|
+
const lc = `${this.lc}[${this.checkForKeystoneUpdate.name}]`;
|
|
53
|
+
try {
|
|
54
|
+
if (!metaspace) {
|
|
55
|
+
metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
56
|
+
}
|
|
57
|
+
if (!metaspace) {
|
|
58
|
+
throw new Error("Metaspace not available.");
|
|
59
|
+
}
|
|
60
|
+
if (!space) {
|
|
61
|
+
space = await metaspace.getLocalUserSpace({ lock: false });
|
|
62
|
+
}
|
|
63
|
+
if (!space) {
|
|
64
|
+
throw new Error("Local user space not available.");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Determine local latest address & frame
|
|
68
|
+
const localLatestAddr = (await metaspace.getLatestAddr({ addr: activePrimaryAddr, space })) || activePrimaryAddr;
|
|
69
|
+
const resLocal = await metaspace.get({ addrs: [localLatestAddr], space });
|
|
70
|
+
const localFrame = (resLocal.success && resLocal.ibGibs && resLocal.ibGibs.length > 0)
|
|
71
|
+
? (resLocal.ibGibs[0] as KeystoneIbGib_V1)
|
|
72
|
+
: undefined;
|
|
73
|
+
|
|
74
|
+
const localN = localFrame?.data?.n ?? 0;
|
|
75
|
+
|
|
76
|
+
// Fetch server graph using activePrimaryAddr (resolving to full domain TJP address, e.g. "keystone^hash")
|
|
77
|
+
const { ib } = getIbAndGib({ ibGibAddr: activePrimaryAddr });
|
|
78
|
+
const info = getGibInfo({ ibGibAddr: activePrimaryAddr });
|
|
79
|
+
const fallbackTjp = info.tjpGib ? `${ib}^${info.tjpGib}` : activePrimaryAddr;
|
|
80
|
+
const domainTjpAddr = (localFrame ? getTjpAddr({ ibGib: localFrame }) : undefined) || fallbackTjp;
|
|
81
|
+
const resGraph = await getApiBridge().getKeystoneGraph(domainTjpAddr);
|
|
82
|
+
|
|
83
|
+
if (!resGraph.success || !resGraph.graph) {
|
|
84
|
+
const res: KeystoneUpdateCheckResult = {
|
|
85
|
+
hasUpdate: false,
|
|
86
|
+
serverN: localN,
|
|
87
|
+
localN,
|
|
88
|
+
serverLatestAddr: localLatestAddr,
|
|
89
|
+
graph: {}
|
|
90
|
+
};
|
|
91
|
+
this.dispatchUpdateAvailableEvent({
|
|
92
|
+
activePrimaryAddr,
|
|
93
|
+
hasUpdate: res.hasUpdate,
|
|
94
|
+
serverN: res.serverN,
|
|
95
|
+
localN: res.localN,
|
|
96
|
+
serverLatestAddr: res.serverLatestAddr,
|
|
97
|
+
});
|
|
98
|
+
return res;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const graph = resGraph.graph as Record<string, KeystoneIbGib_V1>;
|
|
102
|
+
const graphIbGibs = Object.values(graph);
|
|
103
|
+
|
|
104
|
+
// Group timelines by TJP to isolate primary domain timeline
|
|
105
|
+
const timelinesMap = getTimelinesGroupedByTjp({ ibGibs: graphIbGibs });
|
|
106
|
+
// Look for timeline under domainTjpAddr or activePrimaryAddr or first available
|
|
107
|
+
const domainTimeline = timelinesMap[domainTjpAddr] || timelinesMap[activePrimaryAddr] || timelinesMap[Object.keys(timelinesMap)[0]] || [];
|
|
108
|
+
|
|
109
|
+
if (domainTimeline.length === 0) {
|
|
110
|
+
const res: KeystoneUpdateCheckResult = {
|
|
111
|
+
hasUpdate: false,
|
|
112
|
+
serverN: localN,
|
|
113
|
+
localN,
|
|
114
|
+
serverLatestAddr: localLatestAddr,
|
|
115
|
+
graph
|
|
116
|
+
};
|
|
117
|
+
this.dispatchUpdateAvailableEvent({
|
|
118
|
+
activePrimaryAddr,
|
|
119
|
+
hasUpdate: res.hasUpdate,
|
|
120
|
+
serverN: res.serverN,
|
|
121
|
+
localN: res.localN,
|
|
122
|
+
serverLatestAddr: res.serverLatestAddr,
|
|
123
|
+
});
|
|
124
|
+
return res;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Domain timeline sorted ascending by n
|
|
128
|
+
const sortedDomainTimeline = [...domainTimeline].sort((a, b) => (a.data?.n ?? 0) - (b.data?.n ?? 0));
|
|
129
|
+
const serverLatestFrame = sortedDomainTimeline[sortedDomainTimeline.length - 1] as KeystoneIbGib_V1;
|
|
130
|
+
const serverN = serverLatestFrame.data?.n ?? 0;
|
|
131
|
+
const serverLatestAddr = getIbGibAddr({ ibGib: serverLatestFrame });
|
|
132
|
+
|
|
133
|
+
const hasUpdate = serverN > localN;
|
|
134
|
+
|
|
135
|
+
const res: KeystoneUpdateCheckResult = {
|
|
136
|
+
hasUpdate,
|
|
137
|
+
serverN,
|
|
138
|
+
localN,
|
|
139
|
+
serverLatestAddr,
|
|
140
|
+
graph
|
|
141
|
+
};
|
|
142
|
+
this.dispatchUpdateAvailableEvent({
|
|
143
|
+
activePrimaryAddr,
|
|
144
|
+
hasUpdate: res.hasUpdate,
|
|
145
|
+
serverN: res.serverN,
|
|
146
|
+
localN: res.localN,
|
|
147
|
+
serverLatestAddr: res.serverLatestAddr,
|
|
148
|
+
});
|
|
149
|
+
return res;
|
|
150
|
+
} catch (error) {
|
|
151
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
152
|
+
const res: KeystoneUpdateCheckResult = {
|
|
153
|
+
hasUpdate: false,
|
|
154
|
+
serverN: 0,
|
|
155
|
+
localN: 0,
|
|
156
|
+
serverLatestAddr: activePrimaryAddr,
|
|
157
|
+
graph: {}
|
|
158
|
+
};
|
|
159
|
+
this.dispatchUpdateAvailableEvent({
|
|
160
|
+
activePrimaryAddr,
|
|
161
|
+
hasUpdate: false,
|
|
162
|
+
serverN: 0,
|
|
163
|
+
localN: 0,
|
|
164
|
+
serverLatestAddr: activePrimaryAddr,
|
|
165
|
+
});
|
|
166
|
+
return res;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Checks for updates and registers any missing server keystone frames into local space.
|
|
172
|
+
* Returns the updated (or current) primary keystone frame.
|
|
173
|
+
*/
|
|
174
|
+
public async updateActiveKeystone({
|
|
175
|
+
activePrimaryAddr,
|
|
176
|
+
metaspace,
|
|
177
|
+
space
|
|
178
|
+
}: {
|
|
179
|
+
activePrimaryAddr: string;
|
|
180
|
+
metaspace?: any;
|
|
181
|
+
space?: any;
|
|
182
|
+
}): Promise<KeystoneIbGib_V1 | undefined> {
|
|
183
|
+
const lc = `${this.lc}[${this.updateActiveKeystone.name}]`;
|
|
184
|
+
try {
|
|
185
|
+
if (!metaspace) {
|
|
186
|
+
metaspace = await getGlobalMetaspace_waitIfNeeded();
|
|
187
|
+
}
|
|
188
|
+
if (!metaspace) {
|
|
189
|
+
throw new Error("Metaspace not available.");
|
|
190
|
+
}
|
|
191
|
+
if (!space) {
|
|
192
|
+
space = await metaspace.getLocalUserSpace({ lock: false });
|
|
193
|
+
}
|
|
194
|
+
if (!space) {
|
|
195
|
+
throw new Error("Local user space not available.");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const updateInfo = await this.checkForKeystoneUpdate({ activePrimaryAddr, metaspace, space });
|
|
199
|
+
|
|
200
|
+
if (updateInfo.hasUpdate && Object.keys(updateInfo.graph).length > 0) {
|
|
201
|
+
const graphIbGibs = Object.values(updateInfo.graph);
|
|
202
|
+
// Put all graph ibgibs into space
|
|
203
|
+
await metaspace.put({ ibGibs: graphIbGibs, space });
|
|
204
|
+
|
|
205
|
+
// Group by TJP and register each frame ascending by n
|
|
206
|
+
const timelinesMap = getTimelinesGroupedByTjp({ ibGibs: graphIbGibs });
|
|
207
|
+
for (const tjpKey of Object.keys(timelinesMap)) {
|
|
208
|
+
const timeline = timelinesMap[tjpKey];
|
|
209
|
+
const sorted = [...timeline].sort((a, b) => (a.data?.n ?? 0) - (b.data?.n ?? 0));
|
|
210
|
+
for (const frame of sorted) {
|
|
211
|
+
await metaspace.registerNewIbGib({ ibGib: frame, space });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Get updated latest primary frame
|
|
216
|
+
const domainTjp = getGibInfo({ ibGibAddr: activePrimaryAddr }).tjpGib ?? activePrimaryAddr;
|
|
217
|
+
const domainTimeline = timelinesMap[domainTjp] || timelinesMap[activePrimaryAddr] || timelinesMap[Object.keys(timelinesMap)[0]];
|
|
218
|
+
const sortedDomain = [...domainTimeline].sort((a, b) => (a.data?.n ?? 0) - (b.data?.n ?? 0));
|
|
219
|
+
const updatedLatestFrame = sortedDomain[sortedDomain.length - 1] as KeystoneIbGib_V1;
|
|
220
|
+
|
|
221
|
+
if (updatedLatestFrame) {
|
|
222
|
+
// Update special index locally
|
|
223
|
+
await updateSpecialIndex({
|
|
224
|
+
type: "keystones",
|
|
225
|
+
rel8nInfos: [{
|
|
226
|
+
rel8nName: "keystone",
|
|
227
|
+
ibGibs: [toDto({ ibGib: updatedLatestFrame })]
|
|
228
|
+
}],
|
|
229
|
+
metaspace,
|
|
230
|
+
space
|
|
231
|
+
});
|
|
232
|
+
return updatedLatestFrame;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// If no update or update failed, return current local frame
|
|
237
|
+
const localLatestAddr = (await metaspace.getLatestAddr({ addr: activePrimaryAddr, space })) || activePrimaryAddr;
|
|
238
|
+
const resLocal = await metaspace.get({ addrs: [localLatestAddr], space });
|
|
239
|
+
if (resLocal.success && resLocal.ibGibs && resLocal.ibGibs.length > 0) {
|
|
240
|
+
return resLocal.ibGibs[0] as KeystoneIbGib_V1;
|
|
241
|
+
}
|
|
242
|
+
return undefined;
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
245
|
+
throw error;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let _keystoneSyncSvc: KeystoneSyncService | undefined;
|
|
251
|
+
|
|
252
|
+
export function getKeystoneSyncService(): KeystoneSyncService {
|
|
253
|
+
if (!_keystoneSyncSvc) {
|
|
254
|
+
_keystoneSyncSvc = new KeystoneSyncService();
|
|
255
|
+
}
|
|
256
|
+
return _keystoneSyncSvc;
|
|
257
|
+
}
|
package/src/index.mts
CHANGED
|
@@ -1,29 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @module @ibgib/web-gib
|
|
3
|
+
*
|
|
4
|
+
* Front Door: Streamlined App Bootstrapping & Web Components
|
|
5
|
+
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export * from "./app-bootstrap/bootstrap.mjs";
|
|
8
|
+
export * from "./app-bootstrap/types.mjs";
|
|
9
|
+
export * from "./app-bootstrap/init-orchestration.mjs";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export * from "./constants.mjs";
|
|
12
|
+
export * from "./types.mjs";
|
|
13
|
+
export * from "./helpers.web.mjs";
|
|
14
|
+
export * from "./helpers.mjs";
|
|
15
15
|
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
//
|
|
20
|
-
|
|
16
|
+
// REST API bridge
|
|
17
|
+
export * from "./api/ibgib-api-bridge.mjs";
|
|
18
|
+
|
|
19
|
+
// Identity & Sync services
|
|
20
|
+
export * from "./identity/keystone-sync-service.mjs";
|
|
21
|
+
|
|
22
|
+
// Identity UI components
|
|
23
|
+
export * from "./ui/component/identity/index.mjs";
|
|
24
|
+
|
|
25
|
+
// UI constants & types
|
|
26
|
+
export * from "./ui/ui-constants.mjs";
|
|
27
|
+
export * from "./ui/ui-types.mjs";
|
|
21
28
|
|
|
22
|
-
// /**
|
|
23
|
-
// * Toolbox: Library Internals
|
|
24
|
-
// * (Only export what's necessary for advanced users)
|
|
25
|
-
// */
|
|
26
|
-
// export * from "./constants.mjs";
|
|
27
|
-
// export * from "./types.mjs";
|
|
28
|
-
// export * from "./helpers.web.mjs";
|
|
29
|
-
// export * from "./helpers.mjs";
|