@zooid/web 0.6.0 → 0.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 (47) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +39 -0
  3. package/dist/assets/geist-cyrillic-wght-normal-CHSlOQsW.woff2 +0 -0
  4. package/dist/assets/geist-latin-ext-wght-normal-DMtmJ5ZE.woff2 +0 -0
  5. package/dist/assets/geist-latin-wght-normal-Dm3htQBi.woff2 +0 -0
  6. package/dist/assets/index-Bq2HBBZQ.css +1 -0
  7. package/dist/assets/index-CiUWUtw6.js +118066 -0
  8. package/dist/assets/index-wOYm83VW.js +439 -0
  9. package/dist/assets/reaction-picker-emoji-CI7LVLOX.js +716 -0
  10. package/dist/favicon.svg +1 -0
  11. package/dist/index.html +7 -35
  12. package/package.json +63 -29
  13. package/dist/assets/index-7P1i28a8.js +0 -66
  14. package/dist/assets/index-BeqmFlCW.css +0 -1
  15. package/dist/assets/json-editor-Cvlnnf1Q.css +0 -1
  16. package/dist/assets/json-editor-iJIPDKxB.js +0 -84
  17. package/dist/assets/vanilla-picker-l5rcX3cq.js +0 -8
  18. package/src/App.svelte +0 -678
  19. package/src/app.css +0 -178
  20. package/src/lib/api.ts +0 -78
  21. package/src/lib/components/admin-dropdown.svelte +0 -89
  22. package/src/lib/components/auth-modal.svelte +0 -114
  23. package/src/lib/components/avatar.svelte +0 -29
  24. package/src/lib/components/channel-header.svelte +0 -73
  25. package/src/lib/components/create-channel-modal.svelte +0 -137
  26. package/src/lib/components/edit-channel-modal.svelte +0 -234
  27. package/src/lib/components/event-card.svelte +0 -221
  28. package/src/lib/components/event-feed.svelte +0 -50
  29. package/src/lib/components/homepage.svelte +0 -86
  30. package/src/lib/components/json-editor.svelte +0 -57
  31. package/src/lib/components/keys-and-tokens-page.svelte +0 -216
  32. package/src/lib/components/keys-modal.svelte +0 -120
  33. package/src/lib/components/message-bar.svelte +0 -290
  34. package/src/lib/components/mint-token-modal.svelte +0 -141
  35. package/src/lib/components/ref-link.svelte +0 -33
  36. package/src/lib/components/ref-side-sheet.svelte +0 -105
  37. package/src/lib/components/server-config-modal.svelte +0 -141
  38. package/src/lib/components/server-config-page.svelte +0 -130
  39. package/src/lib/components/sidebar.svelte +0 -144
  40. package/src/lib/components/status-bar.svelte +0 -40
  41. package/src/lib/pretty-json.test.ts +0 -200
  42. package/src/lib/pretty-json.ts +0 -79
  43. package/src/lib/time.ts +0 -38
  44. package/src/lib/zooid-uri.test.ts +0 -102
  45. package/src/lib/zooid-uri.ts +0 -74
  46. package/src/main.ts +0 -7
  47. package/src/vite-env.d.ts +0 -2
