@sanity/runtime-cli 1.5.0 → 1.8.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.
Files changed (57) hide show
  1. package/README.md +184 -122
  2. package/dist/actions/blueprints/blueprint.d.ts +24 -7
  3. package/dist/actions/blueprints/blueprint.js +114 -58
  4. package/dist/actions/blueprints/logs.d.ts +3 -0
  5. package/dist/actions/blueprints/logs.js +24 -0
  6. package/dist/actions/blueprints/projects.d.ts +5 -0
  7. package/dist/actions/blueprints/projects.js +21 -0
  8. package/dist/actions/blueprints/resources.d.ts +13 -0
  9. package/dist/actions/blueprints/resources.js +37 -0
  10. package/dist/actions/blueprints/stacks.js +1 -1
  11. package/dist/commands/blueprints/add.d.ts +10 -0
  12. package/dist/commands/blueprints/add.js +67 -0
  13. package/dist/commands/blueprints/config.d.ts +9 -0
  14. package/dist/commands/blueprints/config.js +72 -0
  15. package/dist/commands/blueprints/deploy.js +13 -12
  16. package/dist/commands/blueprints/info.js +1 -1
  17. package/dist/commands/blueprints/init.d.ts +6 -0
  18. package/dist/commands/blueprints/init.js +56 -0
  19. package/dist/commands/blueprints/logs.js +24 -64
  20. package/dist/commands/blueprints/stacks.js +3 -15
  21. package/dist/commands/functions/invoke.d.ts +1 -1
  22. package/dist/commands/functions/invoke.js +9 -7
  23. package/dist/commands/functions/logs.d.ts +1 -1
  24. package/dist/commands/functions/logs.js +21 -12
  25. package/dist/commands/functions/test.d.ts +1 -1
  26. package/dist/commands/functions/test.js +25 -16
  27. package/dist/config.d.ts +1 -0
  28. package/dist/config.js +10 -4
  29. package/dist/server/app.js +2 -2
  30. package/dist/server/static/api.js +43 -38
  31. package/dist/server/static/components/api-base.js +7 -6
  32. package/dist/server/static/components/function-list.js +48 -44
  33. package/dist/server/static/components/network-spinner.js +7 -6
  34. package/dist/server/static/components/payload-panel.js +36 -32
  35. package/dist/server/static/components/response-panel.js +64 -50
  36. package/dist/server/static/vendor/vendor.bundle.js +1029 -913
  37. package/dist/utils/display/blueprints-formatting.d.ts +3 -1
  38. package/dist/utils/display/blueprints-formatting.js +27 -2
  39. package/dist/utils/display/logs-formatting.d.ts +5 -0
  40. package/dist/utils/display/logs-formatting.js +50 -0
  41. package/dist/utils/find-function.d.ts +2 -0
  42. package/dist/utils/find-function.js +6 -0
  43. package/dist/utils/types.d.ts +0 -1
  44. package/oclif.manifest.json +120 -31
  45. package/package.json +14 -10
  46. package/dist/server/static/static/api.js +0 -53
  47. package/dist/server/static/static/components/api-base.js +0 -10
  48. package/dist/server/static/static/components/function-list.js +0 -54
  49. package/dist/server/static/static/components/network-spinner.js +0 -71
  50. package/dist/server/static/static/components/payload-panel.js +0 -45
  51. package/dist/server/static/static/components/response-panel.js +0 -83
  52. package/dist/server/static/static/vendor/vendor.bundle.js +0 -26879
  53. package/dist/utils/spinner.d.ts +0 -9
  54. package/dist/utils/spinner.js +0 -25
  55. /package/dist/server/static/{static/components → components}/app.css +0 -0
  56. /package/dist/server/static/{static/index.html → index.html} +0 -0
  57. /package/dist/server/static/{static/sanity-logo-sm.svg → sanity-logo-sm.svg} +0 -0
@@ -1,4 +1,6 @@
1
- import type { BlueprintResource } from '../types.js';
1
+ import type { BlueprintResource, BlueprintStack } from '../types.js';
2
2
  export declare function formatTitle(title: string, name: string): string;
