hopefully this should fix firefox 🙏
This commit is contained in:
parent
c2107bf01d
commit
6902c03fcb
5 changed files with 39 additions and 19 deletions
|
@ -1,15 +1,23 @@
|
||||||
import type { DropdownMenuTriggerProps } from '@kobalte/core/dropdown-menu'
|
import type { DropdownMenuTriggerProps } from '@kobalte/core/dropdown-menu'
|
||||||
|
import type { mtcute } from 'mtcute-repl-worker/client'
|
||||||
import type { CustomTypeScriptWorker } from '../editor/utils/custom-worker.ts'
|
import type { CustomTypeScriptWorker } from '../editor/utils/custom-worker.ts'
|
||||||
import { timers } from '@fuman/utils'
|
import { timers } from '@fuman/utils'
|
||||||
import { persistentAtom } from '@nanostores/persistent'
|
import { persistentAtom } from '@nanostores/persistent'
|
||||||
import { LucideCheck, LucidePlay, LucidePlug, LucideRefreshCw, LucideSkull, LucideUnplug } from 'lucide-solid'
|
import { LucideCheck, LucidePlay, LucidePlug, LucideRefreshCw, LucideSkull, LucideUnplug } from 'lucide-solid'
|
||||||
import { languages, Uri } from 'monaco-editor/esm/vs/editor/editor.api.js'
|
import { languages, Uri } from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||||
import { type mtcute, workerInvoke } from 'mtcute-repl-worker/client'
|
|
||||||
import { nanoid } from 'nanoid'
|
|
||||||
import { createEffect, createSignal, on, onCleanup, onMount } from 'solid-js'
|
import { createEffect, createSignal, on, onCleanup, onMount } from 'solid-js'
|
||||||
import { Dynamic } from 'solid-js/web'
|
import { Dynamic } from 'solid-js/web'
|
||||||
import { Button } from '../../lib/components/ui/button.tsx'
|
import { Button } from '../../lib/components/ui/button.tsx'
|
||||||
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuGroupLabel, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '../../lib/components/ui/dropdown-menu.tsx'
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuCheckboxItem,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuGroup,
|
||||||
|
DropdownMenuGroupLabel,
|
||||||
|
DropdownMenuItem,
|
||||||
|
DropdownMenuSeparator,
|
||||||
|
DropdownMenuTrigger,
|
||||||
|
} from '../../lib/components/ui/dropdown-menu.tsx'
|
||||||
import { cn } from '../../lib/utils.ts'
|
import { cn } from '../../lib/utils.ts'
|
||||||
import { $activeAccountId } from '../../store/accounts.ts'
|
import { $activeAccountId } from '../../store/accounts.ts'
|
||||||
import { $tabs } from '../../store/tabs.ts'
|
import { $tabs } from '../../store/tabs.ts'
|
||||||
|
@ -41,7 +49,6 @@ export function Runner(props: { isResizing: boolean }) {
|
||||||
const enableUpdates = useStore($enableUpdates)
|
const enableUpdates = useStore($enableUpdates)
|
||||||
const enableVerbose = useStore($enableVerbose)
|
const enableVerbose = useStore($enableVerbose)
|
||||||
|
|
||||||
let currentScriptId: string | undefined
|
|
||||||
let deadTimer: timers.Timer | undefined
|
let deadTimer: timers.Timer | undefined
|
||||||
let inactivityTimer: timers.Timer | undefined
|
let inactivityTimer: timers.Timer | undefined
|
||||||
let iframeContainerRef!: HTMLIFrameElement
|
let iframeContainerRef!: HTMLIFrameElement
|
||||||
|
@ -102,8 +109,6 @@ export function Runner(props: { isResizing: boolean }) {
|
||||||
}
|
}
|
||||||
case 'SCRIPT_END': {
|
case 'SCRIPT_END': {
|
||||||
setRunning(false)
|
setRunning(false)
|
||||||
workerInvoke('sw', 'forgetScript', { name: currentScriptId! })
|
|
||||||
currentScriptId = undefined
|
|
||||||
rescheduleInactivityTimer()
|
rescheduleInactivityTimer()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -180,12 +185,9 @@ export function Runner(props: { isResizing: boolean }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentScriptId = nanoid()
|
|
||||||
await workerInvoke('sw', 'uploadScript', { name: currentScriptId, files })
|
|
||||||
|
|
||||||
runnerIframe()!.contentWindow!.postMessage({
|
runnerIframe()!.contentWindow!.postMessage({
|
||||||
event: 'RUN',
|
event: 'RUN',
|
||||||
scriptId: currentScriptId,
|
files,
|
||||||
exports,
|
exports,
|
||||||
}, '*')
|
}, '*')
|
||||||
setRunning(true)
|
setRunning(true)
|
||||||
|
@ -328,7 +330,7 @@ export function Runner(props: { isResizing: boolean }) {
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-border h-px shrink-0" />
|
<div class="h-px shrink-0 bg-border" />
|
||||||
<Devtools
|
<Devtools
|
||||||
class={cn('size-full grow-0', props.isResizing && 'pointer-events-none')}
|
class={cn('size-full grow-0', props.isResizing && 'pointer-events-none')}
|
||||||
iframeRef={setDevtoolsIframe}
|
iframeRef={setDevtoolsIframe}
|
||||||
|
|
|
@ -19,6 +19,9 @@ await build({
|
||||||
format: 'esm',
|
format: 'esm',
|
||||||
outfile: 'src/sw/iframe/script-bundled.js',
|
outfile: 'src/sw/iframe/script-bundled.js',
|
||||||
define: defines,
|
define: defines,
|
||||||
external: ['@mtcute/web'],
|
external: [
|
||||||
|
'@mtcute/web',
|
||||||
|
'./sw.ts',
|
||||||
|
],
|
||||||
minify: true,
|
minify: true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -12,7 +12,10 @@ let nextId = 0
|
||||||
const pending = new Map<number, Deferred<any>>()
|
const pending = new Map<number, Deferred<any>>()
|
||||||
|
|
||||||
export async function swInvokeMethod(request: SwMessage) {
|
export async function swInvokeMethod(request: SwMessage) {
|
||||||
const sw = await getServiceWorker()
|
return swInvokeMethodInner(request, await getServiceWorker())
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function swInvokeMethodInner(request: SwMessage, sw: ServiceWorker) {
|
||||||
if (!registered) {
|
if (!registered) {
|
||||||
navigator.serviceWorker.addEventListener('message', (e) => {
|
navigator.serviceWorker.addEventListener('message', (e) => {
|
||||||
const { id, result, error } = (e as MessageEvent).data
|
const { id, result, error } = (e as MessageEvent).data
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
|
import { asNonNull } from '@fuman/utils'
|
||||||
import { Long, TelegramClient } from '@mtcute/web'
|
import { Long, TelegramClient } from '@mtcute/web'
|
||||||
|
import { nanoid } from 'nanoid'
|
||||||
|
import { swInvokeMethodInner } from '../client.ts'
|
||||||
|
|
||||||
type ConnectionState = import('@mtcute/web').ConnectionState
|
type ConnectionState = import('@mtcute/web').ConnectionState
|
||||||
type TelegramClientOptions = import('@mtcute/web').TelegramClientOptions
|
type TelegramClientOptions = import('@mtcute/web').TelegramClientOptions
|
||||||
|
@ -31,6 +34,7 @@ chobitsu.setOnMessage((message: string) => {
|
||||||
|
|
||||||
let lastAccountId: string | undefined
|
let lastAccountId: string | undefined
|
||||||
let lastConnectionState: ConnectionState | undefined
|
let lastConnectionState: ConnectionState | undefined
|
||||||
|
let currentScriptId: string | undefined
|
||||||
let logUpdates = false
|
let logUpdates = false
|
||||||
let verboseLogs = false
|
let verboseLogs = false
|
||||||
|
|
||||||
|
@ -70,7 +74,7 @@ function initClient(accountId: string, verbose: boolean) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('message', ({ data }) => {
|
window.addEventListener('message', async ({ data }) => {
|
||||||
if (data.event === 'INIT') {
|
if (data.event === 'INIT') {
|
||||||
sendToDevtools({
|
sendToDevtools({
|
||||||
method: 'Page.frameNavigated',
|
method: 'Page.frameNavigated',
|
||||||
|
@ -102,9 +106,12 @@ window.addEventListener('message', ({ data }) => {
|
||||||
window.parent.postMessage({ event: 'PING' }, HOST_ORIGIN)
|
window.parent.postMessage({ event: 'PING' }, HOST_ORIGIN)
|
||||||
}, 500)
|
}, 500)
|
||||||
} else if (data.event === 'RUN') {
|
} else if (data.event === 'RUN') {
|
||||||
|
currentScriptId = nanoid()
|
||||||
|
await swInvokeMethodInner({ event: 'UPLOAD_SCRIPT', name: currentScriptId, files: data.files }, asNonNull(navigator.serviceWorker.controller))
|
||||||
|
|
||||||
const el = document.createElement('script')
|
const el = document.createElement('script')
|
||||||
el.type = 'module'
|
el.type = 'module'
|
||||||
let script = `import * as result from "/sw/runtime/script/${data.scriptId}/main.js";`
|
let script = `import * as result from "/sw/runtime/script/${currentScriptId}/main.js";`
|
||||||
for (const exportName of data.exports ?? []) {
|
for (const exportName of data.exports ?? []) {
|
||||||
script += `window.${exportName} = result.${exportName};`
|
script += `window.${exportName} = result.${exportName};`
|
||||||
}
|
}
|
||||||
|
@ -114,9 +121,11 @@ window.addEventListener('message', ({ data }) => {
|
||||||
script += 'console.log("[mtcute-repl] Script ended");'
|
script += 'console.log("[mtcute-repl] Script ended");'
|
||||||
}
|
}
|
||||||
script += 'window.__handleScriptEnd();'
|
script += 'window.__handleScriptEnd();'
|
||||||
|
|
||||||
el.textContent = script
|
el.textContent = script
|
||||||
el.addEventListener('error', e => window.__handleScriptEnd(e.error))
|
el.addEventListener('error', e => window.__handleScriptEnd(e.error))
|
||||||
window.__currentScript = el
|
window.__currentScript = el
|
||||||
|
|
||||||
document.body.appendChild(el)
|
document.body.appendChild(el)
|
||||||
} else if (data.event === 'FROM_DEVTOOLS') {
|
} else if (data.event === 'FROM_DEVTOOLS') {
|
||||||
chobitsu.sendRawMessage(data.value)
|
chobitsu.sendRawMessage(data.value)
|
||||||
|
@ -152,6 +161,9 @@ window.addEventListener('message', ({ data }) => {
|
||||||
|
|
||||||
window.__handleScriptEnd = (error) => {
|
window.__handleScriptEnd = (error) => {
|
||||||
if (!window.__currentScript) return
|
if (!window.__currentScript) return
|
||||||
|
if (currentScriptId) {
|
||||||
|
swInvokeMethodInner({ event: 'FORGET_SCRIPT', name: currentScriptId }).catch(console.error)
|
||||||
|
}
|
||||||
window.parent.postMessage({ event: 'SCRIPT_END', error }, HOST_ORIGIN)
|
window.parent.postMessage({ event: 'SCRIPT_END', error }, HOST_ORIGIN)
|
||||||
window.__currentScript.remove()
|
window.__currentScript.remove()
|
||||||
window.__currentScript = undefined
|
window.__currentScript = undefined
|
||||||
|
|
|
@ -59,19 +59,19 @@ export type SwMessage =
|
||||||
| { event: 'CLEAR_AVATAR_CACHE', accountId: string }
|
| { event: 'CLEAR_AVATAR_CACHE', accountId: string }
|
||||||
| { event: 'CLEAR_CACHE' }
|
| { event: 'CLEAR_CACHE' }
|
||||||
|
|
||||||
function handleMessage(msg: SwMessage) {
|
async function handleMessage(msg: SwMessage) {
|
||||||
switch (msg.event) {
|
switch (msg.event) {
|
||||||
case 'UPLOAD_SCRIPT': {
|
case 'UPLOAD_SCRIPT': {
|
||||||
uploadScript(msg.name, msg.files)
|
await uploadScript(msg.name, msg.files)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'FORGET_SCRIPT': {
|
case 'FORGET_SCRIPT': {
|
||||||
forgetScript(msg.name)
|
await forgetScript(msg.name)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'CLEAR_CACHE': {
|
case 'CLEAR_CACHE': {
|
||||||
clearCache()
|
clearCache()
|
||||||
forgetAllScripts()
|
await forgetAllScripts()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case 'CLEAR_AVATAR_CACHE': {
|
case 'CLEAR_AVATAR_CACHE': {
|
||||||
|
|
Loading…
Reference in a new issue