@le-space/ui 0.6.0 → 0.6.2

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.
@@ -9,9 +9,10 @@
9
9
  import './styles/theme.css'
10
10
 
11
11
  export let manifestUrl = './rootfs-manifest.json'
12
- export let manifestJson = ''
13
- export let sshPublicKey = ''
12
+ export let manifestJson = ''
13
+ export let sshPublicKey = ''
14
14
  export let instanceName = 'sponsor-relay'
15
+ export let ucanStoreBootstrap = undefined
15
16
  export let showInstances = true
16
17
  export let openByDefault = false
17
18
  export let launcherMode = 'floating'
@@ -26,6 +27,7 @@ export let apiHost = undefined
26
27
  manifestJson,
27
28
  sshPublicKey,
28
29
  instanceName,
30
+ ucanStoreBootstrap,
29
31
  showInstances,
30
32
  openByDefault,
31
33
  launcherMode,
@@ -42,13 +44,38 @@ export let apiHost = undefined
42
44
  : ''
43
45
  const pollingStages = new Set(['waiting-for-aleph', 'deployment-confirmed', 'publishing-bootstrap', 'refreshing-instances'])
44
46
 
47
+ function deploymentProfile() {
48
+ return state.manifest?.profile === 'ucan-store' ? 'ucan-store' : 'relay'
49
+ }
50
+
51
+ function deploymentTitle() {
52
+ return deploymentProfile() === 'ucan-store' ? 'Sponsor Service' : 'Sponsor Relay'
53
+ }
54
+
55
+ function deploymentInstanceFallbackLabel() {
56
+ return deploymentProfile() === 'ucan-store' ? 'service' : 'relay'
57
+ }
58
+
59
+ function deploymentButtonLabel() {
60
+ return deploymentProfile() === 'ucan-store' ? 'Deploy Service' : 'Deploy Relay'
61
+ }
62
+
63
+ function bootstrapUiEnabled() {
64
+ return deploymentProfile() !== 'ucan-store'
65
+ }
66
+
45
67
  $: pollingActive = state.busy.refreshing || pollingStages.has(state.deploymentProgress.stage)
68
+ $: isServiceProfile = deploymentProfile() === 'ucan-store'
46
69
  $: pollingLabel = state.busy.refreshing
47
- ? 'Checking relay state'
48
- : (state.deploymentProgress.label || 'Polling relay state')
70
+ ? (isServiceProfile ? 'Checking deployment state' : 'Checking relay state')
71
+ : (state.deploymentProgress.label || (isServiceProfile ? 'Polling deployment state' : 'Polling relay state'))
49
72
  $: pollingDetail = state.busy.refreshing