3
3
  export declare function formatStacksList(stacks: string[]): string;
4
4
  export declare function formatResourceTree(resources: BlueprintResource[], logger: (msg: string) => void): void;
5
+ export declare function formatStackInfo(stack: BlueprintStack, isCurrentStack?: boolean): string;
6
+ export declare function formatStacksListing(stacks: BlueprintStack[], currentStackId?: string): string;
@@ -1,4 +1,5 @@
1
1
  import { blue, bold, boldnblue, green, yellow } from './colors.js';
2
+ import { formatDate } from './dates.js';
2
3
  export function formatTitle(title, name) {
3
4
  return `${boldnblue(title)} ${bold(`"${name}"`)}`;
4
5
  }
@@ -18,8 +19,8 @@ export function formatResourceTree(resources, logger) {
18
19
  return;
19
20
  }
20
21
  logger(`${blue('Stack Resources')} [${resources.length}]`);
21
- const functionResources = resources.filter((r) => r.type?.startsWith('sanity.function.') || r.kind === 'function');
22
- const otherResources = resources.filter((r) => !r.type?.startsWith('sanity.function.') && r.kind !== 'function');
22
+ const functionResources = resources.filter((r) => r.type?.startsWith('sanity.function.'));
23
+ const otherResources = resources.filter((r) => !r.type?.startsWith('sanity.function.'));
23
24
  const hasOtherResources = otherResources.length > 0;
24
25
  if (functionResources.length > 0) {
25
26
  logger(` ${hasOtherResources ? '├─' : '└─'} ${bold('Functions')} [${functionResources.length}]`);
@@ -40,3 +41,27 @@ export function formatResourceTree(resources, logger) {
40
41
  }
41
42
  }
42
43
  }