@@ -1,79 +0,0 @@
1
- import { marked } from 'marked';
2
-
3
- marked.setOptions({ breaks: true, gfm: true });
4
-
5
- export type PrettyNode =
6
- | {
7
- kind: 'text';
8
- key: string;
9
- value: string;
10
- markdown: boolean;
11
- multiline: boolean;
12
- }
13
- | { kind: 'ref'; key: string; value: string }
14
- | { kind: 'group'; key: string; children: PrettyNode[] }
15
- | { kind: 'list'; key: string; items: PrettyNode[][] };
16
-
17
- const MD_HINT = /[*_#\[`~>]|\n[-*] |\n\d+\. /;
18
-
19
- export function looksLikeMarkdown(s: string): boolean {
20
- return MD_HINT.test(s);
21
- }
22
-
23
- export function renderMarkdown(s: string): string {
24
- return marked.parse(s, { async: false }) as string;
25
- }
26
-
27
- export function parsePretty(raw: string): PrettyNode[] | null {
28
- try {
29
- const obj = JSON.parse(raw);
30
- if (typeof obj !== 'object' || obj === null || Array.isArray(obj))
31
- return null;
32
- return objectToNodes(obj);
33
- } catch {
34
- return null;
35
- }
36
- }
37
-
38
- export function objectToNodes(obj: Record<string, unknown>): PrettyNode[] {
39
- return Object.entries(obj).map(([key, value]) => {
40
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
41
- return {
42
- kind: 'group' as const,
43
- key,
44
- children: objectToNodes(value as Record<string, unknown>),
45
- };
46
- }
47
- if (Array.isArray(value) && value.length > 0) {
48
- return {
49
- kind: 'list' as const,
50
- key,
51
- items: value.map((item) =>
52
- typeof item === 'object' && item !== null && !Array.isArray(item)
53
- ? objectToNodes(item as Record<string, unknown>)
54
- : [
55
- {
56
- kind: 'text' as const,
57
- key: '',
58
- value: String(item),
59
- markdown: false,
60
- multiline: false,
61
- },
62
- ],
63
- ),
64
- };
65
- }
66
- const str = typeof value === 'string' ? value : JSON.stringify(value);
67
- if (key === 'ref' && typeof value === 'string') {
68
- return { kind: 'ref' as const, key, value: str };
69
- }
70
- const multiline = str.includes('\n');
71
- return {
72
- kind: 'text' as const,
73
- key,
74
- value: str,
75
- markdown: looksLikeMarkdown(str),
76
- multiline,
77
- };
78
- });
79
- }
package/src/lib/time.ts DELETED
@@ -1,38 +0,0 @@
1
- export function formatFull(iso: string): string {
2
- const hasOffset = /Z|[+-]\d{2}:?\d{2}$/.test(iso);
3
- const ts = hasOffset ? iso : iso + 'Z';
4
- return new Date(ts).toLocaleString();
5
- }
6
-
7
- const ULID_CHARS = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
8
-
9
- /** Extract millisecond timestamp from a ULID (first 10 chars encode 48-bit time). */
10
- export function ulidTimestamp(ulid: string): number {
11
- let time = 0;
12
- for (let i = 0; i < 10; i++) {
13
- time = time * 32 + ULID_CHARS.indexOf(ulid[i].toUpperCase());
14
- }
15
- return time;
16
- }
17
-
18
- export function formatRelative(iso: string): string {
19
- const hasOffset = /Z|[+-]\d{2}:?\d{2}$/.test(iso);
20
- const ts = hasOffset ? iso : iso + 'Z';
21
- return formatRelativeMs(new Date(ts).getTime());
22
- }
23
-
24
- export function formatRelativeUlid(ulid: string): string {
25
- return formatRelativeMs(ulidTimestamp(ulid));
26
- }
27
-
28
- function formatRelativeMs(ms: number): string {
29
- const diff = Date.now() - ms;
30
- const seconds = Math.floor(diff / 1000);
31
- if (seconds < 60) return `${seconds}s ago`;
32
- const minutes = Math.floor(seconds / 60);
33
- if (minutes < 60) return `${minutes}m ago`;
34
- const hours = Math.floor(minutes / 60);
35
- if (hours < 24) return `${hours}h ago`;
36
- const days = Math.floor(hours / 24);
37
- return `${days}d ago`;
38
- }
@@ -1,102 +0,0 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { parseZooidUri, resolveRef } from './zooid-uri';
3
-
4
- describe('parseZooidUri', () => {
5
- it('should parse same-server URI', () => {
6
- const result = parseZooidUri('zooid:signals/01HWXYZ123456789012345A');
7
- expect(result).toEqual({
8
- host: null,
9
- channel: 'signals',
10
- eventId: '01HWXYZ123456789012345A',
11
- });
12
- });
13
-
14
- it('should parse cross-server URI', () => {
15
- const result = parseZooidUri(
16
- 'zooid:ori.zoon.eco/signals/01HWXYZ123456789012345A',
17
- );
18
- expect(result).toEqual({
19
- host: 'ori.zoon.eco',
20
- channel: 'signals',
21
- eventId: '01HWXYZ123456789012345A',
22
- });
23
- });
24
-
25
- it('should distinguish host from channel by dot presence', () => {
26
- const withDot = parseZooidUri(
27
- 'zooid:my.server/chan/01HWXYZ123456789012345A',
28
- );
29
- expect(withDot?.host).toBe('my.server');
30
-
31
- const withoutDot = parseZooidUri(
32
- 'zooid:my-channel/01HWXYZ123456789012345A',
33
- );
34
- expect(withoutDot?.host).toBeNull();
35
- expect(withoutDot?.channel).toBe('my-channel');
36
- });
37
-
38
- it('should return null for invalid URIs', () => {
39
- expect(parseZooidUri('not-a-uri')).toBeNull();
40
- expect(parseZooidUri('zooid:')).toBeNull();
41
- expect(parseZooidUri('zooid:only-one-part')).toBeNull();
42
- expect(parseZooidUri('https://example.com')).toBeNull();
43
- });
44
- });
45
-
46
- describe('resolveRef', () => {
47
- const currentServer = 'https://demo.zoon.eco';
48
-
49
- it('should resolve zooid: same-server to in-app link', () => {
50
- const result = resolveRef(
51
- 'zooid:signals/01HWXYZ123456789012345A',
52
- currentServer,
53
- );
54
- expect(result).toEqual({
55
- type: 'zooid',
56
- label: 'signals/01HWXYZ123456789012345A',
57
- channel: 'signals',
58
- eventId: '01HWXYZ123456789012345A',
59
- href: null,
60
- });
61
- });
62
-
63
- it('should resolve zooid: cross-server to external link', () => {
64
- const result = resolveRef(
65
- 'zooid:ori.zoon.eco/signals/01HWXYZ123456789012345A',
66
- currentServer,
67
- );
68
- expect(result).toEqual({
69
- type: 'zooid-external',
70
- label: 'ori.zoon.eco/signals/01HWXYZ123456789012345A',
71
- channel: 'signals',
72
- eventId: '01HWXYZ123456789012345A',
73
- href: 'https://ori.zoon.eco/api/v1/channels/signals/events/01HWXYZ123456789012345A',
74
- });
75
- });
76
-
77
- it('should resolve https: as external link', () => {
78
- const result = resolveRef('https://example.com/docs', currentServer);
79
- expect(result).toEqual({
80
- type: 'external',
81
- label: 'https://example.com/docs',
82
- href: 'https://example.com/docs',
83
- });
84
- });
85
-
86
- it('should resolve http: as external link', () => {
87
- const result = resolveRef('http://localhost:8787/test', currentServer);
88
- expect(result).toEqual({
89
- type: 'external',
90
- label: 'http://localhost:8787/test',
91
- href: 'http://localhost:8787/test',
92
- });
93
- });
94
-
95
- it('should resolve unknown schemes as plain text', () => {
96
- const result = resolveRef('ftp://files.example.com', currentServer);
97
- expect(result).toEqual({
98
- type: 'text',
99
- label: 'ftp://files.example.com',
100
- });
101
- });
102
- });
@@ -1,74 +0,0 @@
1
- export interface ZooidUri {
2
- host: string | null;
3
- channel: string;
4
- eventId: string;
5
- }
6
-
7
- export type ResolvedRef =
8
- | {
9
- type: 'zooid';
10
- label: string;
11
- channel: string;
12
- eventId: string;
13
- href: null;
14
- }
15
- | {
16
- type: 'zooid-external';
17
- label: string;
18
- channel: string;
19
- eventId: string;
20
- href: string;
21
- }
22
- | { type: 'external'; label: string; href: string }
23
- | { type: 'text'; label: string };
24
-
25
- export function parseZooidUri(uri: string): ZooidUri | null {
26
- if (!uri.startsWith('zooid:')) return null;
27
-
28
- const path = uri.slice('zooid:'.length);
29
- if (!path) return null;
30
- const segments = path.split('/');
31
-
32
- if (segments.length === 2) {
33
- const [channel, eventId] = segments;
34
- if (!channel || !eventId) return null;
35
- return { host: null, channel, eventId };
36
- }
37
-
38
- if (segments.length === 3) {
39
- const [host, channel, eventId] = segments;
40
- if (!host || !channel || !eventId) return null;
41
- if (!host.includes('.')) return null;
42
- return { host, channel, eventId };
43
- }
44
-
45
- return null;
46
- }
47
-
48
- export function resolveRef(ref: string, currentServer: string): ResolvedRef {
49
- const zooid = parseZooidUri(ref);
50
- if (zooid) {
51
- if (zooid.host) {
52
- return {
53
- type: 'zooid-external',
54
- label: `${zooid.host}/${zooid.channel}/${zooid.eventId}`,
55
- channel: zooid.channel,
56
- eventId: zooid.eventId,
57
- href: `https://${zooid.host}/api/v1/channels/${zooid.channel}/events/${zooid.eventId}`,
58
- };
59
- }
60
- return {
61
- type: 'zooid',
62
- label: `${zooid.channel}/${zooid.eventId}`,
63
- channel: zooid.channel,
64
- eventId: zooid.eventId,
65
- href: null,
66
- };
67
- }
68
-
69
- if (ref.startsWith('https://') || ref.startsWith('http://')) {
70
- return { type: 'external', label: ref, href: ref };
71
- }
72
-
73
- return { type: 'text', label: ref };
74
- }
package/src/main.ts DELETED
@@ -1,7 +0,0 @@
1
- import './app.css';
2
- import App from './App.svelte';
3
- import { mount } from 'svelte';
4
-
5
- const app = mount(App, { target: document.getElementById('app')! });
6
-
7
- export default app;
package/src/vite-env.d.ts DELETED
@@ -1,2 +0,0 @@
1
- /// <reference types="svelte" />
2
- /// <reference types="vite/client" />