Skip to content

Commit

Permalink
refactor(api/{mime,service-worker}): improve mime query input support…
Browse files Browse the repository at this point in the history
…, use 'BroadcastChannel' in serviceworkers
  • Loading branch information
jwerle committed Jan 10, 2025
1 parent 47faadc commit 44fe5ff
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 339 deletions.
29 changes: 26 additions & 3 deletions api/internal/geolocation.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function createGeolocationPosition (data) {
altitude: {
configurable: false,
writable: false,
value: data.coords.altitude
value: data.coords.altitude ?? null
},

accuracy: {
Expand Down Expand Up @@ -95,12 +95,34 @@ function createGeolocationPosition (data) {
configurable: false,
writable: false,
value: data.coords.speed <= 0 ? null : data.coords.speed
},

toJSON: {
configurable: false,
writable: true,
value: () => ({
accuracy: data.coords.accuracy,
latitude: data.coords.latitude,
longitude: data.coords.longitude,
altitude: data.coords.altitude ?? null,
altitudeAccuracy: data.coords.altitudeAccuracy ?? null,
heading: data.coords.heading ?? null,
speed: data.coords.speed ?? null
})
}
})

return Object.create(GeolocationPosition.prototype, {
coords: { configurable: false, writable: false, value: coords },
timestamp: { configurable: false, writable: false, value: Date.now() }
timestamp: { configurable: false, writable: false, value: Date.now() },
toJSON: {
configurable: false,
writable: true,
value: () => ({
coords: coords.toJSON(),
timestamp: Date.now()
})
}
})
}

