@myko/ui-svelte 4.2.0-canary.3

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 (31) hide show
  1. package/.prettierignore +4 -0
  2. package/.prettierrc +15 -0
  3. package/README.md +58 -0
  4. package/package.json +59 -0
  5. package/src/app.d.ts +13 -0
  6. package/src/app.html +12 -0
  7. package/src/lib/components/ConnectionStats.svelte +83 -0
  8. package/src/lib/components/Logs.svelte +37 -0
  9. package/src/lib/components/Query.svelte +34 -0
  10. package/src/lib/components/Report.svelte +25 -0
  11. package/src/lib/components/Search.svelte +85 -0
  12. package/src/lib/components/ServerView.svelte +95 -0
  13. package/src/lib/components/state/resolutions.ts +137 -0
  14. package/src/lib/components/state/viewstate.svelte.ts +375 -0
  15. package/src/lib/components/state/windback.svelte.ts +88 -0
  16. package/src/lib/components/transactions/EntityHistory.svelte +173 -0
  17. package/src/lib/components/transactions/TimeStrip.svelte +268 -0
  18. package/src/lib/components/transactions/TransactionDetails.svelte +26 -0
  19. package/src/lib/components/transactions/TransactionEvent.svelte +87 -0
  20. package/src/lib/components/transactions/TransactionEventGroup.svelte +56 -0
  21. package/src/lib/components/transactions/Transactions.svelte +111 -0
  22. package/src/lib/components/transactions/TransactonView.svelte +24 -0
  23. package/src/lib/components/windback/WindbackFrame.svelte +65 -0
  24. package/src/lib/components/windback/index.ts +1 -0
  25. package/src/lib/index.ts +26 -0
  26. package/src/lib/services/svelte-client.svelte.ts +863 -0
  27. package/src/routes/+page.svelte +3 -0
  28. package/static/favicon.png +0 -0
  29. package/svelte.config.js +18 -0
  30. package/tsconfig.json +13 -0
  31. package/vite.config.ts +6 -0