50
- ? (state.statusText || 'Refreshing relay sponsor data from Aleph and the selected CRN.')
51
- : (state.deploymentProgress.detail || state.statusText || 'Waiting for the next confirmed relay state from Aleph.')
73
+ ? (state.statusText || (isServiceProfile
74
+ ? 'Refreshing service deployment data from Aleph and the selected CRN.'
75
+ : 'Refreshing relay deployment data from Aleph and the selected CRN.'))
76
+ : (state.deploymentProgress.detail || state.statusText || (isServiceProfile
77
+ ? 'Waiting for the next confirmed deployment state from Aleph.'
78
+ : 'Waiting for the next confirmed relay state from Aleph.'))
52
79
  $: confirmedRegistrationByInstanceHash = new Map(
53
80
  (state.bootstrapRegistrations ?? [])
54
81
  .filter((entry) => entry.confirmed && entry.instanceItemHash)
@@ -86,7 +113,7 @@ export let apiHost = undefined
86
113
  <span class="eyebrow-version">{versionLabel}</span>
87
114
  {/if}
88
115
  </p>
89
- <h2>Sponsor Relay</h2>
116
+ <h2>{deploymentTitle()}</h2>
90
117
  </div>
91
118
  <button class="refresh" type="button" on:click={() => controller.refresh()} disabled={state.busy.refreshing}>
92
119
  {state.busy.refreshing ? 'Syncing' : 'Refresh'}
@@ -165,6 +192,50 @@ export let apiHost = undefined
165
192
  <textarea rows="7" on:input={(event) => controller.setManifestJson(event.currentTarget.value)}>{state.manifestJson}</textarea>
166
193
  </label>
167
194
  </AccordionSection>
195
+
196
+ {#if deploymentProfile() === 'ucan-store'}
197
+ <AccordionSection title="UCAN Store Bootstrap" open={true}>
198
+ <label class="field wide">
199
+ <span>Admin DID</span>
200
+ <input value={state.ucanStoreBootstrap.adminDid} on:input={(event) => controller.setUcanStoreBootstrapField('adminDid', event.currentTarget.value)} />
201
+ </label>
202
+ <label class="field wide">
203
+ <span>Service DID Override</span>
204
+ <input value={state.ucanStoreBootstrap.serviceDid} on:input={(event) => controller.setUcanStoreBootstrapField('serviceDid', event.currentTarget.value)} />
205
+ </label>
206
+ <label class="field wide">
207
+ <span>Space DID</span>
208
+ <input value={state.ucanStoreBootstrap.spaceDid} on:input={(event) => controller.setUcanStoreBootstrapField('spaceDid', event.currentTarget.value)} />
209
+ </label>
210
+ <label class="field wide">
211
+ <span>Root Delegation Proof</span>
212
+ <textarea rows="5" on:input={(event) => controller.setUcanStoreBootstrapField('rootDelegationProof', event.currentTarget.value)}>{state.ucanStoreBootstrap.rootDelegationProof}</textarea>
213
+ </label>
214
+ <label class="field wide">
215
+ <span>Allowed Capabilities</span>
216
+ <textarea rows="4" on:input={(event) => controller.setUcanStoreBootstrapField('allowedCapabilities', event.currentTarget.value)}>{state.ucanStoreBootstrap.allowedCapabilities}</textarea>
217
+ </label>
218
+ <div class="grid">
219
+ <label class="field">
220
+ <span>Default Expiration</span>
221
+ <input value={state.ucanStoreBootstrap.defaultUserDelegationExpiration} on:input={(event) => controller.setUcanStoreBootstrapField('defaultUserDelegationExpiration', event.currentTarget.value)} />
222
+ </label>
223
+ <label class="field">
224
+ <span>Max Expiration</span>
225
+ <input value={state.ucanStoreBootstrap.maxUserDelegationExpiration} on:input={(event) => controller.setUcanStoreBootstrapField('maxUserDelegationExpiration', event.currentTarget.value)} />
226
+ </label>
227
+ </div>
228
+ <label class="field wide">
229
+ <span>PWA Origin Override</span>
230
+ <input value={state.ucanStoreBootstrap.pwaOrigin} on:input={(event) => controller.setUcanStoreBootstrapField('pwaOrigin', event.currentTarget.value)} />
231
+ </label>
232
+ <label class="field wide">
233
+ <span>Service Origin Override</span>
234
+ <input value={state.ucanStoreBootstrap.serviceOrigin} on:input={(event) => controller.setUcanStoreBootstrapField('serviceOrigin', event.currentTarget.value)} />
235
+ </label>
236
+ <small>Operator address comes from the connected MetaMask account. If service origin is empty, the runtime proxy URL is used during guest configuration.</small>
237
+ </AccordionSection>
238
+ {/if}
168
239
  </div>
169
240
  </details>
170
241
 
@@ -194,7 +265,7 @@ export let apiHost = undefined
194
265
  <div class="actions">
195
266
  {#if state.wallet.connected}
196
267
  <button class="primary" type="button" on:click={() => controller.deploy()} disabled={state.busy.deploying || state.rootfsHealth.tone !== 'ok'}>
197
- {state.busy.deploying ? 'Deploying…' : 'Deploy Relay'}
268
+ {state.busy.deploying ? 'Deploying…' : deploymentButtonLabel()}
198
269
  </button>
199
270
  {:else}
200
271
  <button class="primary" type="button" on:click={() => controller.connectWallet()} disabled={state.busy.connectingWallet}>
@@ -225,7 +296,7 @@ export let apiHost = undefined
225
296
  {/if}
226
297
 
227
298
  {#each state.instances as entry}
228
- <AccordionSection title={`${entry.instance.content?.metadata?.name ?? 'relay'} · ${shortHash(entry.instance.item_hash)}`} open={true}>
299
+ <AccordionSection title={`${entry.instance.content?.metadata?.name ?? deploymentInstanceFallbackLabel()} · ${shortHash(entry.instance.item_hash)}`} open={true}>
229
300
  {@const confirmedRegistration = confirmedRegistrationByInstanceHash.get(entry.instance.item_hash)}
230
301
  <div class="instance-topline">
231
302
  <div class="chip-row">
@@ -233,7 +304,7 @@ export let apiHost = undefined
233
304
  {#if entry.details.crnUrl}
234
305
  <span class="chip">{entry.details.crnUrl.replace(/^https?:\/\//, '')}</span>
235
306
  {/if}
236
- {#if confirmedRegistration}
307
+ {#if bootstrapUiEnabled() && confirmedRegistration}
237
308
  <span class="chip chip-confirmed">
238
309
  <span class="chip-dot-confirmed"></span>
239
310
  Aleph bootstrap registered
@@ -280,7 +351,7 @@ export let apiHost = undefined
280
351
  <strong>{joinMappedPorts(entry.details.mappedPorts)}</strong>
281
352
  </div>
282
353
 
283
- {#if confirmedRegistration}
354
+ {#if bootstrapUiEnabled() && confirmedRegistration}
284
355
  <div class="mono-block">
285
356
  <span>Bootstrap Registration</span>
286
357
  <strong>{shortHash(confirmedRegistration.messageHash ?? confirmedRegistration.content?.registrationId ?? 'confirmed', 14, 8)}</strong>
@@ -302,7 +373,7 @@ export let apiHost = undefined
302
373
  </AccordionSection>
303
374
  {/each}
304
375
 
305
- {#if orphanRegistrations.length > 0}
376
+ {#if bootstrapUiEnabled() && orphanRegistrations.length > 0}
306
377
  <div class="orphan-box">
307
378
  <div class="orphan-head">
308
379
  <strong>Orphan bootstrap registrations</strong>