Expand Down Expand Up @@ -176,7 +198,8 @@ export async function getCurrentPosition (
timer = setTimeout(() => {
didTimeout = true
const error = Object.create(GeolocationPositionError.prototype, {
code: { value: GeolocationPositionError.TIMEOUT }
code: { value: GeolocationPositionError.TIMEOUT },
message: { value: 'Position acquisition timed out' }
})

if (typeof onError === 'function') {
Expand Down
72 changes: 42 additions & 30 deletions api/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1772,39 +1772,51 @@ export function findIPCMessageTransfers (transfers, object) {
object[i] = findIPCMessageTransfers(transfers, object[i])
}
} else if (object && typeof object === 'object') {
if (object instanceof MessagePort) {
if (object instanceof IPCMessagePort) {
const port = IPCMessagePort.create(object)
ports.get(port.id).channel.onmessage = (event) => {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
return false
}
if (
object instanceof MessagePort || (
typeof object.postMessage === 'function' &&
Object.getPrototypeOf(object).constructor.name === 'MessagePort'
)
) {
const port = IPCMessagePort.create(object)
object.addEventListener('message', function onMessage (event) {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
object.removeEventListener('message', onMessage)
return false
}

if (port.started && event.data?.token !== port.token) {
console.log(event.data)
const transfers = new Set()
findIPCMessageTransfers(transfers, event.data)
object.postMessage(event.data, {
transfer: Array.from(transfers)
})
}
port.dispatchEvent(new MessageEvent('message', event))
})

port.onmessage = (event) => {
if (port.closed === true) {
port.onmessage = null
event.preventDefault()
event.stopImmediatePropagation()
return false
}
add(port)
return port
} else {
add(object)
return object
}
} else if (Object.getPrototypeOf(object) === Object.prototype) {
for (const key in object) {
object[key] = findIPCMessageTransfers(
transfers,
object[key]
)

const transfers = new Set()
findIPCMessageTransfers(transfers, event.data)
object.postMessage(event.data, {
transfer: Array.from(transfers)
})
}
add(port)
return port
} else {
add(object)
return object
}
} else if (Object.getPrototypeOf(object) === Object.prototype) {
for (const key in object) {
object[key] = findIPCMessageTransfers(
transfers,
object[key]
)
}
}

Expand Down
10 changes: 9 additions & 1 deletion api/mime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,16 @@ export class Database {
query (query) {
query = query.toLowerCase()

const queryParts = query.split('+')
if (query.startsWith('.')) {
query = query.slice(1)
}

const results = []
const queryParts = query
.split('+')
.map((query) => query.trim())
.map((query) => query.startsWith('.') ? query.slice(1) : query)
.filter(Boolean)

for (const [key, value] of this.map.entries()) {
const name = key.toLowerCase()
Expand Down
94 changes: 44 additions & 50 deletions api/service-worker/container.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* global EventTarget */
import { ServiceWorkerRegistration } from './registration.js'
import { createServiceWorker, SHARED_WORKER_URL } from './instance.js'
import { SharedWorker } from '../shared-worker/index.js'
import { createServiceWorker } from './instance.js'
import { Deferred } from '../async.js'
import application from '../application.js'
import location from '../location.js'
Expand All @@ -23,8 +22,7 @@ class ServiceWorkerContainerInternalStateMap extends Map {
class ServiceWorkerContainerInternalState {
currentWindow = null
controller = null
sharedWorker = null
channel = new BroadcastChannel('socket.runtime.ServiceWorkerContainer')
channel = new BroadcastChannel('socket.runtime.serviceWorker')
ready = new Deferred()
init = new Deferred()

Expand Down Expand Up @@ -487,65 +485,61 @@ export class ServiceWorkerContainer extends EventTarget {
return globalThis.top.navigator.serviceWorker.startMessages()
}

if (!internal.get(this).sharedWorker && globalThis.RUNTIME_WORKER_LOCATION !== SHARED_WORKER_URL) {
internal.get(this).sharedWorker = new SharedWorker(SHARED_WORKER_URL)
internal.get(this).sharedWorker.port.start()
internal.get(this).sharedWorker.port.onmessage = async (event) => {
if (
event.data?.from === 'realm' &&
event.data?.registration?.id &&
event.data?.client?.id === globalThis.__args.client.id &&
event.data?.client?.type === globalThis.__args.client.type &&
event.data?.client?.frameType === globalThis.__args.client.frameType
) {
const registrations = await this.getRegistrations()
for (const registration of registrations) {
const info = registration[Symbol.for('socket.runtime.ServiceWorkerRegistration.info')]
if (info?.id === event.data.registration.id) {
const serviceWorker = createServiceWorker(state.serviceWorker.state, {
subscribe: false,
scriptURL: info.scriptURL,
id: info.id
})

const messageEvent = new MessageEvent('message', {
origin: new URL(info.scriptURL, location.origin).origin,
data: event.data.message
})

Object.defineProperty(messageEvent, 'source', {
configurable: false,
enumerable: false,
writable: false,
value: serviceWorker
})

this.dispatchEvent(messageEvent)
break
}
}
} else if (
event.data?.from === 'instance' &&
event.data?.registration?.id &&
event.data?.client?.id &&
event.data?.client?.id !== globalThis.__args.client.id
) {
if (globalThis.isWorkerScope && globalThis.serviceWorker) {
internal.get(this).channel.onmessage = async (event) => {
if (
event.data?.from === 'realm' &&
event.data?.registration?.id &&
event.data?.client?.id === globalThis.__args.client.id &&
event.data?.client?.type === globalThis.__args.client.type &&
event.data?.client?.frameType === globalThis.__args.client.frameType
) {
const registrations = await this.getRegistrations()
for (const registration of registrations) {
const info = registration[Symbol.for('socket.runtime.ServiceWorkerRegistration.info')]
if (info?.id === event.data.registration.id) {
const serviceWorker = createServiceWorker(state.serviceWorker.state, {
subscribe: false,
scriptURL: info.scriptURL,
id: info.id
})

const messageEvent = new MessageEvent('message', {
origin: event.data.client.origin.origin,
origin: new URL(info.scriptURL, location.origin).origin,
data: event.data.message
})

Object.defineProperty(messageEvent, 'source', {
configurable: false,
enumerable: false,
writable: false,
value: await globalThis.clients.get(event.data.client.id)
value: serviceWorker
})

this.dispatchEvent(messageEvent)
break
}
}
} else if (
event.data?.from === 'instance' &&
event.data?.registration?.id &&
event.data?.client?.id &&
event.data?.client?.id !== globalThis.__args.client.id
) {
if (globalThis.isWorkerScope && globalThis.serviceWorker) {
const messageEvent = new MessageEvent('message', {
origin: event.data.client.origin.origin,
data: event.data.message
})

Object.defineProperty(messageEvent, 'source', {
configurable: false,
enumerable: false,
writable: false,
value: await globalThis.clients.get(event.data.client.id)
})

this.dispatchEvent(messageEvent)
}
}
}
}
Expand Down
Loading

0 comments on commit 44fe5ff

Please sign in to comment.