@@ -0,0 +1,4 @@
1
+ # Package Managers
2
+ package-lock.json
3
+ pnpm-lock.yaml
4
+ yarn.lock
package/.prettierrc ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "useTabs": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "none",
5
+ "printWidth": 100,
6
+ "plugins": ["prettier-plugin-svelte"],
7
+ "overrides": [
8
+ {
9
+ "files": "*.svelte",
10
+ "options": {
11
+ "parser": "svelte"
12
+ }
13
+ }
14
+ ]
15
+ }
package/README.md ADDED
@@ -0,0 +1,58 @@
1
+ # create-svelte
2
+
3
+ Everything you need to build a Svelte library, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte).
4
+
5
+ Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
+
7
+ ## Creating a project
8
+
9
+ If you're seeing this, you've probably already done this step. Congrats!
10
+
11
+ ```bash
12
+ # create a new project in the current directory
13
+ npx sv create
14
+
15
+ # create a new project in my-app
16
+ npx sv create my-app
17
+ ```
18
+
19
+ ## Developing
20
+
21
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
+
23
+ ```bash
24
+ npm run dev
25
+
26
+ # or start the server and open the app in a new browser tab
27
+ npm run dev -- --open
28
+ ```
29
+
30
+ Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
+
32
+ ## Building
33
+
34
+ To build your library:
35
+
36
+ ```bash
37
+ npm run package
38
+ ```
39
+
40
+ To create a production version of your showcase app:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ You can preview the production build with `npm run preview`.
47
+
48
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
+
50
+ ## Publishing
51
+
52
+ Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
+
54
+ To publish your library to [npm](https://www.npmjs.com):
55
+
56
+ ```bash
57
+ npm publish
58
+ ```
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "dependencies": {
3
+ "@myko/core": "workspace:*"
4
+ },
5
+ "devDependencies": {
6
+ "@sveltejs/adapter-auto": "^3.0.0",
7
+ "@sveltejs/kit": "^2.0.0",
8
+ "@sveltejs/package": "^2.0.0",
9
+ "@sveltejs/vite-plugin-svelte": "^4.0.0",
10
+ "@types/luxon": "^3.4.2",
11
+ "@types/ramda": "^0.30.2",
12
+ "chokidar-cli": "^3.0.0",
13
+ "luxon": "^3.5.0",
14
+ "prettier": "^3.3.2",
15
+ "prettier-plugin-svelte": "^3.2.6",
16
+ "publint": "^0.2.0",
17
+ "ramda": "^0.30.1",
18
+ "rxjs": "^7.8.1",
19
+ "svelte": "^5.17.5",
20
+ "svelte-check": "^4.0.0",
21
+ "svelte-inview": "^4.0.4",
22
+ "svelte-watch-resize": "^1.0.3",
23
+ "typescript": "^5.0.0",
24
+ "vite": "^5.0.11"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "default": "./src/lib/index.ts",
29
+ "svelte": "./src/lib/index.ts"
30
+ }
31
+ },
32
+ "flux": {
33
+ "tasks": [
34
+ "build",
35
+ "check",
36
+ "publish"
37
+ ]
38
+ },
39
+ "name": "@myko/ui-svelte",
40
+ "peerDependencies": {
41
+ "svelte": "^5.0.0"
42
+ },
43
+ "scripts": {
44
+ "build": "vite build && svelte-kit sync && svelte-package",
45
+ "build:watch": "vite build && svelte-kit sync && svelte-package && chokidar 'src/**/*.ts' 'src/**/*.svelte' -c 'vite build && svelte-kit sync && svelte-package'",
46
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
47
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
48
+ "dev": "vite dev",
49
+ "format": "prettier --write .",
50
+ "lint": "prettier --check .",
51
+ "package": "svelte-kit sync && svelte-package",
52
+ "preview": "vite preview"
53
+ },
54
+ "sideEffects": [
55
+ "**/*.css"
56
+ ],
57
+ "type": "module",
58
+ "version": "4.2.0-canary.3"
59
+ }
package/src/app.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ // See https://svelte.dev/docs/kit/types#app.d.ts
2
+ // for information about these interfaces
3
+ declare global {
4
+ namespace App {
5
+ // interface Error {}
6
+ // interface Locals {}
7
+ // interface PageData {}
8
+ // interface PageState {}
9
+ // interface Platform {}
10
+ }
11
+ }
12
+
13
+ export {};
package/src/app.html ADDED
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" href="%sveltekit.assets%/favicon.png" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ %sveltekit.head%
8
+ </head>
9
+ <body data-sveltekit-preload-data="hover">
10
+ <div>%sveltekit.body%</div>
11
+ </body>
12
+ </html>
@@ -0,0 +1,83 @@
1
+ <script lang="ts">
2
+ import { GetConnectedServer } from '@myko/core';
3
+ import { getMykoClient, type SvelteMykoClient } from '../services/svelte-client.svelte.js';
4
+
5
+ interface Props {
6
+ /** Optional client instance (defaults to global singleton) */
7
+ client?: SvelteMykoClient;
8
+ /** CSS class for the container */
9
+ class?: string;
10
+ }
11
+
12
+ let { client, class: className = '' }: Props = $props();
13
+
14
+ const resolvedClient = client ?? getMykoClient();
15
+
16
+ const stats = $derived(resolvedClient.stats);
17
+ const isConnected = $derived(resolvedClient.isConnected);
18
+
19
+ // Query for connected server
20
+ const serverQuery = resolvedClient.liveQuery(() => new GetConnectedServer({}));
21
+
22
+ const server = $derived([...serverQuery.items.values()][0]);
23
+ </script>
24
+
25
+ {#if isConnected && stats}
26
+ <div class="connection-stats {className}">
27
+ {#if server}
28
+ <span class="stat server" title="Connected server">
29
+ <span class="value">{server.address}:{server.port}</span>
30
+ </span>
31
+ <span class="stat version" title="Server version">
32
+ <span class="label">v</span>
33
+ <span class="value">{server.version}</span>
34
+ </span>
35
+ {/if}
36
+ <span class="stat ping" title="Round-trip latency">
37
+ <span class="label">Ping</span>
38
+ <span class="value">{stats.ping}ms</span>
39
+ </span>
40
+ <span class="stat down" title="Messages received per second">
41
+ <span class="label">Down</span>
42
+ <span class="value">{stats.mpsDown}/s</span>
43
+ </span>
44
+ <span class="stat up" title="Messages sent per second">
45
+ <span class="label">Up</span>
46
+ <span class="value">{stats.mpsUp}/s</span>
47
+ </span>
48
+ </div>
49
+ {:else}
50
+ <div class="connection-stats disconnected {className}">
51
+ <span class="stat">
52
+ <span class="value">--</span>
53
+ </span>
54
+ </div>
55
+ {/if}
56
+
57
+ <style>
58
+ .connection-stats {
59
+ display: inline-flex;
60
+ gap: 1rem;
61
+ font-size: 0.875rem;
62
+ font-family: monospace;
63
+ white-space: nowrap;
64
+ }
65
+
66
+ .stat {
67
+ display: flex;
68
+ gap: 0.25rem;
69
+ align-items: center;
70
+ }
71
+
72
+ .label {
73
+ opacity: 0.6;
74
+ }
75
+
76
+ .value {
77
+ font-weight: 500;
78
+ }
79
+
80
+ .disconnected {
81
+ opacity: 0.4;
82
+ }
83
+ </style>
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import { startWith } from 'rxjs';
3
+ import { myko as client } from '../services/svelte-client.svelte.js';
4
+ import { Loggers, type ID } from '@myko/core';
5
+
6
+ type Props = {
7
+ serverId: ID;
8
+ };
9
+
10
+ const { serverId }: Props = $props();
11
+
12
+ const logs = client.watchReport(new Loggers({})).pipe(startWith([]));
13
+ </script>
14
+
15
+ {#each $logs as log}
16
+ <div class="log">
17
+ <input type="checkbox" />
18
+ <span>
19
+ {log}
20
+ </span>
21
+ </div>
22
+ {/each}
23
+
24
+ <style>
25
+ .log {
26
+ display: flex;
27
+ align-items: center;
28
+ }
29
+
30
+ .log input {
31
+ margin-right: 0.5rem;
32
+ }
33
+
34
+ .log span {
35
+ flex: 1;
36
+ }
37
+ </style>
@@ -0,0 +1,34 @@
1
+ <script lang="ts" generics="Q extends Query<unknown>">
2
+ import type { Query, QueryItem } from '@myko/core';
3
+ import { getMykoClient, type SvelteMykoClient } from '../services/svelte-client.svelte.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ interface Props {
7
+ query: Q;
8
+ client?: SvelteMykoClient;
9
+ children: Snippet<[QueryItem<Q> & { id: string }]>;
10
+ empty?: Snippet;
11
+ loading?: Snippet;
12
+ }
13
+
14
+ let { query, client, children, empty, loading }: Props = $props();
15
+
16
+ const resolvedClient = client ?? getMykoClient();
17
+ const result = resolvedClient.liveQuery(() => query);
18
+ </script>
19
+
20
+ {#if result.items.size === 0}
21
+ {#if !result.resolved}
22
+ {#if loading}
23
+ {@render loading()}
24
+ {:else}
25
+ <span class="query-loading">Loading...</span>
26
+ {/if}
27
+ {:else if empty}
28
+ {@render empty()}
29
+ {/if}
30
+ {:else}
31
+ {#each result.items as [id, item] (id)}
32
+ {@render children(item)}
33
+ {/each}
34
+ {/if}
@@ -0,0 +1,25 @@
1
+ <script lang="ts" generics="R extends Report<unknown>">
2
+ import type { Report, ReportResult } from '@myko/core';
3
+ import { getMykoClient, type SvelteMykoClient } from '../services/svelte-client.svelte.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ interface Props {
7
+ report: R;
8
+ client?: SvelteMykoClient;
9
+ children: Snippet<[ReportResult<R>]>;
10
+ loading?: Snippet;
11
+ }
12
+
13
+ let { report, client, children, loading }: Props = $props();
14
+
15
+ const resolvedClient = client ?? getMykoClient();
16
+ const result = resolvedClient.liveReport(() => report);
17
+ </script>
18
+
19
+ {#if result.value === undefined}
20
+ {#if loading}
21
+ {@render loading()}
22
+ {/if}
23
+ {:else}
24
+ {@render children(result.value)}
25
+ {/if}
@@ -0,0 +1,85 @@
1
+ <script lang="ts" generics="T extends { id: string }">
2
+ import { EntitySearch, type Query } from '@myko/core';
3
+ import { getMykoClient, type SvelteMykoClient } from '../services/svelte-client.svelte.js';
4
+ import type { Snippet } from 'svelte';
5
+
6
+ interface Props {
7
+ /** Entity type to search (e.g., "Target", "Scene") */
8
+ entityType: string;
9
+ /** Search query string */
10
+ query: string;
11
+ /** Maximum number of results (default: 100) */
12
+ limit?: number;
13
+ /** Query factory to fetch items by IDs - receives array of matching IDs */
14
+ queryByIds: (ids: string[]) => Query<T>;
15
+ /** Query to use when search query is empty (shows all items) */
16
+ showAllOnEmpty?: Query<T>;
17
+ /** Optional client instance */
18
+ client?: SvelteMykoClient;
19
+ /** Render snippet for each result item */
20
+ children: Snippet<[T]>;
21
+ /** Render snippet when no results found */
22
+ empty?: Snippet;
23
+ /** Render snippet while loading */
24
+ loading?: Snippet;
25
+ }
26
+
27
+ let {
28
+ entityType,
29
+ query,
30
+ limit = 100,
31
+ queryByIds,
32
+ showAllOnEmpty,
33
+ client,
34
+ children,
35
+ empty,
36
+ loading
37
+ }: Props = $props();
38
+
39
+ const resolvedClient = client ?? getMykoClient();
40
+
41
+ // Subscribe to EntitySearch report when we have a query
42
+ const searchResult = resolvedClient.liveReport(() =>
43
+ query?.trim() ? new EntitySearch({ entityType, query, limit }) : null,
44
+ );
45
+
46
+ // Get the matching IDs from search result
47
+ const searchIds = $derived(searchResult.value?.ids ?? []);
48
+
49
+ // Subscribe to items - either by search IDs, showAllOnEmpty, or nothing
50
+ const itemsResult = resolvedClient.liveQuery(() => {
51
+ if (query?.trim()) {
52
+ // Have a search query - fetch by search result IDs
53
+ return searchIds.length > 0 ? queryByIds(searchIds) : null;
54
+ } else if (showAllOnEmpty) {
55
+ // Empty query with showAllOnEmpty - fetch all
56
+ return showAllOnEmpty;
57
+ }
58
+ return null;
59
+ });
60
+
61
+ // Derived loading state
62
+ const isLoading = $derived(
63
+ query?.trim()
64
+ ? !searchResult.value || (searchIds.length > 0 && !itemsResult.resolved)
65
+ : showAllOnEmpty
66
+ ? !itemsResult.resolved
67
+ : false,
68
+ );
69
+ </script>
70
+
71
+ {#if isLoading}
72
+ {#if loading}
73
+ {@render loading()}
74
+ {:else}
75
+ <span class="search-loading">Searching...</span>
76
+ {/if}
77
+ {:else if itemsResult.items.size === 0}
78
+ {#if empty}
79
+ {@render empty()}
80
+ {/if}
81
+ {:else}
82
+ {#each itemsResult.items as [id, item] (id)}
83
+ {@render children(item)}
84
+ {/each}
85
+ {/if}
@@ -0,0 +1,95 @@
1
+ <script lang="ts">
2
+ import {
3
+ LOG_RANK,
4
+ type LogLevel,
5
+ PeerAlive,
6
+ ServerLogLevel,
7
+ SetLogLevel,
8
+ type Server
9
+ } from '@myko/core';
10
+ import { DateTime } from 'luxon';
11
+ import { Observable, interval, switchMap } from 'rxjs';
12
+ import { onDestroy } from 'svelte';
13
+ import { myko as client } from '../services/svelte-client.svelte.js';
14
+
15
+ interface Props {
16
+ server: Server;
17
+ isClientServer?: boolean;
18
+ }
19
+
20
+ let { server, isClientServer = false }: Props = $props();
21
+
22
+ let alive = $derived(
23
+ isClientServer
24
+ ? (interval(500).pipe(switchMap(() => client.ping().catch((e) => false))) as Observable<
25
+ number | false
26
+ >)
27
+ : client.watchReport(new PeerAlive({ peerId: server.id }))
28
+ );
29
+
30
+ let ping = $derived.by(() => {
31
+ const value = $alive;
32
+ if (value === undefined) return 'Connecting';
33
+ if (value === false) return 'Dead';
34
+ if (!Number.isFinite(value) || value < 0) return 'Unknown';
35
+ return `${Math.round(value)}ms`;
36
+ });
37
+
38
+ let started = $state(DateTime.fromISO(server.startedAt).toRelative());
39
+
40
+ let startedInterbal = setInterval(() => {
41
+ started = DateTime.fromISO(server.startedAt).toRelative();
42
+ }, 1000);
43
+
44
+ onDestroy(() => {
45
+ clearInterval(startedInterbal);
46
+ });
47
+
48
+ const currentLogLevel = $derived(client.watchReport(new ServerLogLevel({ serverId: server.id })));
49
+ </script>
50
+
51
+ <div class="server flex gap-5">
52
+ <div class="info">
53
+ <span class="address">{server.address}:{server.port}</span>
54
+ <span class="version">{server.version}</span>
55
+ <span class="id">ID: {server.id}</span>
56
+ <span class="started">Started: {started}</span>
57
+ <span>Ping {isClientServer ? '' : 'to connected'}: {ping}</span>
58
+ <select
59
+ aria-label="Log Level"
60
+ class="select"
61
+ onchange={(e) => {
62
+ console.log(e.currentTarget.value);
63
+ client.sendCommand(
64
+ new SetLogLevel({
65
+ serverId: server.id,
66
+ level: e.currentTarget.value as LogLevel
67
+ })
68
+ );
69
+ }}
70
+ >
71
+ {#each LOG_RANK as rank}
72
+ <option selected={rank === $currentLogLevel} value={rank}>{rank}</option>
73
+ {/each}
74
+ </select>
75
+ </div>
76
+ </div>
77
+
78
+ <style>
79
+ .server {
80
+ position: relative;
81
+ }
82
+
83
+ span {
84
+ display: block;
85
+ white-space: nowrap;
86
+ }
87
+
88
+ .version {
89
+ opacity: 0.5;
90
+ }
91
+
92
+ .id {
93
+ white-space: nowrap;
94
+ }
95
+ </style>
@@ -0,0 +1,137 @@
1
+ import { Duration } from 'luxon';
2
+
3
+ export type Resolution = {
4
+ milis: number;
5
+ majorFormat: string;
6
+ minorFormat: string;
7
+ };
8
+
9
+ export const resolutions = [
10
+ {
11
+ label: '1ms',
12
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
13
+ minorFormat: '.SSS',
14
+ milis: Duration.fromObject({ milliseconds: 1 }).as('milliseconds')
15
+ },
16
+ {
17
+ label: '5ms',
18
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
19
+ minorFormat: '.SSS',
20
+ milis: Duration.fromObject({ milliseconds: 5 }).as('milliseconds')
21
+ },
22
+ {
23
+ label: '10ms',
24
+ minorFormat: '.SSS',
25
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
26
+ milis: Duration.fromObject({ milliseconds: 10 }).as('milliseconds')
27
+ },
28
+ {
29
+ label: '50ms',
30
+ minorFormat: '.SSS',
31
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
32
+ milis: Duration.fromObject({ milliseconds: 50 }).as('milliseconds')
33
+ },
34
+ {
35
+ label: '100ms',
36
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
37
+ minorFormat: '.SSS',
38
+
39
+ milis: Duration.fromObject({ milliseconds: 100 }).as('milliseconds')
40
+ },
41
+ {
42
+ label: '500ms',
43
+ majorFormat: 'dd MMM HH:mm:ss.SSS',
44
+ minorFormat: '.SSS',
45
+ milis: Duration.fromObject({ milliseconds: 500 }).as('milliseconds')
46
+ },
47
+ {
48
+ label: '1s',
49
+ majorFormat: 'dd MMM HH:mm:ss',
50
+ minorFormat: 'ss',
51
+ milis: Duration.fromObject({ seconds: 1 }).as('milliseconds')
52
+ },
53
+ {
54
+ label: '5s',
55
+ majorFormat: 'dd MMM HH:mm:ss',
56
+ minorFormat: 'ss',
57
+ milis: Duration.fromObject({ seconds: 5 }).as('milliseconds')
58
+ },
59
+ {
60
+ label: '10s',
61
+ majorFormat: 'dd MMM HH:mm:ss',
62
+ minorFormat: 'ss',
63
+ milis: Duration.fromObject({ seconds: 10 }).as('milliseconds')
64
+ },
65
+ {
66
+ label: '30s',
67
+ majorFormat: 'dd MMM HH:mm:ss',
68
+ minorFormat: 'ss',
69
+ milis: Duration.fromObject({ seconds: 30 }).as('milliseconds')
70
+ },
71
+ {
72
+ label: '1m',
73
+ majorFormat: 'dd MMM HH:mm:ss',
74
+ minorFormat: 'mm:ss',
75
+ milis: Duration.fromObject({ minutes: 1 }).as('milliseconds')
76
+ },
77
+ {
78
+ label: '5m',
79
+ majorFormat: 'dd MMM HH:mm:ss',
80
+ minorFormat: 'mm:ss',
81
+ milis: Duration.fromObject({ minutes: 5 }).as('milliseconds')
82
+ },
83
+ {
84
+ label: '10m',
85
+ majorFormat: 'dd MMM HH:mm:ss',
86
+ minorFormat: 'mm:ss',
87
+ milis: Duration.fromObject({ minutes: 10 }).as('milliseconds')
88
+ },
89
+ {
90
+ label: '30m',
91
+ majorFormat: 'dd MMM HH:mm:ss',
92
+ minorFormat: 'mm:ss',
93
+ milis: Duration.fromObject({ minutes: 30 }).as('milliseconds')
94
+ },
95
+ {
96
+ label: '1h',
97
+ majorFormat: 'dd MMM HH:mm:ss',
98
+ minorFormat: 'HH:mm',
99
+ milis: Duration.fromObject({ hours: 1 }).as('milliseconds')
100
+ },
101
+ {
102
+ label: '6h',
103
+ majorFormat: 'dd MMM HH:mm:ss',
104
+ minorFormat: 'HH:mm',
105
+ milis: Duration.fromObject({ hours: 6 }).as('milliseconds')
106
+ },
107
+ {
108
+ label: '12h',
109
+ majorFormat: 'dd MMM',
110
+ minorFormat: 'HH:mm',
111
+ milis: Duration.fromObject({ hours: 12 }).as('milliseconds')
112
+ },
113
+ {
114
+ label: '1d',
115
+ majorFormat: 'dd MMM',
116
+ minorFormat: 'dd',
117
+ milis: Duration.fromObject({ days: 1 }).as('milliseconds')
118
+ },
119
+ {
120
+ label: '1w',
121
+ majorFormat: 'dd MMM yyyy',
122
+ minorFormat: 'dd',
123
+ milis: Duration.fromObject({ weeks: 1 }).as('milliseconds')
124
+ },
125
+ {
126
+ label: '1M',
127
+ majorFormat: 'MMM yyyy',
128
+ minorFormat: 'MMM',
129
+ milis: Duration.fromObject({ months: 1 }).as('milliseconds')
130
+ },
131
+ {
132
+ label: '1y',
133
+ majorFormat: 'yyyy',
134
+ minorFormat: 'yyyy',
135
+ milis: Duration.fromObject({ years: 1 }).as('milliseconds')
136
+ }
137
+ ];