Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$mol_offline refactor, disable cache on page reload via dev server #710

Open
wants to merge 67 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
b22b11a
$mol_offline refactor, disable cache on page reload via dev server
zerkalica Oct 25, 2024
9d5f058
$mol_offline refactor
zerkalica Oct 25, 2024
ce606ba
$mol_offline refactor 2 - simplify respond
zerkalica Oct 25, 2024
ca3be5d
$mol_offline refactor 3 - simplify respond
zerkalica Oct 25, 2024
f965597
$mol_offline refactor 4 - extracted send
zerkalica Oct 25, 2024
81a9ac6
$mol_offline refactor
zerkalica Oct 25, 2024
c83d213
$mol_offline mol_build_obsolete message pass to worker to disable cache
zerkalica Oct 25, 2024
9f3722b
$mol_offline review fixes
zerkalica Oct 26, 2024
84c0253
$mol_offline review fixes 2
zerkalica Oct 26, 2024
c476bb3
$mol_offline fixes 3
zerkalica Oct 26, 2024
f8eab6a
$mol_offline refactor, extract $mol_worker
zerkalica Oct 26, 2024
f17f33b
$mol_offline fix refresh
zerkalica Oct 26, 2024
6efe454
$mol_offline use force-cache
zerkalica Oct 26, 2024
5864255
$mol_offline rules refactored, some bugs fixed
zerkalica Oct 27, 2024
201dcb2
$mol_offline configure cached and blocked urls regexp
zerkalica Oct 27, 2024
cd84bfa
$mol_offline fix regexp
zerkalica Oct 27, 2024
958e207
$mol_worker_service plugins, refactor
zerkalica Oct 28, 2024
2dcd5aa
$mol_offline save ignore_cache between window.reload()
zerkalica Oct 28, 2024
08aa70c
$mol_offline fix test.html caching
zerkalica Oct 28, 2024
3593a0a
$mol_worker refactor
zerkalica Oct 29, 2024
e25b677
$mol_worker fix worker singletone
zerkalica Oct 29, 2024
db14037
$mol_worker fix try/catch in attach
zerkalica Oct 29, 2024
bb46b57
$mol_worker_service renamed to $mol_service, $mol_offline refactor to…
zerkalica Oct 29, 2024
121c90e
$mol_service fix init hook
zerkalica Oct 29, 2024
9f86a71
$mol_service refactor extracted fetch service and notify
zerkalica Oct 29, 2024
7d3ce8a
$mol_fetch_service fix bug with fetch_event binded scope
zerkalica Oct 29, 2024
b168b72
$mol_fetch_service refactor simplify add logic
zerkalica Oct 29, 2024
354468b
$mol_service_plugin extracted, used static, fetch hook moved back to …
zerkalica Oct 30, 2024
7a0cf1e
$mol_service refactor detach method, auto init
zerkalica Oct 30, 2024
d53c252
$mol_service_plugin namespace
zerkalica Oct 30, 2024
21da91e
$mol_service_plugin remove plugin filter, simplify
zerkalica Oct 30, 2024
cbcef3f
$mol_service_plugin moved to $ namespace
zerkalica Oct 30, 2024
ea7d089
$mol_build_client removed unused postMessage
zerkalica Oct 30, 2024
02d8dcc
$mol_service_plugin - include mol_service, add waitUntil to modify, $…
zerkalica Oct 30, 2024
7f7ce8d
$mol_service fix inner namespace
zerkalica Oct 30, 2024
4b10be0
$mol_service_host refactor, better update handling api
zerkalica Oct 31, 2024
d12f71f
$mol_service review fixes
zerkalica Nov 1, 2024
a202b1b
$mol_offline regexp to URL parser
zerkalica Nov 1, 2024
61fb6db
$mol_service separate worker plugins, fixes
zerkalica Nov 1, 2024
5b68802
$mol_service moved to wires, better errors
zerkalica Nov 2, 2024
00dcb49
$mol_service refactor
zerkalica Nov 2, 2024
33b1fc6
$mol_service refactor
zerkalica Nov 2, 2024
3ee7e45
$mol_worker async
zerkalica Nov 2, 2024
6fabdac
$mol_offline refactoring
zerkalica Nov 3, 2024
10b0cef
$mol_service push event handler added, sync scope
zerkalica Nov 3, 2024
1efed9b
$mol_service_worker refactor, extracted prompt events
zerkalica Nov 3, 2024
7f008e6
$mol_service_worker type fix
zerkalica Nov 3, 2024
2169769
$mol_service_worker simple notify
zerkalica Nov 3, 2024
2265c73
$mol_service_prompt moved to offline, refactor
zerkalica Nov 3, 2024
9dafc68
$mol_offline web
zerkalica Nov 3, 2024
7778411
$mol_service_worker fix start
zerkalica Nov 4, 2024
a2aa4c3
$mol_offline fix prompt offline
zerkalica Nov 4, 2024
b13f25e
Merge branch 'master' of github.com:hyoo-ru/mam_mol into offline2
zerkalica Nov 4, 2024
6715f91
$mol_service_worker minor fixes
zerkalica Nov 5, 2024
001e562
$mol_fetch removed unused request
zerkalica Nov 5, 2024
60811c1
$mol_service refactor, split self and worker
zerkalica Nov 6, 2024
d579f8a
$mol_service fixes
zerkalica Nov 6, 2024
370372a
$mol_service fixes 2
zerkalica Nov 6, 2024
a33dcaf
$mol_worker rpc refactored
zerkalica Nov 6, 2024
7849b8a
$mol_notify fixes
zerkalica Nov 6, 2024
854046d
$mol_rpc_client fix call bug
zerkalica Nov 7, 2024
667e459
Merge branch 'master' of github.com:hyoo-ru/mam_mol into offline2
zerkalica Dec 29, 2024
e995539
Merge branch 'master' of github.com:hyoo-ru/mam_mol into offline2
zerkalica Jan 3, 2025
48fe3a1
$mol_offline add require-corp header
zerkalica Jan 3, 2025
3cb5e0f
$mol_file_node fix error handler
zerkalica Jan 3, 2025
44a1890
Merge branch 'master' of github.com:hyoo-ru/mam_mol into offline2
zerkalica Jan 9, 2025
078f6a2
$mol_offline corp disable by default
zerkalica Jan 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/client/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ function $mol_build_client() {

socket.onmessage = message => {
if( message.data !== '$mol_build_obsolete' ) return
postMessage('mol_build_obsolete')
location.reload()
}

Expand Down
2 changes: 1 addition & 1 deletion offline/install/install.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace $ {
try {
$mol_offline()
$mol_offline.main.run()
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
} catch( error ) {
console.error( error )
}
Expand Down
13 changes: 12 additions & 1 deletion offline/offline.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
namespace $ {

export function $mol_offline( ) {}
export type $mol_offline_web_message = {
ignore_cache?: boolean
blocked_urls?: readonly string[]
cached_urls?: readonly string[]
}

export class $mol_offline extends $mol_worker {
static main = new $mol_offline

blocked(urls?: readonly string[]) { return urls ?? [] }
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
cached(urls?: readonly string[]) { return urls ?? [] }
}

}
224 changes: 123 additions & 101 deletions offline/offline.web.ts
Original file line number Diff line number Diff line change
@@ -1,109 +1,131 @@
/// <reference lib="webworker" />

namespace $ {

const blacklist = new Set([
'//cse.google.com/adsense/search/async-ads.js'
])

/** Installs service worker proxy, which caches all requests and respond from cache on http errors. */
export function $mol_offline_web() {

if( typeof window === 'undefined' ) {

self.addEventListener( 'install' , ( event : any )=> {
;( self as any ).skipWaiting()
} )

self.addEventListener( 'activate' , ( event : any )=> {

// caches.delete( '$mol_offline' )

;( self as any ).clients.claim()

$$.$mol_log3_done({
place: '$mol_offline',
message: 'Activated',
})

} )

self.addEventListener( 'fetch' , ( event : any )=> {

const request = event.request as Request

if( blacklist.has( request.url.replace( /^https?:/, '' ) ) ) {
return event.respondWith(
new Response(
null,
{
status: 418,
statusText: 'Blocked'
},
)
export class $mol_offline_web extends $mol_worker_web {
static main = new $mol_offline_web

override path() { return 'web.js' }

override ready(reg: $mol_worker_reg_active) {
reg.active.postMessage({ ignore_cache: false })
}

override async registration_init() {
window.addEventListener('message', this.window_message.bind(this))
return super.registration_init()
}

protected window_message(e: MessageEvent) {
const data = e.data
if (data === 'mol_build_obsolete') return this.send({ ignore_cache: true })
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
}

blocked(urls?: readonly string[]) {
urls = urls ?? this.blocked_urls
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
this.send({ blocked_urls: urls })
return urls
}

cached(urls?: readonly string[]) {
urls = urls ?? this.cached_urls
this.send({ cached_urls: urls })
return urls
}

override message(event: ExtendableMessageEvent) {
const data = event.data as string | null | $mol_offline_web_message
if ( ! data || typeof data !== 'object' ) return

if (data.ignore_cache !== undefined) this.ignore_cache = data.ignore_cache
if (data.blocked_urls) this.blocked_regexp = this.url_regexp(data.blocked_urls)
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
if (data.cached_urls) this.cached_regexp = this.url_regexp(data.cached_urls)
}


override activate(event: ExtendableEvent) {
super.activate(event)
$$.$mol_log3_done({
place: '$mol_offline',
message: 'Activated',
})
}

protected blocked_urls = [
'//cse.google.com/adsense/search/async-ads.js'
] as readonly string[]

protected cached_urls = [
'.*/index.html'
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
] as readonly string[]

protected blocked_regexp = this.url_regexp(this.blocked_urls)
protected cached_regexp = this.url_regexp(this.cached_urls)

url_regexp(list: readonly string[]) {
return new RegExp(`#^https?:(?:(?:${list.map(url_reg => url_reg.replace('.', '\.')).join(')|(?:')}))#`)
zerkalica marked this conversation as resolved.
Show resolved Hide resolved
}

protected ignore_cache = false

override fetch_event(event: FetchEvent) {
const request = event.request

if( this.blocked_regexp.test(request.url) ) {
return event.respondWith(
new Response(
null,
{
status: 418,
statusText: 'Blocked'
},
)
)
}

if( request.method !== 'GET' ) return
if( !/^https?:/.test( request.url ) ) return
if( /\?/.test( request.url ) ) return
if( request.cache === 'no-store' ) return

event.respondWith( this.respond(event.request) )
}

async respond(request: Request) {
let fallback_header

const force_cache = this.cached_regexp.test(request.url)
const no_cache = request.cache === 'no-cache' && ! force_cache

if (this.ignore_cache || request.cache === 'reload' || no_cache) {

if (request.cache !== 'no-cache' && request.cache !== 'reload') {
request = new Request(request, { cache: 'no-cache' })
}

if( request.method !== 'GET' ) return
if( !/^https?:/.test( request.url ) ) return
if( /\?/.test( request.url ) ) return
if( request.cache === 'no-store' ) return

const fetch_data = () => fetch( request ).then( response => {
if (response.status !== 200) return response
event.waitUntil(
caches.open( '$mol_offline' ).then(
cache => cache.put( request , response )
)
)

return response.clone()
} )

const fresh = request.cache === 'force-cache' ? null : fetch_data()

if (fresh) event.waitUntil( fresh )

event.respondWith(
caches.match( request ).then(
cached => request.cache === 'no-cache' || request.cache === 'reload'
? ( cached
? fresh!
.then(actual => {
if (actual.status === cached.status) return actual
throw new Error(
`${actual.status}${actual.statusText ? ` ${actual.statusText}` : ''}`,
{ cause: actual }
)
})
.catch((err: Error) => {
const cloned = cached.clone()
const message = `${err.cause instanceof Response ? '' : '500 '}${err.message} $mol_offline fallback to cache`
cloned.headers.set( '$mol_offline_remote_status', message )
return cloned
})
: fresh
)
: ( cached || fresh || fetch_data() )

// fetch with fallback to cache if statuses not match
try {
const actual = await fetch(request)
if (actual.status < 400) return actual

throw new Error(
`${actual.status}${actual.statusText ? ` ${actual.statusText}` : ''}`,
{ cause: actual }
)
)

})

self.addEventListener( 'beforeinstallprompt' , ( event : any )=> event.prompt() )

} else if( location.protocol !== 'https:' && location.hostname !== 'localhost' ) {
console.warn( 'HTTPS or localhost is required for service workers.' )
} else if( !navigator.serviceWorker ) {
console.warn( 'Service Worker is not supported.' )
} else {
navigator.serviceWorker.register( 'web.js' ).then( reg => {
// reg.addEventListener( 'updatefound', ()=> {
// const worker = reg.installing!
// worker.addEventListener( 'statechange', ()=> {
// if( worker.state !== 'activated' ) return
// window.location.reload()
// } )
// } )
} )
} catch (err) {
fallback_header = `${(err as Error).cause instanceof Response ? '' : '500 '}${
(err as Error).message} $mol_offline fallback to cache`
}
}

const cached = await fetch(new Request(request, { cache: 'force-cache' }))

if (! fallback_header || cached.headers.get('$mol_offline_remote_status')) return cached

const clone = new Response(cached.body, cached)
clone.headers.set( '$mol_offline_remote_status', fallback_header ?? '')

return clone
}

}
Expand Down
9 changes: 9 additions & 0 deletions worker/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace $ {
export class $mol_worker extends $mol_object {
run() {
return false
}

async send(data: unknown) {}
}
}
Loading
Loading