@tldraw/editor 3.16.0-canary.39bd199a7aa6 → 3.16.0-canary.3c51fb02c6a5
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/dist-cjs/index.d.ts +24 -0
- package/dist-cjs/index.js +1 -1
- package/dist-cjs/lib/TldrawEditor.js +6 -2
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/MenuClickCapture.js +0 -5
- package/dist-cjs/lib/components/MenuClickCapture.js.map +2 -2
- package/dist-cjs/lib/components/Shape.js +7 -10
- package/dist-cjs/lib/components/Shape.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +2 -21
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultErrorFallback.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +1 -1
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +2 -2
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +9 -1
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +2 -2
- package/dist-cjs/lib/config/TLUserPreferences.js +9 -3
- package/dist-cjs/lib/config/TLUserPreferences.js.map +2 -2
- package/dist-cjs/lib/editor/Editor.js +44 -15
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js +9 -4
- package/dist-cjs/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.js.map +2 -2
- package/dist-cjs/lib/exports/getSvgJsx.js +1 -2
- package/dist-cjs/lib/exports/getSvgJsx.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +24 -20
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js +4 -1
- package/dist-cjs/lib/hooks/usePassThroughWheelEvents.js.map +2 -2
- package/dist-cjs/lib/license/Watermark.js +6 -6
- package/dist-cjs/lib/license/Watermark.js.map +1 -1
- package/dist-cjs/lib/options.js +7 -0
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/version.js +3 -3
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +24 -0
- package/dist-esm/index.mjs +1 -1
- package/dist-esm/lib/TldrawEditor.mjs +6 -2
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/MenuClickCapture.mjs +0 -5
- package/dist-esm/lib/components/MenuClickCapture.mjs.map +2 -2
- package/dist-esm/lib/components/Shape.mjs +7 -10
- package/dist-esm/lib/components/Shape.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +2 -21
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultErrorFallback.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +1 -1
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +9 -1
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +2 -2
- package/dist-esm/lib/config/TLUserPreferences.mjs +9 -3
- package/dist-esm/lib/config/TLUserPreferences.mjs.map +2 -2
- package/dist-esm/lib/editor/Editor.mjs +44 -15
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs +9 -4
- package/dist-esm/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.mjs.map +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs +2 -2
- package/dist-esm/lib/exports/getSvgJsx.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +25 -21
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs +4 -1
- package/dist-esm/lib/hooks/usePassThroughWheelEvents.mjs.map +2 -2
- package/dist-esm/lib/license/Watermark.mjs +6 -6
- package/dist-esm/lib/license/Watermark.mjs.map +1 -1
- package/dist-esm/lib/options.mjs +7 -0
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/version.mjs +3 -3
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +293 -288
- package/package.json +14 -37
- package/src/lib/TldrawEditor.tsx +11 -6
- package/src/lib/components/MenuClickCapture.tsx +0 -8
- package/src/lib/components/Shape.tsx +6 -12
- package/src/lib/components/default-components/DefaultCanvas.tsx +2 -21
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +1 -1
- package/src/lib/components/default-components/DefaultErrorFallback.tsx +1 -1
- package/src/lib/components/default-components/DefaultScribble.tsx +1 -1
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +5 -1
- package/src/lib/config/TLUserPreferences.ts +8 -1
- package/src/lib/editor/Editor.test.ts +12 -11
- package/src/lib/editor/Editor.ts +55 -20
- package/src/lib/editor/managers/ClickManager/ClickManager.test.ts +15 -14
- package/src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.test.ts +16 -15
- package/src/lib/editor/managers/FocusManager/FocusManager.test.ts +49 -48
- package/src/lib/editor/managers/FontManager/FontManager.test.ts +24 -23
- package/src/lib/editor/managers/HistoryManager/HistoryManager.test.ts +7 -6
- package/src/lib/editor/managers/ScribbleManager/ScribbleManager.test.ts +12 -11
- package/src/lib/editor/managers/SnapManager/SnapManager.test.ts +57 -50
- package/src/lib/editor/managers/TextManager/TextManager.test.ts +51 -26
- package/src/lib/editor/managers/TickManager/TickManager.test.ts +14 -13
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.test.ts +34 -26
- package/src/lib/editor/managers/UserPreferencesManager/UserPreferencesManager.ts +6 -1
- package/src/lib/exports/getSvgJsx.tsx +2 -2
- package/src/lib/hooks/useCanvasEvents.ts +39 -32
- package/src/lib/hooks/usePassThroughWheelEvents.ts +6 -1
- package/src/lib/license/LicenseManager.test.ts +3 -1
- package/src/lib/license/Watermark.test.tsx +2 -1
- package/src/lib/license/Watermark.tsx +6 -6
- package/src/lib/options.ts +8 -0
- package/src/lib/utils/sync/LocalIndexedDb.test.ts +2 -1
- package/src/lib/utils/sync/TLLocalSyncClient.test.ts +15 -15
- package/src/version.ts +3 -3
- package/dist-cjs/lib/utils/nearestMultiple.js +0 -34
- package/dist-cjs/lib/utils/nearestMultiple.js.map +0 -7
- package/dist-esm/lib/utils/nearestMultiple.mjs +0 -14
- package/dist-esm/lib/utils/nearestMultiple.mjs.map +0 -7
- package/src/lib/utils/nearestMultiple.ts +0 -13
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useValue } from '@tldraw/state-react'
|
|
2
|
-
import React, { useMemo } from 'react'
|
|
2
|
+
import React, { useEffect, useMemo } from 'react'
|
|
3
3
|
import { RIGHT_MOUSE_BUTTON } from '../constants'
|
|
4
4
|
import {
|
|
5
5
|
preventDefault,
|
|
@@ -16,9 +16,6 @@ export function useCanvasEvents() {
|
|
|
16
16
|
|
|
17
17
|
const events = useMemo(
|
|
18
18
|
function canvasEvents() {
|
|
19
|
-
// Track the last screen point
|
|
20
|
-
let lastX: number, lastY: number
|
|
21
|
-
|
|
22
19
|
function onPointerDown(e: React.PointerEvent) {
|
|
23
20
|
if ((e as any).isKilled) return
|
|
24
21
|
|
|
@@ -44,35 +41,9 @@ export function useCanvasEvents() {
|
|
|
44
41
|
})
|
|
45
42
|
}
|
|
46
43
|
|
|
47
|
-
function onPointerMove(e: React.PointerEvent) {
|
|
48
|
-
if ((e as any).isKilled) return
|
|
49
|
-
|
|
50
|
-
if (e.clientX === lastX && e.clientY === lastY) return
|
|
51
|
-
lastX = e.clientX
|
|
52
|
-
lastY = e.clientY
|
|
53
|
-
|
|
54
|
-
// For tools that benefit from a higher fidelity of events,
|
|
55
|
-
// we dispatch the coalesced events.
|
|
56
|
-
// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
|
|
57
|
-
const events =
|
|
58
|
-
currentTool.useCoalescedEvents && e.nativeEvent.getCoalescedEvents
|
|
59
|
-
? e.nativeEvent.getCoalescedEvents()
|
|
60
|
-
: [e]
|
|
61
|
-
for (const singleEvent of events) {
|
|
62
|
-
editor.dispatch({
|
|
63
|
-
type: 'pointer',
|
|
64
|
-
target: 'canvas',
|
|
65
|
-
name: 'pointer_move',
|
|
66
|
-
...getPointerInfo(singleEvent),
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
44
|
function onPointerUp(e: React.PointerEvent) {
|
|
72
45
|
if ((e as any).isKilled) return
|
|
73
46
|
if (e.button !== 0 && e.button !== 1 && e.button !== 2 && e.button !== 5) return
|
|
74
|
-
lastX = e.clientX
|
|
75
|
-
lastY = e.clientY
|
|
76
47
|
|
|
77
48
|
releasePointerCapture(e.currentTarget, e)
|
|
78
49
|
|
|
@@ -158,7 +129,6 @@ export function useCanvasEvents() {
|
|
|
158
129
|
|
|
159
130
|
return {
|
|
160
131
|
onPointerDown,
|
|
161
|
-
onPointerMove,
|
|
162
132
|
onPointerUp,
|
|
163
133
|
onPointerEnter,
|
|
164
134
|
onPointerLeave,
|
|
@@ -169,8 +139,45 @@ export function useCanvasEvents() {
|
|
|
169
139
|
onClick,
|
|
170
140
|
}
|
|
171
141
|
},
|
|
172
|
-
[editor
|
|
142
|
+
[editor]
|
|
173
143
|
)
|
|
174
144
|
|
|
145
|
+
// onPointerMove is special: where we're only interested in the other events when they're
|
|
146
|
+
// happening _on_ the canvas (as opposed to outside of it, or on UI floating over it), we want
|
|
147
|
+
// the pointer position to be up to date regardless of whether it's over the tldraw canvas or
|
|
148
|
+
// not. So instead of returning a listener to be attached to the canvas, we directly attach a
|
|
149
|
+
// listener to the whole document instead.
|
|
150
|
+
useEffect(() => {
|
|
151
|
+
let lastX: number, lastY: number
|
|
152
|
+
|
|
153
|
+
function onPointerMove(e: PointerEvent) {
|
|
154
|
+
if ((e as any).isKilled) return
|
|
155
|
+
;(e as any).isKilled = true
|
|
156
|
+
|
|
157
|
+
if (e.clientX === lastX && e.clientY === lastY) return
|
|
158
|
+
lastX = e.clientX
|
|
159
|
+
lastY = e.clientY
|
|
160
|
+
|
|
161
|
+
// For tools that benefit from a higher fidelity of events,
|
|
162
|
+
// we dispatch the coalesced events.
|
|
163
|
+
// N.B. Sometimes getCoalescedEvents isn't present on iOS, ugh.
|
|
164
|
+
const events =
|
|
165
|
+
currentTool.useCoalescedEvents && e.getCoalescedEvents ? e.getCoalescedEvents() : [e]
|
|
166
|
+
for (const singleEvent of events) {
|
|
167
|
+
editor.dispatch({
|
|
168
|
+
type: 'pointer',
|
|
169
|
+
target: 'canvas',
|
|
170
|
+
name: 'pointer_move',
|
|
171
|
+
...getPointerInfo(singleEvent),
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
document.body.addEventListener('pointermove', onPointerMove)
|
|
177
|
+
return () => {
|
|
178
|
+
document.body.removeEventListener('pointermove', onPointerMove)
|
|
179
|
+
}
|
|
180
|
+
}, [editor, currentTool])
|
|
181
|
+
|
|
175
182
|
return events
|
|
176
183
|
}
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { RefObject, useEffect } from 'react'
|
|
2
2
|
import { preventDefault } from '../utils/dom'
|
|
3
3
|
import { useContainer } from './useContainer'
|
|
4
|
+
import { useMaybeEditor } from './useEditor'
|
|
4
5
|
|
|
5
6
|
/** @public */
|
|
6
7
|
export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
|
|
7
8
|
if (!ref) throw Error('usePassThroughWheelEvents must be passed a ref')
|
|
8
9
|
const container = useContainer()
|
|
10
|
+
const editor = useMaybeEditor()
|
|
9
11
|
|
|
10
12
|
useEffect(() => {
|
|
11
13
|
function onWheel(e: WheelEvent) {
|
|
14
|
+
// Only pass through wheel events if the editor is focused
|
|
15
|
+
if (!editor?.getInstanceState().isFocused) return
|
|
16
|
+
|
|
12
17
|
if ((e as any).isSpecialRedispatchedEvent) return
|
|
13
18
|
|
|
14
19
|
// if the element is scrollable, don't redispatch the event
|
|
@@ -32,5 +37,5 @@ export function usePassThroughWheelEvents(ref: RefObject<HTMLElement>) {
|
|
|
32
37
|
return () => {
|
|
33
38
|
elm.removeEventListener('wheel', onWheel)
|
|
34
39
|
}
|
|
35
|
-
}, [container, ref])
|
|
40
|
+
}, [container, editor, ref])
|
|
36
41
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import crypto from 'crypto'
|
|
2
|
+
import { vi } from 'vitest'
|
|
2
3
|
import { publishDates } from '../../version'
|
|
3
4
|
import { str2ab } from '../utils/licensing'
|
|
4
5
|
import {
|
|
@@ -9,8 +10,9 @@ import {
|
|
|
9
10
|
ValidLicenseKeyResult,
|
|
10
11
|
} from './LicenseManager'
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
vi.mock('../../version', () => {
|
|
13
14
|
return {
|
|
15
|
+
version: '3.15.1',
|
|
14
16
|
publishDates: {
|
|
15
17
|
major: '2024-06-28T10:56:07.893Z',
|
|
16
18
|
minor: '2024-07-02T16:49:50.397Z',
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { act, render, waitFor } from '@testing-library/react'
|
|
2
|
+
import { vi } from 'vitest'
|
|
2
3
|
import { TldrawEditor } from '../TldrawEditor'
|
|
3
4
|
import { LicenseManager } from './LicenseManager'
|
|
4
5
|
|
|
5
6
|
let mockLicenseState = 'unlicensed'
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
vi.mock('./useLicenseManagerState', () => ({
|
|
8
9
|
useLicenseManagerState: () => mockLicenseState,
|
|
9
10
|
}))
|
|
10
11
|
|
|
@@ -86,15 +86,15 @@ To remove the watermark, please purchase a license at tldraw.dev.
|
|
|
86
86
|
|
|
87
87
|
.${className} {
|
|
88
88
|
position: absolute;
|
|
89
|
-
bottom: var(--space-2);
|
|
90
|
-
right: var(--space-2);
|
|
89
|
+
bottom: var(--tl-space-2);
|
|
90
|
+
right: var(--tl-space-2);
|
|
91
91
|
width: 96px;
|
|
92
92
|
height: 32px;
|
|
93
93
|
display: flex;
|
|
94
94
|
align-items: center;
|
|
95
95
|
justify-content: center;
|
|
96
|
-
z-index: var(--layer-watermark) !important;
|
|
97
|
-
background-color: color-mix(in srgb, var(--color-background) 62%, transparent);
|
|
96
|
+
z-index: var(--tl-layer-watermark) !important;
|
|
97
|
+
background-color: color-mix(in srgb, var(--tl-color-background) 62%, transparent);
|
|
98
98
|
opacity: 1;
|
|
99
99
|
border-radius: 5px;
|
|
100
100
|
pointer-events: all;
|
|
@@ -108,7 +108,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
|
|
|
108
108
|
height: 32px;
|
|
109
109
|
pointer-events: all;
|
|
110
110
|
cursor: inherit;
|
|
111
|
-
color: var(--color-text);
|
|
111
|
+
color: var(--tl-color-text);
|
|
112
112
|
opacity: .38;
|
|
113
113
|
border: 0;
|
|
114
114
|
padding: 0;
|
|
@@ -137,7 +137,7 @@ To remove the watermark, please purchase a license at tldraw.dev.
|
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
.${className}:hover {
|
|
140
|
-
background-color: var(--color-background);
|
|
140
|
+
background-color: var(--tl-color-background);
|
|
141
141
|
transition: background-color 0.2s ease-in-out;
|
|
142
142
|
transition-delay: 0.32s;
|
|
143
143
|
}
|
package/src/lib/options.ts
CHANGED
|
@@ -27,6 +27,8 @@ export interface TldrawOptions {
|
|
|
27
27
|
readonly multiClickDurationMs: number
|
|
28
28
|
readonly coarseDragDistanceSquared: number
|
|
29
29
|
readonly dragDistanceSquared: number
|
|
30
|
+
readonly uiDragDistanceSquared: number
|
|
31
|
+
readonly uiCoarseDragDistanceSquared: number
|
|
30
32
|
readonly defaultSvgPadding: number
|
|
31
33
|
readonly cameraSlideFriction: number
|
|
32
34
|
readonly gridSteps: readonly {
|
|
@@ -53,6 +55,7 @@ export interface TldrawOptions {
|
|
|
53
55
|
readonly flattenImageBoundsPadding: number
|
|
54
56
|
readonly laserDelayMs: number
|
|
55
57
|
readonly maxExportDelayMs: number
|
|
58
|
+
readonly tooltipDelayMs: number
|
|
56
59
|
/**
|
|
57
60
|
* How long should previews created by {@link Editor.createTemporaryAssetPreview} last before
|
|
58
61
|
* they expire? Defaults to 3 minutes.
|
|
@@ -97,6 +100,10 @@ export const defaultTldrawOptions = {
|
|
|
97
100
|
multiClickDurationMs: 200,
|
|
98
101
|
coarseDragDistanceSquared: 36, // 6 squared
|
|
99
102
|
dragDistanceSquared: 16, // 4 squared
|
|
103
|
+
uiDragDistanceSquared: 16, // 4 squared
|
|
104
|
+
// it's really easy to accidentally drag from the toolbar on mobile, so we use a much larger
|
|
105
|
+
// threshold than usual here to try and prevent accidental drags.
|
|
106
|
+
uiCoarseDragDistanceSquared: 625, // 25 squared
|
|
100
107
|
defaultSvgPadding: 32,
|
|
101
108
|
cameraSlideFriction: 0.09,
|
|
102
109
|
gridSteps: [
|
|
@@ -124,6 +131,7 @@ export const defaultTldrawOptions = {
|
|
|
124
131
|
flattenImageBoundsPadding: 16,
|
|
125
132
|
laserDelayMs: 1200,
|
|
126
133
|
maxExportDelayMs: 5000,
|
|
134
|
+
tooltipDelayMs: 700,
|
|
127
135
|
temporaryAssetPreviewLifetimeMs: 180000,
|
|
128
136
|
actionShortcutsLocation: 'swap',
|
|
129
137
|
createTextOnCanvasDoubleClick: true,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createTLSchema } from '@tldraw/tlschema'
|
|
2
2
|
import { openDB } from 'idb'
|
|
3
|
+
import { vi } from 'vitest'
|
|
3
4
|
import { hardReset } from './hardReset'
|
|
4
5
|
import { getAllIndexDbNames, LocalIndexedDb } from './LocalIndexedDb'
|
|
5
6
|
|
|
6
7
|
const schema = createTLSchema({ shapes: {}, bindings: {} })
|
|
7
8
|
describe('LocalIndexedDb', () => {
|
|
8
9
|
beforeEach(() => {
|
|
9
|
-
|
|
10
|
+
vi.useRealTimers()
|
|
10
11
|
})
|
|
11
12
|
afterEach(async () => {
|
|
12
13
|
await hardReset({ shouldReload: false })
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PageRecordType } from '@tldraw/tlschema'
|
|
2
2
|
import { IndexKey, promiseWithResolve } from '@tldraw/utils'
|
|
3
|
-
import {
|
|
3
|
+
import { Mock, vi } from 'vitest'
|
|
4
4
|
import { createTLStore } from '../../config/createTLStore'
|
|
5
5
|
import { TLLocalSyncClient } from './TLLocalSyncClient'
|
|
6
6
|
import { hardReset } from './hardReset'
|
|
@@ -10,20 +10,20 @@ class BroadcastChannelMock {
|
|
|
10
10
|
constructor(_name: string) {
|
|
11
11
|
// noop
|
|
12
12
|
}
|
|
13
|
-
postMessage =
|
|
13
|
+
postMessage = vi.fn((_msg: any) => {
|
|
14
14
|
// noop
|
|
15
15
|
})
|
|
16
|
-
close =
|
|
16
|
+
close = vi.fn(() => {
|
|
17
17
|
// noop
|
|
18
18
|
})
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function testClient(channel = new BroadcastChannelMock('test')) {
|
|
22
22
|
const store = createTLStore({ shapeUtils: [], bindingUtils: [] })
|
|
23
|
-
const onLoad =
|
|
23
|
+
const onLoad = vi.fn(() => {
|
|
24
24
|
return
|
|
25
25
|
})
|
|
26
|
-
const onLoadError =
|
|
26
|
+
const onLoadError = vi.fn(() => {
|
|
27
27
|
return
|
|
28
28
|
})
|
|
29
29
|
const client = new TLLocalSyncClient(
|
|
@@ -36,26 +36,26 @@ function testClient(channel = new BroadcastChannelMock('test')) {
|
|
|
36
36
|
channel
|
|
37
37
|
)
|
|
38
38
|
|
|
39
|
-
client.db.storeSnapshot =
|
|
40
|
-
client.db.storeChanges =
|
|
39
|
+
client.db.storeSnapshot = vi.fn(() => Promise.resolve())
|
|
40
|
+
client.db.storeChanges = vi.fn(() => Promise.resolve())
|
|
41
41
|
|
|
42
42
|
return {
|
|
43
|
-
client: client as { db: { storeSnapshot:
|
|
43
|
+
client: client as { db: { storeSnapshot: Mock; storeChanges: Mock } } & typeof client,
|
|
44
44
|
store,
|
|
45
45
|
onLoad,
|
|
46
46
|
onLoadError,
|
|
47
47
|
channel,
|
|
48
48
|
tick: async () => {
|
|
49
|
-
|
|
49
|
+
vi.advanceTimersByTime(500)
|
|
50
50
|
await Promise.resolve()
|
|
51
51
|
await client.db.pending()
|
|
52
|
-
|
|
52
|
+
vi.advanceTimersByTime(500)
|
|
53
53
|
await Promise.resolve()
|
|
54
54
|
},
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
const reloadMock =
|
|
58
|
+
const reloadMock = vi.fn()
|
|
59
59
|
|
|
60
60
|
beforeAll(() => {
|
|
61
61
|
Object.defineProperty(window, 'location', {
|
|
@@ -65,14 +65,14 @@ beforeAll(() => {
|
|
|
65
65
|
})
|
|
66
66
|
|
|
67
67
|
beforeEach(() => {
|
|
68
|
-
|
|
68
|
+
vi.clearAllMocks()
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
afterEach(async () => {
|
|
72
72
|
await hardReset({ shouldReload: false })
|
|
73
73
|
})
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
vi.useFakeTimers()
|
|
76
76
|
|
|
77
77
|
test('the client connects on instantiation, announcing its schema', async () => {
|
|
78
78
|
const { channel, tick } = testClient()
|
|
@@ -86,7 +86,7 @@ test('the client connects on instantiation, announcing its schema', async () =>
|
|
|
86
86
|
test('when a client receives an announce with a newer schema version it reloads itself', async () => {
|
|
87
87
|
const { client, channel, onLoadError, tick } = testClient()
|
|
88
88
|
await tick()
|
|
89
|
-
|
|
89
|
+
vi.advanceTimersByTime(10000)
|
|
90
90
|
expect(reloadMock).not.toHaveBeenCalled()
|
|
91
91
|
channel.onmessage?.({
|
|
92
92
|
data: {
|
|
@@ -104,7 +104,7 @@ test('when a client receives an announce with a newer schema version it reloads
|
|
|
104
104
|
test('when a client receives an announce with a newer schema version shortly after loading it does not reload but instead reports a loadError', async () => {
|
|
105
105
|
const { client, channel, onLoadError, tick } = testClient()
|
|
106
106
|
await tick()
|
|
107
|
-
|
|
107
|
+
vi.advanceTimersByTime(1000)
|
|
108
108
|
expect(reloadMock).not.toHaveBeenCalled()
|
|
109
109
|
channel.onmessage?.({
|
|
110
110
|
data: {
|
package/src/version.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// This file is automatically generated by internal/scripts/refresh-assets.ts.
|
|
2
2
|
// Do not edit manually. Or do, I'm a comment, not a cop.
|
|
3
3
|
|
|
4
|
-
export const version = '3.16.0-canary.
|
|
4
|
+
export const version = '3.16.0-canary.3c51fb02c6a5'
|
|
5
5
|
export const publishDates = {
|
|
6
6
|
major: '2024-09-13T14:36:29.063Z',
|
|
7
|
-
minor: '2025-08-
|
|
8
|
-
patch: '2025-08-
|
|
7
|
+
minor: '2025-08-25T12:12:01.278Z',
|
|
8
|
+
patch: '2025-08-25T12:12:01.278Z',
|
|
9
9
|
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var nearestMultiple_exports = {};
|
|
20
|
-
__export(nearestMultiple_exports, {
|
|
21
|
-
nearestMultiple: () => nearestMultiple
|
|
22
|
-
});
|
|
23
|
-
module.exports = __toCommonJS(nearestMultiple_exports);
|
|
24
|
-
function gcd(a, b) {
|
|
25
|
-
return b === 0 ? a : gcd(b, a % b);
|
|
26
|
-
}
|
|
27
|
-
function nearestMultiple(float) {
|
|
28
|
-
const decimal = float.toString().split(".")[1];
|
|
29
|
-
if (!decimal) return 1;
|
|
30
|
-
const denominator = Math.pow(10, decimal.length);
|
|
31
|
-
const numerator = parseInt(decimal, 10);
|
|
32
|
-
return denominator / gcd(numerator, denominator);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=nearestMultiple.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/lib/utils/nearestMultiple.ts"],
|
|
4
|
-
"sourcesContent": ["// Euclidean algorithm to find the GCD\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n// Returns the lowest value that the given number can be multiplied by to reach an integer\nexport function nearestMultiple(float: number) {\n\tconst decimal = float.toString().split('.')[1]\n\tif (!decimal) return 1\n\tconst denominator = Math.pow(10, decimal.length)\n\tconst numerator = parseInt(decimal, 10)\n\treturn denominator / gcd(numerator, denominator)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,SAAS,IAAI,GAAW,GAAmB;AAC1C,SAAO,MAAM,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;AAClC;AAGO,SAAS,gBAAgB,OAAe;AAC9C,QAAM,UAAU,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7C,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAAc,KAAK,IAAI,IAAI,QAAQ,MAAM;AAC/C,QAAM,YAAY,SAAS,SAAS,EAAE;AACtC,SAAO,cAAc,IAAI,WAAW,WAAW;AAChD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
function gcd(a, b) {
|
|
2
|
-
return b === 0 ? a : gcd(b, a % b);
|
|
3
|
-
}
|
|
4
|
-
function nearestMultiple(float) {
|
|
5
|
-
const decimal = float.toString().split(".")[1];
|
|
6
|
-
if (!decimal) return 1;
|
|
7
|
-
const denominator = Math.pow(10, decimal.length);
|
|
8
|
-
const numerator = parseInt(decimal, 10);
|
|
9
|
-
return denominator / gcd(numerator, denominator);
|
|
10
|
-
}
|
|
11
|
-
export {
|
|
12
|
-
nearestMultiple
|
|
13
|
-
};
|
|
14
|
-
//# sourceMappingURL=nearestMultiple.mjs.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../src/lib/utils/nearestMultiple.ts"],
|
|
4
|
-
"sourcesContent": ["// Euclidean algorithm to find the GCD\nfunction gcd(a: number, b: number): number {\n\treturn b === 0 ? a : gcd(b, a % b)\n}\n\n// Returns the lowest value that the given number can be multiplied by to reach an integer\nexport function nearestMultiple(float: number) {\n\tconst decimal = float.toString().split('.')[1]\n\tif (!decimal) return 1\n\tconst denominator = Math.pow(10, decimal.length)\n\tconst numerator = parseInt(decimal, 10)\n\treturn denominator / gcd(numerator, denominator)\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,IAAI,GAAW,GAAmB;AAC1C,SAAO,MAAM,IAAI,IAAI,IAAI,GAAG,IAAI,CAAC;AAClC;AAGO,SAAS,gBAAgB,OAAe;AAC9C,QAAM,UAAU,MAAM,SAAS,EAAE,MAAM,GAAG,EAAE,CAAC;AAC7C,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,cAAc,KAAK,IAAI,IAAI,QAAQ,MAAM;AAC/C,QAAM,YAAY,SAAS,SAAS,EAAE;AACtC,SAAO,cAAc,IAAI,WAAW,WAAW;AAChD;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// Euclidean algorithm to find the GCD
|
|
2
|
-
function gcd(a: number, b: number): number {
|
|
3
|
-
return b === 0 ? a : gcd(b, a % b)
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
// Returns the lowest value that the given number can be multiplied by to reach an integer
|
|
7
|
-
export function nearestMultiple(float: number) {
|
|
8
|
-
const decimal = float.toString().split('.')[1]
|
|
9
|
-
if (!decimal) return 1
|
|
10
|
-
const denominator = Math.pow(10, decimal.length)
|
|
11
|
-
const numerator = parseInt(decimal, 10)
|
|
12
|
-
return denominator / gcd(numerator, denominator)
|
|
13
|
-
}
|