44
+ export function formatStackInfo(stack, isCurrentStack = false) {
45
+ let result = '';
46
+ const stackName = isCurrentStack ? boldnblue(stack.name) : bold(stack.name);
47
+ result += `${stackName} <${yellow(stack.id)}>${isCurrentStack ? ' (current)' : ''}\n`;
48
+ if (stack.createdAt) {
49
+ result += ` Created: ${formatDate(stack.createdAt)}\n`;
50
+ }
51
+ if (stack.updatedAt) {
52
+ result += ` Updated: ${formatDate(stack.updatedAt)}\n`;
53
+ }
54
+ result += ` ${stack.resources.length} resource${stack.resources.length === 1 ? '' : 's'}\n\n`;
55
+ return result;
56
+ }
57
+ export function formatStacksListing(stacks, currentStackId) {
58
+ if (!stacks || stacks.length === 0) {
59
+ return 'No stacks found';
60
+ }
61
+ let result = '';
62
+ for (const stack of stacks) {
63
+ const isCurrentStack = currentStackId === stack.id;
64
+ result += formatStackInfo(stack, isCurrentStack);
65
+ }
66
+ return result;
67
+ }
@@ -0,0 +1,5 @@
1
+ import type { BlueprintLog } from '../types.js';
2
+ export declare function formatLogEntry(log: BlueprintLog, isNewest?: boolean): string;
3
+ export declare function formatRecentLogs(logs: BlueprintLog[]): string;
4
+ export declare function organizeLogsByDay(logs: BlueprintLog[]): Map<string, BlueprintLog[]>;
5
+ export declare function formatLogsByDay(logsByDay: Map<string, BlueprintLog[]>): string;
@@ -0,0 +1,50 @@
1
+ import { blue, bold, green, yellow } from './colors.js';
2
+ export function formatLogEntry(log, isNewest = false) {
3
+ const date = new Date(log.timestamp);
4
+ const time = date.toLocaleTimeString();
5
+ const day = date.toLocaleDateString();
6
+ return `${isNewest ? `${green('>')} ` : ''}${bold(day)} ${yellow(time)} ${log.message}`;
7
+ }
8
+ export function formatRecentLogs(logs) {
9
+ if (logs.length === 0)
10
+ return 'No recent logs found';
11
+ const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
12
+ const recentLogs = sortedLogs.slice(-10);
13
+ let result = '\nMost recent logs:\n';
14
+ for (const log of recentLogs) {
15
+ result += ` ${formatLogEntry(log)}\n`;
16
+ }
17
+ return result;
18
+ }
19
+ export function organizeLogsByDay(logs) {
20
+ const logsByDay = new Map();
21
+ for (const log of logs) {
22
+ const date = new Date(log.timestamp);
23
+ const day = date.toLocaleDateString();
24
+ if (!logsByDay.has(day)) {
25
+ logsByDay.set(day, []);
26
+ }
27
+ logsByDay.get(day)?.push(log);
28
+ }
29
+ return logsByDay;
30
+ }
31
+ export function formatLogsByDay(logsByDay) {
32
+ let result = '';
33
+ const sortedDays = Array.from(logsByDay.keys()).sort((a, b) => {
34
+ return new Date(a).getTime() - new Date(b).getTime();
35
+ });
36
+ for (const day of sortedDays) {
37
+ result += `${blue('Date:')} ${bold(day)}\n`;
38
+ const dayLogs = logsByDay.get(day) || [];
39
+ dayLogs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
40
+ for (const [i, log] of dayLogs.entries()) {
41
+ const date = new Date(log.timestamp);
42
+ const time = date.toLocaleTimeString();
43
+ const isLast = i === dayLogs.length - 1;
44
+ result += ` ${isLast ? '└─' : '├─'} ${yellow(time)} ${log.message}\n`;
45
+ }
46
+ // new line between days
47
+ result += '\n';
48
+ }
49
+ return result;
50
+ }
@@ -0,0 +1,2 @@
1
+ import type { Blueprint, BlueprintResource, BlueprintStack } from './types.js';
2
+ export declare function findFunctionByName(blueprint: Blueprint | BlueprintStack, name: string): BlueprintResource;
@@ -0,0 +1,6 @@
1
+ export function findFunctionByName(blueprint, name) {
2
+ const func = blueprint?.resources.find((r) => r?.type?.startsWith('sanity.function.') && r.name === name);
3
+ if (!func)
4
+ throw Error(`Unable to find function ${name}`);
5
+ return func;
6
+ }
@@ -37,7 +37,6 @@ export interface BlueprintResource {
37
37
  id: string;
38
38
  displayName: string;
39
39
  name: string;
40
- kind: string;
41
40
  type: string;
42
41
  src: string;
43
42
  externalId: string;
@@ -1,5 +1,70 @@
1
1
  {
2
2
  "commands": {
3
+ "blueprints:add": {
4
+ "aliases": [],
5
+ "args": {
6
+ "type": {
7
+ "description": "Type of resource to add (e.g. function)",
8
+ "name": "type",
9
+ "options": [
10
+ "function"
11
+ ],
12
+ "required": true
13
+ }
14
+ },
15
+ "description": "Add a resource to a Blueprint",
16
+ "examples": [
17
+ "<%= config.bin %> <%= command.id %> function"
18
+ ],
19
+ "flags": {},
20
+ "hasDynamicHelp": false,
21
+ "hiddenAliases": [],
22
+ "id": "blueprints:add",
23
+ "pluginAlias": "@sanity/runtime-cli",
24
+ "pluginName": "@sanity/runtime-cli",
25
+ "pluginType": "core",
26
+ "strict": true,
27
+ "enableJsonFlag": false,
28
+ "isESM": true,
29
+ "relativePath": [
30
+ "src",
31
+ "commands",
32
+ "blueprints",
33
+ "add.ts"
34
+ ]
35
+ },
36
+ "blueprints:config": {
37
+ "aliases": [],
38
+ "args": {},
39
+ "description": "View or edit Blueprint configuration",
40
+ "examples": [
41
+ "<%= config.bin %> <%= command.id %>",
42
+ "<%= config.bin %> <%= command.id %> --edit"
43
+ ],
44
+ "flags": {
45
+ "edit": {
46
+ "description": "Edit the configuration",
47
+ "name": "edit",
48
+ "allowNo": false,
49
+ "type": "boolean"
50
+ }
51
+ },
52
+ "hasDynamicHelp": false,
53
+ "hiddenAliases": [],
54
+ "id": "blueprints:config",
55
+ "pluginAlias": "@sanity/runtime-cli",
56
+ "pluginName": "@sanity/runtime-cli",
57
+ "pluginType": "core",
58
+ "strict": true,
59
+ "enableJsonFlag": false,
60
+ "isESM": true,
61
+ "relativePath": [
62
+ "src",
63
+ "commands",
64
+ "blueprints",
65
+ "config.ts"
66
+ ]
67
+ },
3
68
  "blueprints:deploy": {
4
69
  "aliases": [],
5
70
  "args": {},
@@ -18,10 +83,10 @@
18
83
  "enableJsonFlag": false,
19
84
  "isESM": true,
20
85
  "relativePath": [
21
- "dist",
86
+ "src",
22
87
  "commands",
23
88
  "blueprints",
24
- "deploy.js"
89
+ "deploy.ts"
25
90
  ]
26
91
  },
27
92
  "blueprints:info": {
@@ -52,10 +117,34 @@
52
117
  "enableJsonFlag": false,
53
118
  "isESM": true,
54
119
  "relativePath": [
55
- "dist",
120
+ "src",
56
121
  "commands",
57
122
  "blueprints",
58
- "info.js"
123
+ "info.ts"
124
+ ]
125
+ },
126
+ "blueprints:init": {
127
+ "aliases": [],
128
+ "args": {},
129
+ "description": "Initialize a new Blueprint",
130
+ "examples": [
131
+ "<%= config.bin %> <%= command.id %>"
132
+ ],
133
+ "flags": {},
134
+ "hasDynamicHelp": false,
135
+ "hiddenAliases": [],
136
+ "id": "blueprints:init",
137
+ "pluginAlias": "@sanity/runtime-cli",
138
+ "pluginName": "@sanity/runtime-cli",
139
+ "pluginType": "core",
140
+ "strict": true,
141
+ "enableJsonFlag": false,
142
+ "isESM": true,
143
+ "relativePath": [
144
+ "src",
145
+ "commands",
146
+ "blueprints",
147
+ "init.ts"
59
148
  ]
60
149
  },
61
150
  "blueprints:logs": {
@@ -86,10 +175,10 @@
86
175
  "enableJsonFlag": false,
87
176
  "isESM": true,
88
177
  "relativePath": [
89
- "dist",
178
+ "src",
90
179
  "commands",
91
180
  "blueprints",
92
- "logs.js"
181
+ "logs.ts"
93
182
  ]
94
183
  },
95
184
  "blueprints:plan": {
@@ -110,10 +199,10 @@
110
199
  "enableJsonFlag": false,
111
200
  "isESM": true,
112
201
  "relativePath": [
113
- "dist",
202
+ "src",
114
203
  "commands",
115
204
  "blueprints",
116
- "plan.js"
205
+ "plan.ts"
117
206
  ]
118
207
  },
119
208
  "blueprints:stacks": {
@@ -134,10 +223,10 @@
134
223
  "enableJsonFlag": false,
135
224
  "isESM": true,
136
225
  "relativePath": [
137
- "dist",
226
+ "src",
138
227
  "commands",
139
228
  "blueprints",
140
- "stacks.js"
229
+ "stacks.ts"
141
230
  ]
142
231
  },
143
232
  "functions:dev": {
@@ -168,18 +257,18 @@
168
257
  "enableJsonFlag": false,
169
258
  "isESM": true,
170
259
  "relativePath": [
171
- "dist",
260
+ "src",
172
261
  "commands",
173
262
  "functions",
174
- "dev.js"
263
+ "dev.ts"
175
264
  ]
176
265
  },
177
266
  "functions:invoke": {
178
267
  "aliases": [],
179
268
  "args": {
180
- "id": {
181
- "description": "The ID of the function to invoke",
182
- "name": "id",
269
+ "name": {
270
+ "description": "The name of the Sanity Function",
271
+ "name": "name",
183
272
  "required": true
184
273
  }
185
274
  },
@@ -218,18 +307,18 @@
218
307
  "enableJsonFlag": false,
219
308
  "isESM": true,
220
309
  "relativePath": [
221
- "dist",
310
+ "src",
222
311
  "commands",
223
312
  "functions",
224
- "invoke.js"
313
+ "invoke.ts"
225
314
  ]
226
315
  },
227
316
  "functions:logs": {
228
317
  "aliases": [],
229
318
  "args": {
230
- "id": {
231
- "description": "The ID of the function to retrieve logs for",
232
- "name": "id",
319
+ "name": {
320
+ "description": "The name of the Sanity Function",
321
+ "name": "name",
233
322
  "required": true
234
323
  }
235
324
  },
@@ -248,26 +337,26 @@
248
337
  "enableJsonFlag": false,
249
338
  "isESM": true,
250
339
  "relativePath": [
251
- "dist",
340
+ "src",
252
341
  "commands",
253
342
  "functions",
254
- "logs.js"
343
+ "logs.ts"
255
344
  ]
256
345
  },
257
346
  "functions:test": {
258
347
  "aliases": [],
259
348
  "args": {
260
- "path": {
261
- "description": "The path to the function source code",
262
- "name": "path",
349
+ "name": {
350
+ "description": "The name of the Sanity Function",
351
+ "name": "name",
263
352
  "required": true
264
353
  }
265
354
  },
266
355
  "description": "Invoke a local Sanity Function",
267
356
  "examples": [
268
- "<%= config.bin %> <%= command.id %> ./test.ts --data '{ \"id\": 1 }'",
269
- "<%= config.bin %> <%= command.id %> ./test.js --file 'payload.json'",
270
- "<%= config.bin %> <%= command.id %> ./test.ts --data '{ \"id\": 1 }' --timeout 60"
357
+ "<%= config.bin %> <%= command.id %> echo-fn --data '{ \"id\": 1 }'",
358
+ "<%= config.bin %> <%= command.id %> echo-fn --file 'payload.json'",
359
+ "<%= config.bin %> <%= command.id %> echo-fn --data '{ \"id\": 1 }' --timeout 60"
271
360
  ],
272
361
  "flags": {
273
362
  "data": {
@@ -308,12 +397,12 @@
308
397
  "enableJsonFlag": false,
309
398
  "isESM": true,
310
399
  "relativePath": [
311
- "dist",
400
+ "src",
312
401
  "commands",
313
402
  "functions",
314
- "test.js"
403
+ "test.ts"
315
404
  ]
316
405
  }
317
406
  },
318
- "version": "1.5.0"
407
+ "version": "1.8.0"
319
408
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sanity/runtime-cli",
3
3
  "description": "A new CLI generated with oclif",
4
- "version": "1.5.0",
4
+ "version": "1.8.0",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -13,19 +13,22 @@
13
13
  "engines": {
14
14
  "node": ">=20.11.0"
15
15
  },
16
+ "optionalPeerDependencies": {
17
+ "tsx": "^4.19.3"
18
+ },
16
19
  "files": [
17
20
  "./bin",
18
21
  "./dist",
19
22
  "./oclif.manifest.json"
20
23
  ],
21
24
  "bin": {
22
- "sanity": "./bin/run.js"
25
+ "sanity-run": "./bin/run.js"
23
26
  },
24
27
  "scripts": {
25
28
  "build": "rollup -c && npm run build:bin && npm run build:static",
26
29
  "build:bin": "shx rm -rf dist *.tsbuildinfo && tsc -b",
27
30
  "build:static": "npm run copy:wrapper && npm run copy:server",
28
- "copy:server": "shx cp -r ./src/server/static ./dist/server/static",
31
+ "copy:server": "shx cp -r ./src/server/static ./dist/server",
29
32
  "copy:wrapper": "shx cp ./src/utils/child-process-wrapper.js ./dist/utils/child-process-wrapper.js",
30
33
  "lint": "biome ci",
31
34
  "lint:write": "biome check --write",
@@ -44,6 +47,9 @@
44
47
  "inquirer": "^12.5.0",
45
48
  "jszip": "^3.10.1",
46
49
  "mime-types": "^2.1.35",
50
+ "picocolors": "^1.1.1",
51
+ "picospinner": "^3.0.0",
52
+ "tinyhighlight": "^0.3.2",
47
53
  "xdg-basedir": "^5.1.0"
48
54
  },
49
55
  "devDependencies": {
@@ -64,23 +70,21 @@
64
70
  "rollup": "^4.36.0",
65
71
  "shx": "^0.4.0",
66
72
  "ts-node": "^10",
73
+ "tsx": "^4.19.3",
67
74
  "typescript": "^5",
68
75
  "vitest": "3.0.8"
69
76
  },
70
77
  "oclif": {
71
- "bin": "sanity",
72
- "dirname": "sanity",
78
+ "bin": "sanity-run",
79
+ "dirname": "sanity-run",
73
80
  "commands": "./dist/commands",
74
81
  "plugins": [
75
82
  "@oclif/plugin-help",
76
83
  "@oclif/plugin-plugins"
77
84
  ],
85
+ "state": "beta",
78
86
  "topicSeparator": " ",
79
- "topics": {
80
- "hello": {
81
- "description": "Say hello to the world and others"
82
- }
83
- }
87
+ "topics": {}
84
88
  },
85
89
  "publishConfig": {
86
90
  "access": "public",
@@ -1,53 +0,0 @@
1
- /* eslint-disable n/no-unsupported-features/node-builtins */
2
- import {Store} from './vendor/vendor.bundle.js'
3
-
4
- // eslint-disable-next-line new-cap
5
- const store = Store()
6
-
7
- export default function API() {
8
- return {
9
- blueprint,
10
- invoke,
11
- store,
12
- subscribe: store.subscribe,
13
- unsubscribe: store.unsubscribe,
14
- }
15
- }
16
-
17
- function invoke(payloadText = '{}') {
18
- store.inprogress = true
19
- const start = Date.now()
20
- const payload = {
21
- data: payloadText,
22
- func: store.selectedIndex,
23
- }
24
- fetch('/invoke', {
25
- body: JSON.stringify(payload),
26
- headers: {
27
- 'Content-Type': 'application/json',
28
- },
29
- method: 'POST',
30
- })
31
- .then((response) => response.json())
32
- .then((data) => {
33
- store.inprogress = false
34
- store.result = {
35
- ...data,
36
- time: Date.now() - start,
37
- }
38
- })
39
- }
40
-
41
- function blueprint() {
42
- fetch('/blueprint')
43
- .then((response) => response.json())
44
- .then((json) => {
45
- const functions = json?.document?.resources.filter((resource) => resource.kind === 'function')
46
-
47
- store.functions = functions
48
- store.selectedIndex = functions[0].src
49
- })
50
- .catch(() => {
51
- store.functions = []
52
- })
53
- }
@@ -1,10 +0,0 @@
1
- /* globals HTMLElement */
2
- import apiConstructor from '../api.js'
3
- const api = apiConstructor()
4
-
5
- export class ApiBaseElement extends HTMLElement {
6
- constructor() {
7
- super()
8
- this.api = api
9
- }
10
- }
@@ -1,54 +0,0 @@
1
- /* globals customElements */
2
- import {ApiBaseElement} from './api-base.js'
3
-
4
- const template = `<ol class="hidden-lg" type="content"></ol>
5
- <fieldset class="pad-sm hidden block-lg"><select></select></fieldset>
6
- `
7
-
8
- class FunctionList extends ApiBaseElement {
9
- functionClicked = (event) => {
10
- // eslint-disable-next-line unicorn/prefer-dom-node-text-content
11
- const target = this.api.store.functions.find((func) => func.name === event.srcElement.innerText)
12
- this.api.store.selectedIndex = target.src
13
- }
14
- functionSelected = (event) => {
15
- this.api.store.selectedIndex = event.srcElement.value
16
- }
17
- renderFunctions = () => {
18
- if (this.api.store.functions.length > 0) {
19
- this.list.innerHTML = this.api.store.functions
20
- .map((func) => {
21
- const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
22
- return `<li class="pad-sm ${selected}">${func.name}</li>`
23
- })
24
- .join('')
25
- this.select.innerHTML = this.api.store.functions
26
- .map((func) => {
27
- const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
28
- return `<option value="${func.src}" ${selected}>${func.name}</option>`
29
- })
30
- .join('')
31
- } else {
32
- this.list.innerHTML = '<option class="pad-sm">No blueprint.json file found</li>'
33
- this.select.innerHTML = '<option>No blueprint.json file found</option>'
34
- }
35
- }
36
-
37
- connectedCallback() {
38
- this.innerHTML = template
39
- this.list = this.querySelector('ol')
40
- this.select = this.querySelector('select')
41
- this.list.addEventListener('click', this.functionClicked)
42
- this.select.addEventListener('change', this.functionSelected)
43
- this.api.subscribe(this.renderFunctions, ['functions', 'selectedIndex'])
44
- this.api.blueprint()
45
- }
46
-
47
- disconnectedCallback() {
48
- this.list.removeEventListener('click', this.functionClicked)
49
- this.select.removeEventListener('change', this.functionSelected)
50
- this.api.unsubscribe(this.renderFunctions)
51
- }
52
- }
53
-
54
- customElements.define('function-list', FunctionList)
@@ -1,71 +0,0 @@
1
- /* globals customElements HTMLElement */
2
- const template = `<style>
3
- network-spinner {
4
- --track-width: 2px;
5
- --track-color: var(--card-border-color);
6
- --indicator-color: var(--text-color);
7
- --speed: 2s;
8
-
9
- display: inline-flex;
10
- width: 1em;
11
- height: 1em;
12
- flex: none;
13
- }
14
-
15
- .spinner {
16
- flex: 1 1 auto;
17
- height: 100%;
18
- width: 100%;
19
- }
20
-
21
- .spinner__track,
22
- .spinner__indicator {
23
- fill: none;
24
- stroke-width: var(--track-width);
25
- r: calc(0.5em - var(--track-width) / 2);
26
- cx: 0.5em;
27
- cy: 0.5em;
28
- transform-origin: 50% 50%;
29
- }
30
-
31
- .spinner__track {
32
- stroke: var(--track-color);
33
- transform-origin: 0% 0%;
34
- }
35
-
36
- .spinner__indicator {
37
- stroke: var(--indicator-color);
38
- stroke-linecap: round;
39
- stroke-dasharray: 150% 75%;
40
- animation: spin var(--speed) linear infinite;
41
- }
42
-
43
- @keyframes spin {
44
- 0% {
45
- transform: rotate(0deg);
46
- stroke-dasharray: 0.05em, 3em;
47
- }
48
-
49
- 50% {
50
- transform: rotate(450deg);
51
- stroke-dasharray: 1.375em, 1.375em;
52
- }
53
-
54
- 100% {
55
- transform: rotate(1080deg);
56
- stroke-dasharray: 0.05em, 3em;
57
- }
58
- }
59
- </style>
60
- <svg part="base" class="spinner" role="progressbar" aria-label="loading">
61
- <circle class="spinner__track"></circle>
62
- <circle class="spinner__indicator"></circle>
63
- </svg>`
64
-
65
- class NetworkSpinner extends HTMLElement {
66
- connectedCallback() {
67
- this.innerHTML = template
68
- }
69
- }
70
-
71
- customElements.define('network-spinner', NetworkSpinner)