mirror of
https://github.com/pockethost/pockethost.git
synced 2025-05-19 13:26:42 +00:00
chore: remove deno worker helper lib
This commit is contained in:
parent
535903a160
commit
2205f4a30b
@ -1,267 +0,0 @@
|
||||
/**
|
||||
* https://raw.githubusercontent.com/MierenManz/EventSource/main/mod.ts
|
||||
*
|
||||
* Maintaining until https://github.com/MierenManz/EventSource/issues/32
|
||||
*/
|
||||
|
||||
interface EventSourceInit {
|
||||
withCredentials: boolean
|
||||
}
|
||||
|
||||
type EventHandler<Evt extends Event> = (e: Evt) => void | Promise<void>
|
||||
|
||||
interface Settings {
|
||||
url: string
|
||||
fetchSettings: {
|
||||
headers: string[][]
|
||||
credentials: 'same-origin' | 'include'
|
||||
mode: 'cors'
|
||||
}
|
||||
reconnectionTime: number
|
||||
lastEventID: string
|
||||
}
|
||||
|
||||
export class EventSource extends EventTarget {
|
||||
#withCredentials = false
|
||||
#readyState: 0 | 1 | 2 = 0
|
||||
#abortController = new AbortController()
|
||||
#settings: Settings = {
|
||||
url: '',
|
||||
fetchSettings: {
|
||||
headers: [['Accept', 'text/event-stream']],
|
||||
credentials: 'same-origin',
|
||||
mode: 'cors',
|
||||
},
|
||||
reconnectionTime: 2200,
|
||||
lastEventID: '',
|
||||
}
|
||||
|
||||
onopen: EventHandler<Event> | null = null
|
||||
onmessage: EventHandler<MessageEvent<string>> | null = null
|
||||
onerror: EventHandler<Event> | null = null
|
||||
|
||||
CONNECTING: 0 = 0
|
||||
OPEN: 1 = 1
|
||||
CLOSED: 2 = 2
|
||||
|
||||
get readyState(): 0 | 1 | 2 {
|
||||
return this.#readyState
|
||||
}
|
||||
|
||||
get url(): string {
|
||||
return this.#settings.url
|
||||
}
|
||||
|
||||
get withCredentials(): boolean {
|
||||
return this.#withCredentials
|
||||
}
|
||||
|
||||
constructor(url: string, eventSourceInitDict?: EventSourceInit) {
|
||||
super()
|
||||
|
||||
try {
|
||||
// Allow empty url
|
||||
// https://github.com/web-platform-tests/wpt/blob/master/eventsource/eventsource-constructor-empty-url.any.js
|
||||
this.#settings.url =
|
||||
url == ''
|
||||
? window.location.toString()
|
||||
: new URL(url, window.location?.href).toString()
|
||||
} catch (e) {
|
||||
// Dunno if this is allowed in the spec. But handy for testing purposes
|
||||
if (e instanceof ReferenceError) {
|
||||
this.#settings.url = new URL(url).toString()
|
||||
} else throw new DOMException(e.message, 'SyntaxError')
|
||||
}
|
||||
|
||||
if (eventSourceInitDict?.withCredentials) {
|
||||
this.#settings.fetchSettings.credentials = 'include'
|
||||
this.#withCredentials = true
|
||||
}
|
||||
|
||||
this.#fetch()
|
||||
return
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.#readyState = this.CLOSED
|
||||
this.#abortController.abort()
|
||||
}
|
||||
|
||||
#retry() {
|
||||
const errorEvent = new Event('error', {
|
||||
bubbles: false,
|
||||
cancelable: false,
|
||||
})
|
||||
super.dispatchEvent(errorEvent)
|
||||
this.onerror?.(errorEvent)
|
||||
setTimeout(this.#fetch, 0)
|
||||
}
|
||||
|
||||
async #fetch(): Promise<void> {
|
||||
this.#readyState = this.CONNECTING
|
||||
const res = await fetch(this.url, {
|
||||
cache: 'no-store',
|
||||
// This seems to cause problems if the abort happens while `res.body` is being used
|
||||
// signal: this.#abortController.signal,
|
||||
keepalive: true,
|
||||
redirect: 'follow',
|
||||
...this.#settings.fetchSettings,
|
||||
}).catch(console.error)
|
||||
|
||||
if (
|
||||
res?.body &&
|
||||
res?.status === 200 &&
|
||||
res.headers.get('content-type')?.startsWith('text/event-stream')
|
||||
) {
|
||||
// Announce connection
|
||||
this.#readyState = this.OPEN
|
||||
const openEvent = new Event('open', {
|
||||
bubbles: false,
|
||||
cancelable: false,
|
||||
})
|
||||
super.dispatchEvent(openEvent)
|
||||
this.onopen?.(openEvent)
|
||||
|
||||
// Decode body for interpreting
|
||||
const decoder = new TextDecoderStream('utf-8', {
|
||||
ignoreBOM: false,
|
||||
fatal: false,
|
||||
})
|
||||
const reader = res.body.pipeThrough(decoder)
|
||||
|
||||
// Initiate buffers
|
||||
let lastEventIDBuffer = ''
|
||||
let eventTypeBuffer = ''
|
||||
let messageBuffer = ''
|
||||
let readBuffer = ''
|
||||
|
||||
try {
|
||||
for await (const chunk of reader) {
|
||||
if (this.#abortController.signal.aborted) break
|
||||
const lines = decodeURIComponent(readBuffer + chunk)
|
||||
.replaceAll('\r\n', '\n')
|
||||
.replaceAll('\r', '\n')
|
||||
.split('\n')
|
||||
readBuffer = lines.pop() ?? ''
|
||||
|
||||
// Start loop for interpreting
|
||||
for (const line of lines) {
|
||||
if (!line) {
|
||||
this.#settings.lastEventID = lastEventIDBuffer
|
||||
|
||||
// Check if buffer is not an empty string
|
||||
if (messageBuffer) {
|
||||
// Create event
|
||||
if (!eventTypeBuffer) {
|
||||
eventTypeBuffer = 'message'
|
||||
}
|
||||
|
||||
const event = new MessageEvent<string>(eventTypeBuffer, {
|
||||
data: messageBuffer.trim(),
|
||||
origin: res.url,
|
||||
lastEventId: this.#settings.lastEventID,
|
||||
cancelable: false,
|
||||
bubbles: false,
|
||||
})
|
||||
|
||||
if (this.readyState !== this.CLOSED) {
|
||||
// Fire event
|
||||
super.dispatchEvent(event)
|
||||
if (this.onmessage) this.onmessage(event)
|
||||
}
|
||||
}
|
||||
|
||||
// Clear buffers
|
||||
messageBuffer = ''
|
||||
eventTypeBuffer = ''
|
||||
continue
|
||||
}
|
||||
|
||||
// Ignore comments
|
||||
if (line[0] === ':') continue
|
||||
|
||||
let splitIndex = line.indexOf(':')
|
||||
splitIndex = splitIndex > 0 ? splitIndex : line.length
|
||||
const field = line.slice(0, splitIndex).trim()
|
||||
const data = line.slice(splitIndex + 1).trim()
|
||||
switch (field) {
|
||||
case 'event':
|
||||
// Set fieldBuffer to Field Value
|
||||
eventTypeBuffer = data
|
||||
break
|
||||
case 'data':
|
||||
// append Field Value to dataBuffer
|
||||
messageBuffer += `${data}\n`
|
||||
break
|
||||
case 'id':
|
||||
// set lastEventID to Field Value
|
||||
if (
|
||||
data &&
|
||||
!data.includes('\u0000') &&
|
||||
!data.includes('\x00')
|
||||
) {
|
||||
lastEventIDBuffer = data
|
||||
}
|
||||
break
|
||||
case 'retry': {
|
||||
// set reconnectionTime to Field Value if int
|
||||
const num = Number(data)
|
||||
if (!isNaN(num) && isFinite(num)) {
|
||||
this.#settings.reconnectionTime = num
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`caught an error!`, e)
|
||||
} finally {
|
||||
// Cancel reader to close the EventSource properly
|
||||
await reader.cancel().catch(console.error)
|
||||
this.#readyState = this.CLOSED
|
||||
}
|
||||
} else {
|
||||
// Connection failed for whatever reason
|
||||
this.#readyState = this.CLOSED
|
||||
this.#abortController.abort()
|
||||
const errorEvent = new Event('error', {
|
||||
bubbles: false,
|
||||
cancelable: false,
|
||||
})
|
||||
super.dispatchEvent(errorEvent)
|
||||
this.onerror?.(errorEvent)
|
||||
setTimeout(continuallyConnect, 0)
|
||||
return
|
||||
}
|
||||
|
||||
// Set readyState to CONNECTING
|
||||
if (this.#readyState !== this.CLOSED) {
|
||||
// Fire onerror
|
||||
const errorEvent = new Event('error', {
|
||||
bubbles: false,
|
||||
cancelable: false,
|
||||
})
|
||||
|
||||
super.dispatchEvent(errorEvent)
|
||||
if (this.onerror) this.onerror(errorEvent)
|
||||
|
||||
// Timeout for re-establishing the connection
|
||||
await new Promise<void>((res) => {
|
||||
const id = setTimeout(
|
||||
() => res(clearTimeout(id)),
|
||||
this.#settings.reconnectionTime,
|
||||
)
|
||||
})
|
||||
|
||||
if (this.#readyState !== this.CONNECTING) break
|
||||
|
||||
if (this.#settings.lastEventID) {
|
||||
this.#settings.fetchSettings.headers.push([
|
||||
'Last-Event-ID',
|
||||
this.#settings.lastEventID,
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,571 +0,0 @@
|
||||
import * as events from 'https://deno.land/std@0.167.0/node/events.ts'
|
||||
import * as http from 'https://deno.land/std@0.167.0/node/http.ts'
|
||||
import * as https from 'https://deno.land/std@0.167.0/node/https.ts'
|
||||
import { parse } from 'https://deno.land/std@0.167.0/node/url.ts'
|
||||
import * as util from 'https://deno.land/std@0.167.0/node/util.ts'
|
||||
|
||||
var httpsOptions = [
|
||||
'pfx',
|
||||
'key',
|
||||
'passphrase',
|
||||
'cert',
|
||||
'ca',
|
||||
'ciphers',
|
||||
'rejectUnauthorized',
|
||||
'secureProtocol',
|
||||
'servername',
|
||||
'checkServerIdentity',
|
||||
]
|
||||
|
||||
var bom = [239, 187, 191]
|
||||
var colon = 58
|
||||
var space = 32
|
||||
var lineFeed = 10
|
||||
var carriageReturn = 13
|
||||
// Beyond 256KB we could not observe any gain in performance
|
||||
var maxBufferAheadAllocation = 1024 * 256
|
||||
// Headers matching the pattern should be removed when redirecting to different origin
|
||||
var reUnsafeHeader = /^(cookie|authorization)$/i
|
||||
|
||||
function hasBom(buf) {
|
||||
return bom.every(function (charCode, index) {
|
||||
return buf[index] === charCode
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new EventSource object
|
||||
*
|
||||
* @param {String} url the URL to which to connect
|
||||
* @param {Object} [eventSourceInitDict] extra init params. See README for details.
|
||||
* @api public
|
||||
**/
|
||||
function EventSource(url, eventSourceInitDict) {
|
||||
var readyState = EventSource.CONNECTING
|
||||
var headers = eventSourceInitDict && eventSourceInitDict.headers
|
||||
var hasNewOrigin = false
|
||||
Object.defineProperty(this, 'readyState', {
|
||||
get: function () {
|
||||
return readyState
|
||||
},
|
||||
})
|
||||
|
||||
Object.defineProperty(this, 'url', {
|
||||
get: function () {
|
||||
return url
|
||||
},
|
||||
})
|
||||
|
||||
var self = this
|
||||
self.reconnectInterval = 1000
|
||||
self.connectionInProgress = false
|
||||
|
||||
function onConnectionClosed(message) {
|
||||
if (readyState === EventSource.CLOSED) return
|
||||
readyState = EventSource.CONNECTING
|
||||
_emit('error', new Event('error', { message: message }))
|
||||
|
||||
// The url may have been changed by a temporary redirect. If that's the case,
|
||||
// revert it now, and flag that we are no longer pointing to a new origin
|
||||
if (reconnectUrl) {
|
||||
url = reconnectUrl
|
||||
reconnectUrl = null
|
||||
hasNewOrigin = false
|
||||
}
|
||||
setTimeout(function () {
|
||||
if (readyState !== EventSource.CONNECTING || self.connectionInProgress) {
|
||||
return
|
||||
}
|
||||
self.connectionInProgress = true
|
||||
connect()
|
||||
}, self.reconnectInterval)
|
||||
}
|
||||
|
||||
var req
|
||||
var lastEventId = ''
|
||||
if (headers && headers['Last-Event-ID']) {
|
||||
lastEventId = headers['Last-Event-ID']
|
||||
delete headers['Last-Event-ID']
|
||||
}
|
||||
|
||||
var discardTrailingNewline = false
|
||||
var data = ''
|
||||
var eventName = ''
|
||||
|
||||
var reconnectUrl = null
|
||||
|
||||
function connect() {
|
||||
var options = parse(url)
|
||||
var isSecure = options.protocol === 'https:'
|
||||
options.headers = {
|
||||
'Cache-Control': 'no-cache',
|
||||
Accept: 'text/event-stream',
|
||||
}
|
||||
if (lastEventId) options.headers['Last-Event-ID'] = lastEventId
|
||||
if (headers) {
|
||||
var reqHeaders = hasNewOrigin ? removeUnsafeHeaders(headers) : headers
|
||||
for (var i in reqHeaders) {
|
||||
var header = reqHeaders[i]
|
||||
if (header) {
|
||||
options.headers[i] = header
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Legacy: this should be specified as `eventSourceInitDict.https.rejectUnauthorized`,
|
||||
// but for now exists as a backwards-compatibility layer
|
||||
options.rejectUnauthorized = !(
|
||||
eventSourceInitDict && !eventSourceInitDict.rejectUnauthorized
|
||||
)
|
||||
|
||||
if (
|
||||
eventSourceInitDict &&
|
||||
eventSourceInitDict.createConnection !== undefined
|
||||
) {
|
||||
options.createConnection = eventSourceInitDict.createConnection
|
||||
}
|
||||
|
||||
// If specify http proxy, make the request to sent to the proxy server,
|
||||
// and include the original url in path and Host headers
|
||||
var useProxy = eventSourceInitDict && eventSourceInitDict.proxy
|
||||
if (useProxy) {
|
||||
var proxy = parse(eventSourceInitDict.proxy)
|
||||
isSecure = proxy.protocol === 'https:'
|
||||
|
||||
options.protocol = isSecure ? 'https:' : 'http:'
|
||||
options.path = url
|
||||
options.headers.Host = options.host
|
||||
options.hostname = proxy.hostname
|
||||
options.host = proxy.host
|
||||
options.port = proxy.port
|
||||
}
|
||||
|
||||
// If https options are specified, merge them into the request options
|
||||
if (eventSourceInitDict && eventSourceInitDict.https) {
|
||||
for (var optName in eventSourceInitDict.https) {
|
||||
if (httpsOptions.indexOf(optName) === -1) {
|
||||
continue
|
||||
}
|
||||
|
||||
var option = eventSourceInitDict.https[optName]
|
||||
if (option !== undefined) {
|
||||
options[optName] = option
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pass this on to the XHR
|
||||
if (
|
||||
eventSourceInitDict &&
|
||||
eventSourceInitDict.withCredentials !== undefined
|
||||
) {
|
||||
options.withCredentials = eventSourceInitDict.withCredentials
|
||||
}
|
||||
|
||||
req = (isSecure ? https : http).request(options, function (res) {
|
||||
self.connectionInProgress = false
|
||||
// Handle HTTP errors
|
||||
if (
|
||||
res.statusCode === 500 ||
|
||||
res.statusCode === 502 ||
|
||||
res.statusCode === 503 ||
|
||||
res.statusCode === 504
|
||||
) {
|
||||
_emit(
|
||||
'error',
|
||||
new Event('error', {
|
||||
status: res.statusCode,
|
||||
message: res.statusMessage,
|
||||
})
|
||||
)
|
||||
onConnectionClosed()
|
||||
return
|
||||
}
|
||||
|
||||
// Handle HTTP redirects
|
||||
if (
|
||||
res.statusCode === 301 ||
|
||||
res.statusCode === 302 ||
|
||||
res.statusCode === 307
|
||||
) {
|
||||
var location = res.headers.location
|
||||
if (!location) {
|
||||
// Server sent redirect response without Location header.
|
||||
_emit(
|
||||
'error',
|
||||
new Event('error', {
|
||||
status: res.statusCode,
|
||||
message: res.statusMessage,
|
||||
})
|
||||
)
|
||||
return
|
||||
}
|
||||
var prevOrigin = new URL(url).origin
|
||||
var nextOrigin = new URL(location).origin
|
||||
hasNewOrigin = prevOrigin !== nextOrigin
|
||||
if (res.statusCode === 307) reconnectUrl = url
|
||||
url = location
|
||||
process.nextTick(connect)
|
||||
return
|
||||
}
|
||||
|
||||
if (res.statusCode !== 200) {
|
||||
_emit(
|
||||
'error',
|
||||
new Event('error', {
|
||||
status: res.statusCode,
|
||||
message: res.statusMessage,
|
||||
})
|
||||
)
|
||||
return self.close()
|
||||
}
|
||||
|
||||
readyState = EventSource.OPEN
|
||||
res.on('close', function () {
|
||||
res.removeAllListeners('close')
|
||||
res.removeAllListeners('end')
|
||||
onConnectionClosed()
|
||||
})
|
||||
|
||||
res.on('end', function () {
|
||||
res.removeAllListeners('close')
|
||||
res.removeAllListeners('end')
|
||||
onConnectionClosed()
|
||||
})
|
||||
_emit('open', new Event('open'))
|
||||
|
||||
// text/event-stream parser adapted from webkit's
|
||||
// Source/WebCore/page/EventSource.cpp
|
||||
var buf
|
||||
var newBuffer
|
||||
var startingPos = 0
|
||||
var startingFieldLength = -1
|
||||
var newBufferSize = 0
|
||||
var bytesUsed = 0
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
if (!buf) {
|
||||
buf = chunk
|
||||
if (hasBom(buf)) {
|
||||
buf = buf.slice(bom.length)
|
||||
}
|
||||
bytesUsed = buf.length
|
||||
} else {
|
||||
if (chunk.length > buf.length - bytesUsed) {
|
||||
newBufferSize = buf.length * 2 + chunk.length
|
||||
if (newBufferSize > maxBufferAheadAllocation) {
|
||||
newBufferSize =
|
||||
buf.length + chunk.length + maxBufferAheadAllocation
|
||||
}
|
||||
newBuffer = Buffer.alloc(newBufferSize)
|
||||
buf.copy(newBuffer, 0, 0, bytesUsed)
|
||||
buf = newBuffer
|
||||
}
|
||||
chunk.copy(buf, bytesUsed)
|
||||
bytesUsed += chunk.length
|
||||
}
|
||||
|
||||
var pos = 0
|
||||
var length = bytesUsed
|
||||
|
||||
while (pos < length) {
|
||||
if (discardTrailingNewline) {
|
||||
if (buf[pos] === lineFeed) {
|
||||
++pos
|
||||
}
|
||||
discardTrailingNewline = false
|
||||
}
|
||||
|
||||
var lineLength = -1
|
||||
var fieldLength = startingFieldLength
|
||||
var c
|
||||
|
||||
for (var i = startingPos; lineLength < 0 && i < length; ++i) {
|
||||
c = buf[i]
|
||||
if (c === colon) {
|
||||
if (fieldLength < 0) {
|
||||
fieldLength = i - pos
|
||||
}
|
||||
} else if (c === carriageReturn) {
|
||||
discardTrailingNewline = true
|
||||
lineLength = i - pos
|
||||
} else if (c === lineFeed) {
|
||||
lineLength = i - pos
|
||||
}
|
||||
}
|
||||
|
||||
if (lineLength < 0) {
|
||||
startingPos = length - pos
|
||||
startingFieldLength = fieldLength
|
||||
break
|
||||
} else {
|
||||
startingPos = 0
|
||||
startingFieldLength = -1
|
||||
}
|
||||
|
||||
parseEventStreamLine(buf, pos, fieldLength, lineLength)
|
||||
|
||||
pos += lineLength + 1
|
||||
}
|
||||
|
||||
if (pos === length) {
|
||||
buf = void 0
|
||||
bytesUsed = 0
|
||||
} else if (pos > 0) {
|
||||
buf = buf.slice(pos, bytesUsed)
|
||||
bytesUsed = buf.length
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
req.on('error', function (err) {
|
||||
self.connectionInProgress = false
|
||||
onConnectionClosed(err.message)
|
||||
})
|
||||
|
||||
if (req.setNoDelay) req.setNoDelay(true)
|
||||
req.end()
|
||||
}
|
||||
|
||||
connect()
|
||||
|
||||
function _emit() {
|
||||
if (self.listeners(arguments[0]).length > 0) {
|
||||
self.emit.apply(self, arguments)
|
||||
}
|
||||
}
|
||||
|
||||
this._close = function () {
|
||||
if (readyState === EventSource.CLOSED) return
|
||||
readyState = EventSource.CLOSED
|
||||
if (req.abort) req.abort()
|
||||
if (req.xhr && req.xhr.abort) req.xhr.abort()
|
||||
}
|
||||
|
||||
function parseEventStreamLine(buf, pos, fieldLength, lineLength) {
|
||||
if (lineLength === 0) {
|
||||
if (data.length > 0) {
|
||||
var type = eventName || 'message'
|
||||
_emit(
|
||||
type,
|
||||
new MessageEvent(type, {
|
||||
data: data.slice(0, -1), // remove trailing newline
|
||||
lastEventId: lastEventId,
|
||||
origin: new URL(url).origin,
|
||||
})
|
||||
)
|
||||
data = ''
|
||||
}
|
||||
eventName = void 0
|
||||
} else if (fieldLength > 0) {
|
||||
var noValue = fieldLength < 0
|
||||
var step = 0
|
||||
var field = buf
|
||||
.slice(pos, pos + (noValue ? lineLength : fieldLength))
|
||||
.toString()
|
||||
|
||||
if (noValue) {
|
||||
step = lineLength
|
||||
} else if (buf[pos + fieldLength + 1] !== space) {
|
||||
step = fieldLength + 1
|
||||
} else {
|
||||
step = fieldLength + 2
|
||||
}
|
||||
pos += step
|
||||
|
||||
var valueLength = lineLength - step
|
||||
var value = buf.slice(pos, pos + valueLength).toString()
|
||||
|
||||
if (field === 'data') {
|
||||
data += value + '\n'
|
||||
} else if (field === 'event') {
|
||||
eventName = value
|
||||
} else if (field === 'id') {
|
||||
lastEventId = value
|
||||
} else if (field === 'retry') {
|
||||
var retry = parseInt(value, 10)
|
||||
if (!Number.isNaN(retry)) {
|
||||
self.reconnectInterval = retry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default EventSource
|
||||
|
||||
util.inherits(EventSource, events.EventEmitter)
|
||||
EventSource.prototype.constructor = EventSource // make stacktraces readable
|
||||
;['open', 'error', 'message'].forEach(function (method) {
|
||||
Object.defineProperty(EventSource.prototype, 'on' + method, {
|
||||
/**
|
||||
* Returns the current listener
|
||||
*
|
||||
* @return {Mixed} the set function or undefined
|
||||
* @api private
|
||||
*/
|
||||
get: function get() {
|
||||
var listener = this.listeners(method)[0]
|
||||
return listener
|
||||
? listener._listener
|
||||
? listener._listener
|
||||
: listener
|
||||
: undefined
|
||||
},
|
||||
|
||||
/**
|
||||
* Start listening for events
|
||||
*
|
||||
* @param {Function} listener the listener
|
||||
* @return {Mixed} the set function or undefined
|
||||
* @api private
|
||||
*/
|
||||
set: function set(listener) {
|
||||
this.removeAllListeners(method)
|
||||
this.addEventListener(method, listener)
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
/**
|
||||
* Ready states
|
||||
*/
|
||||
Object.defineProperty(EventSource, 'CONNECTING', { enumerable: true, value: 0 })
|
||||
Object.defineProperty(EventSource, 'OPEN', { enumerable: true, value: 1 })
|
||||
Object.defineProperty(EventSource, 'CLOSED', { enumerable: true, value: 2 })
|
||||
|
||||
EventSource.prototype.CONNECTING = 0
|
||||
EventSource.prototype.OPEN = 1
|
||||
EventSource.prototype.CLOSED = 2
|
||||
|
||||
/**
|
||||
* Closes the connection, if one is made, and sets the readyState attribute to 2 (closed)
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventSource/close
|
||||
* @api public
|
||||
*/
|
||||
EventSource.prototype.close = function () {
|
||||
this._close()
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulates the W3C Browser based WebSocket interface using addEventListener.
|
||||
*
|
||||
* @param {String} type A string representing the event type to listen out for
|
||||
* @param {Function} listener callback
|
||||
* @see https://developer.mozilla.org/en/DOM/element.addEventListener
|
||||
* @see http://dev.w3.org/html5/websockets/#the-websocket-interface
|
||||
* @api public
|
||||
*/
|
||||
EventSource.prototype.addEventListener = function addEventListener(
|
||||
type,
|
||||
listener
|
||||
) {
|
||||
if (typeof listener === 'function') {
|
||||
// store a reference so we can return the original function again
|
||||
listener._listener = listener
|
||||
this.on(type, listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulates the W3C Browser based WebSocket interface using dispatchEvent.
|
||||
*
|
||||
* @param {Event} event An event to be dispatched
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent
|
||||
* @api public
|
||||
*/
|
||||
EventSource.prototype.dispatchEvent = function dispatchEvent(event) {
|
||||
if (!event.type) {
|
||||
throw new Error('UNSPECIFIED_EVENT_TYPE_ERR')
|
||||
}
|
||||
|
||||
this.emit(event.type, event)
|
||||
}
|
||||
|
||||
/**
|
||||
* Emulates the W3C Browser based WebSocket interface using removeEventListener.
|
||||
*
|
||||
* @param {String} type A string representing the event type to remove
|
||||
* @param {Function} listener callback
|
||||
* @see https://developer.mozilla.org/en/DOM/element.removeEventListener
|
||||
* @see http://dev.w3.org/html5/websockets/#the-websocket-interface
|
||||
* @api public
|
||||
*/
|
||||
EventSource.prototype.removeEventListener = function removeEventListener(
|
||||
type,
|
||||
listener
|
||||
) {
|
||||
if (typeof listener === 'function') {
|
||||
listener._listener = undefined
|
||||
this.removeListener(type, listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* W3C Event
|
||||
*
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/#interface-Event
|
||||
* @api private
|
||||
*/
|
||||
function Event(type, optionalProperties) {
|
||||
Object.defineProperty(this, 'type', {
|
||||
writable: false,
|
||||
value: type,
|
||||
enumerable: true,
|
||||
})
|
||||
if (optionalProperties) {
|
||||
for (var f in optionalProperties) {
|
||||
if (optionalProperties.hasOwnProperty(f)) {
|
||||
Object.defineProperty(this, f, {
|
||||
writable: false,
|
||||
value: optionalProperties[f],
|
||||
enumerable: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* W3C MessageEvent
|
||||
*
|
||||
* @see http://www.w3.org/TR/webmessaging/#event-definitions
|
||||
* @api private
|
||||
*/
|
||||
function MessageEvent(type, eventInitDict) {
|
||||
Object.defineProperty(this, 'type', {
|
||||
writable: false,
|
||||
value: type,
|
||||
enumerable: true,
|
||||
})
|
||||
for (var f in eventInitDict) {
|
||||
if (eventInitDict.hasOwnProperty(f)) {
|
||||
Object.defineProperty(this, f, {
|
||||
writable: false,
|
||||
value: eventInitDict[f],
|
||||
enumerable: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new object of headers that does not include any authorization and cookie headers
|
||||
*
|
||||
* @param {Object} headers An object of headers ({[headerName]: headerValue})
|
||||
* @return {Object} a new object of headers
|
||||
* @api private
|
||||
*/
|
||||
function removeUnsafeHeaders(headers) {
|
||||
var safe = {}
|
||||
for (var key in headers) {
|
||||
if (reUnsafeHeader.test(key)) {
|
||||
continue
|
||||
}
|
||||
|
||||
safe[key] = headers[key]
|
||||
}
|
||||
|
||||
return safe
|
||||
}
|
88
packages/deno-worker/dom-monkeypatch.d.ts
vendored
88
packages/deno-worker/dom-monkeypatch.d.ts
vendored
@ -1,88 +0,0 @@
|
||||
/**
|
||||
* The Event interface represents any event which takes place in the DOM; some are user-generated (such as mouse or keyboard events), while others are generated by APIs (such as
|
||||
* events that indicate an animation has finished running, a video has been paused, and so forth). While events are usually triggered by such "external" sources, they can also be
|
||||
* triggered programmatically, such as by calling the HTMLElement.click() method of an element, or by defining the event, then sending it to a specified target using
|
||||
* EventTarget.dispatchEvent(). There are many types of events, some of which use other interfaces based on the main Event interface. Event itself contains the properties and
|
||||
* methods which are common to all events.
|
||||
*/
|
||||
interface Event {
|
||||
/**
|
||||
* Returns true or false depending on how event was initialized. True if event goes through its target's ancestors in reverse tree order, and false otherwise.
|
||||
*/
|
||||
readonly bubbles: boolean
|
||||
cancelBubble: boolean
|
||||
readonly cancelable: boolean
|
||||
/**
|
||||
* Returns true or false depending on how event was initialized. True if event invokes listeners past a ShadowRoot node that is the root of its target, and false otherwise.
|
||||
*/
|
||||
readonly composed: boolean
|
||||
readonly defaultPrevented: boolean
|
||||
readonly eventPhase: number
|
||||
/**
|
||||
* Returns true if event was dispatched by the user agent, and
|
||||
* false otherwise.
|
||||
*/
|
||||
readonly isTrusted: boolean
|
||||
returnValue: boolean
|
||||
/**
|
||||
* Returns the event's timestamp as the number of milliseconds measured relative to
|
||||
* the time origin.
|
||||
*/
|
||||
readonly timeStamp: number
|
||||
/**
|
||||
* Unauthorized and redirect error status codes (for example 401, 403, 301, 307)
|
||||
*/
|
||||
readonly status?: number | undefined
|
||||
/**
|
||||
* Returns the type of event, e.g.
|
||||
* "click", "hashchange", or
|
||||
* "submit".
|
||||
*/
|
||||
readonly type: string
|
||||
readonly AT_TARGET: number
|
||||
readonly BUBBLING_PHASE: number
|
||||
readonly CAPTURING_PHASE: number
|
||||
readonly NONE: number
|
||||
composedPath(): any[]
|
||||
initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void
|
||||
preventDefault(): void
|
||||
/**
|
||||
* Invoking this method prevents event from reaching
|
||||
* any registered event listeners after the current one finishes running and, when dispatched in a tree, also prevents event from reaching any
|
||||
* other objects.
|
||||
*/
|
||||
stopImmediatePropagation(): void
|
||||
/**
|
||||
* When dispatched in a tree, invoking this method prevents event from reaching any objects other than the current object.
|
||||
*/
|
||||
stopPropagation(): void
|
||||
}
|
||||
|
||||
interface EventInit {
|
||||
bubbles?: boolean | undefined
|
||||
cancelable?: boolean | undefined
|
||||
composed?: boolean | undefined
|
||||
}
|
||||
|
||||
interface MessageEventInit<T = any> extends EventInit {
|
||||
data?: T | undefined
|
||||
lastEventId?: string | undefined
|
||||
origin?: string | undefined
|
||||
}
|
||||
|
||||
/** The MessageEvent interface represents a message received by a target object. */
|
||||
interface MessageEvent<T = any> extends Event {
|
||||
/**
|
||||
* Returns the data of the message.
|
||||
*/
|
||||
readonly data: T
|
||||
/**
|
||||
* Returns the last event ID string, for server-sent events.
|
||||
*/
|
||||
readonly lastEventId: string
|
||||
/**
|
||||
* Returns the origin of the message, for server-sent events and
|
||||
* cross-document messaging.
|
||||
*/
|
||||
readonly origin: string
|
||||
}
|
56
packages/deno-worker/index.d.ts
vendored
56
packages/deno-worker/index.d.ts
vendored
@ -1,56 +0,0 @@
|
||||
// Type definitions for eventsource 1.1
|
||||
// Project: https://github.com/EventSource/eventsource
|
||||
// Definitions by: Scott Lee Davis <https://github.com/scottleedavis>
|
||||
// Ali Afroozeh <https://github.com/afroozeh>
|
||||
// Pedro Gámez <https://github.com/snakedrak>
|
||||
// Akuukis <https://github.com/Akuukis>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
|
||||
// eventsource uses DOM dependencies which are absent in a browserless environment like node.js.
|
||||
// to avoid compiler errors this monkey patch is used. See more details in:
|
||||
// - sinon: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/11351
|
||||
// - rxjs: https://github.com/ReactiveX/rxjs/issues/1986
|
||||
/// <reference path="./dom-monkeypatch.d.ts" />
|
||||
|
||||
declare class EventSource {
|
||||
static readonly CLOSED: number
|
||||
static readonly CONNECTING: number
|
||||
static readonly OPEN: number
|
||||
|
||||
constructor(
|
||||
url: string,
|
||||
eventSourceInitDict?: EventSource.EventSourceInitDict,
|
||||
)
|
||||
|
||||
readonly CLOSED: number
|
||||
readonly CONNECTING: number
|
||||
readonly OPEN: number
|
||||
readonly url: string
|
||||
readonly readyState: number
|
||||
readonly withCredentials: boolean
|
||||
onopen: (evt: MessageEvent) => any
|
||||
onmessage: (evt: MessageEvent) => any
|
||||
onerror: (evt: MessageEvent) => any
|
||||
addEventListener(type: string, listener: (evt: MessageEvent) => void): void
|
||||
dispatchEvent(evt: Event): boolean
|
||||
removeEventListener(type: string, listener: (evt: MessageEvent) => void): void
|
||||
close(): void
|
||||
}
|
||||
|
||||
declare namespace EventSource {
|
||||
enum ReadyState {
|
||||
CONNECTING = 0,
|
||||
OPEN = 1,
|
||||
CLOSED = 2,
|
||||
}
|
||||
|
||||
interface EventSourceInitDict {
|
||||
withCredentials?: boolean | undefined
|
||||
headers?: object | undefined
|
||||
proxy?: string | undefined
|
||||
https?: object | undefined
|
||||
rejectUnauthorized?: boolean | undefined
|
||||
}
|
||||
}
|
||||
|
||||
export = EventSource
|
@ -1,38 +0,0 @@
|
||||
// import { EventSource as EventSourceClass } from 'https://cdn.jsdelivr.net/gh/MierenManz/EventSource@53f3ec9001d1eac19645c2214652a6a7aa3a51cb/mod.ts'
|
||||
// @deno-types="./index.d.ts"
|
||||
import EventSourceClass from './EventSource2.js'
|
||||
// @deno-types="https://cdn.jsdelivr.net/npm/pocketbase/dist/pocketbase.es.d.ts"
|
||||
import PocketBase from 'https://cdn.jsdelivr.net/npm/pocketbase'
|
||||
declare global {
|
||||
// deno-lint-ignore no-var
|
||||
var EventSource: typeof EventSourceClass
|
||||
}
|
||||
|
||||
globalThis.EventSource = EventSourceClass
|
||||
|
||||
export const init = (klass: typeof PocketBase) => {
|
||||
const POCKETBASE_URL = Deno.env.get('POCKETBASE_URL')
|
||||
const ADMIN_LOGIN = Deno.env.get('ADMIN_LOGIN') || ''
|
||||
const ADMIN_PASSWORD = Deno.env.get('ADMIN_PASSWORD') || ''
|
||||
|
||||
if (!POCKETBASE_URL) {
|
||||
throw new Error(`POCKETBASE_URL must be defined.`)
|
||||
}
|
||||
|
||||
const client = new klass(POCKETBASE_URL)
|
||||
|
||||
const adminAuthWithPassword = async (
|
||||
login = ADMIN_LOGIN,
|
||||
password = ADMIN_PASSWORD,
|
||||
) => {
|
||||
console.log(`Connecting to ${POCKETBASE_URL} with ${ADMIN_LOGIN}`)
|
||||
await client.admins.authWithPassword(login, password)
|
||||
console.log(`Successfully logged in as ${ADMIN_LOGIN}.`)
|
||||
return client
|
||||
}
|
||||
|
||||
return {
|
||||
adminAuthWithPassword,
|
||||
client,
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user