Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f4516c8
query-core: export type QueryObserverListener
milahu Oct 25, 2022
d6b5e35
solid-query: add isRestoring
milahu Oct 25, 2022
f5bec64
solid-query-persist-client: init at 4.13.0
milahu Oct 25, 2022
b465787
examples/solid/basic-typescript: move dep to dev-deps
milahu Oct 25, 2022
7ef366d
examples/solid/offline: init draft
milahu Oct 25, 2022
1000f37
Merge branch 'main' into solid-query-persist-client--init
TkDodo Oct 28, 2022
8764ce6
fixup solid-query-persist-client/package.json
milahu Oct 28, 2022
251dc6e
examples/solid/offline: fix vite config
milahu Oct 28, 2022
dea079b
solid-query-persist-client fixup rollup config
milahu Oct 28, 2022
cf226fc
solid-query-persist-client fixup tsconfig.json
milahu Oct 28, 2022
cb4a14b
solid-query-persist-client fixup root tsconfig.json
milahu Oct 28, 2022
e0b858d
examples/solid/offline: fix react -> solid
milahu Oct 28, 2022
b694c1a
examples/solid/offline fix: start worker
milahu Oct 28, 2022
3564065
examples/solid/offline fix service worker: npx msw init .
milahu Oct 28, 2022
ff9e23f
examples/solid/offline fix types
milahu Oct 28, 2022
b4f113a
examples/solid/offline src/api.ts fix types
milahu Oct 28, 2022
328fbd0
examples/solid/offline vite.config.ts mention vite-plugin-pwa
milahu Oct 28, 2022
48d9629
examples/solid/offline refetchOnWindowFocus: false
milahu Oct 28, 2022
cb44541
examples/solid/offline fix solid routes DRAFT
milahu Oct 28, 2022
3f07a23
examples/solid/offline package.json fix sort order
milahu Oct 29, 2022
891aa3d
examples/solid/offline update src/App.tsx
milahu Oct 29, 2022
b907c04
examples/solid/offline debug src/persister.ts
milahu Oct 29, 2022
c61e60a
examples/solid/offline fix comment, function vs value
milahu Oct 29, 2022
c5d2292
examples/solid/offline disable workaround in src/persister.ts
milahu Oct 29, 2022
300461f
packages/solid-query: fix options on restore
milahu Oct 29, 2022
cf45c39
examples/solid/offline disable refetch on mount + reconnect
milahu Oct 29, 2022
89e3327
examples/solid/offline src/movies.ts rename: comment -> commentLocal
milahu Oct 29, 2022
7e77367
examples/solid/offline src/movies.ts fix mutate
milahu Oct 29, 2022
c022114
examples/solid/offline fixup lodash in src/persister.ts
milahu Oct 29, 2022
93f9a12
examples/solid/offline fix: dont refetch after restore
milahu Oct 29, 2022
5ba3053
examples/solid/offline refactor src/api.ts
milahu Oct 29, 2022
f3ea16a
examples/solid/offline bigger textarea in src/App.tsx
milahu Oct 29, 2022
9be42bf
examples/solid/offline fix default value for commentLocal in src/pers…
milahu Oct 29, 2022
428b1ec
packages/query-core export type QueriesObserverListener
milahu Oct 29, 2022
3f2f022
packages/solid-query createQueries: handle isRestoring
milahu Oct 29, 2022
2ce3b6c
examples/solid/offline update lockfile
milahu Oct 30, 2022
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
2 changes: 1 addition & 1 deletion examples/solid/basic-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
},
"license": "MIT",
"dependencies": {
"@tanstack/solid-query": "^4.3.9",
"solid-js": "^1.5.1"
},
"devDependencies": {
"@tanstack/solid-query": "^4.3.9",
"typescript": "^4.8.2",
"vite": "^3.0.9",
"vite-plugin-solid": "^2.3.9"
Expand Down
10 changes: 10 additions & 0 deletions examples/solid/offline/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"parserOptions": {
"project": "./tsconfig.json",
"sourceType": "module"
},
"rules": {
"react/react-in-jsx-scope": "off",
"jsx-a11y/anchor-is-valid": "off"
}
}
4 changes: 4 additions & 0 deletions examples/solid/offline/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
dist
.yalc
yalc.lock
6 changes: 6 additions & 0 deletions examples/solid/offline/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example

To run this example:

- `npm install`
- `npm run start`
16 changes: 16 additions & 0 deletions examples/solid/offline/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="shortcut icon" type="image/ico" href="/src/assets/favicon.ico" />
<title>Solid App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>

<script src="/src/index.tsx" type="module"></script>
</body>
</html>
338 changes: 338 additions & 0 deletions examples/solid/offline/mockServiceWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
/* eslint-disable */
/* tslint:disable */

/**
* Mock Service Worker (0.39.2).
* @see https://github.com/mswjs/msw
* - Please do NOT modify this file.
* - Please do NOT serve this file on production.
*/

const INTEGRITY_CHECKSUM = '02f4ad4a2797f85668baf196e553d929'
const bypassHeaderName = 'x-msw-bypass'
const activeClientIds = new Set()

self.addEventListener('install', function () {
return self.skipWaiting()
})

self.addEventListener('activate', async function (event) {
return self.clients.claim()
})

self.addEventListener('message', async function (event) {
const clientId = event.source.id

if (!clientId || !self.clients) {
return
}

const client = await self.clients.get(clientId)

if (!client) {
return
}

const allClients = await self.clients.matchAll()

switch (event.data) {
case 'KEEPALIVE_REQUEST': {
sendToClient(client, {
type: 'KEEPALIVE_RESPONSE',
})
break
}

case 'INTEGRITY_CHECK_REQUEST': {
sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE',
payload: INTEGRITY_CHECKSUM,
})
break
}

case 'MOCK_ACTIVATE': {
activeClientIds.add(clientId)

sendToClient(client, {
type: 'MOCKING_ENABLED',
payload: true,
})
break
}

case 'MOCK_DEACTIVATE': {
activeClientIds.delete(clientId)
break
}

case 'CLIENT_CLOSED': {
activeClientIds.delete(clientId)

const remainingClients = allClients.filter((client) => {
return client.id !== clientId
})

// Unregister itself when there are no more clients
if (remainingClients.length === 0) {
self.registration.unregister()
}

break
}
}
})

// Resolve the "main" client for the given event.
// Client that issues a request doesn't necessarily equal the client
// that registered the worker. It's with the latter the worker should
// communicate with during the response resolving phase.
async function resolveMainClient(event) {
const client = await self.clients.get(event.clientId)

if (client.frameType === 'top-level') {
return client
}

const allClients = await self.clients.matchAll()

return allClients
.filter((client) => {
// Get only those clients that are currently visible.
return client.visibilityState === 'visible'
})
.find((client) => {
// Find the client ID that's recorded in the
// set of clients that have registered the worker.
return activeClientIds.has(client.id)
})
}

async function handleRequest(event, requestId) {
const client = await resolveMainClient(event)
const response = await getResponse(event, client, requestId)

// Send back the response clone for the "response:*" life-cycle events.
// Ensure MSW is active and ready to handle the message, otherwise
// this message will pend indefinitely.
if (client && activeClientIds.has(client.id)) {
;(async function () {
const clonedResponse = response.clone()
sendToClient(client, {
type: 'RESPONSE',
payload: {
requestId,
type: clonedResponse.type,
ok: clonedResponse.ok,
status: clonedResponse.status,
statusText: clonedResponse.statusText,
body:
clonedResponse.body === null ? null : await clonedResponse.text(),
headers: serializeHeaders(clonedResponse.headers),
redirected: clonedResponse.redirected,
},
})
})()
}

return response
}

async function getResponse(event, client, requestId) {
const { request } = event
const requestClone = request.clone()
const getOriginalResponse = () => fetch(requestClone)

// Bypass mocking when the request client is not active.
if (!client) {
return getOriginalResponse()
}

// Bypass initial page load requests (i.e. static assets).
// The absence of the immediate/parent client in the map of the active clients
// means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet
// and is not ready to handle requests.
if (!activeClientIds.has(client.id)) {
return await getOriginalResponse()
}

// Bypass requests with the explicit bypass header
if (requestClone.headers.get(bypassHeaderName) === 'true') {
const cleanRequestHeaders = serializeHeaders(requestClone.headers)

// Remove the bypass header to comply with the CORS preflight check.
delete cleanRequestHeaders[bypassHeaderName]

const originalRequest = new Request(requestClone, {
headers: new Headers(cleanRequestHeaders),
})

return fetch(originalRequest)
}

// Send the request to the client-side MSW.
const reqHeaders = serializeHeaders(request.headers)
const body = await request.text()

const clientMessage = await sendToClient(client, {
type: 'REQUEST',
payload: {
id: requestId,
url: request.url,
method: request.method,
headers: reqHeaders,
cache: request.cache,
mode: request.mode,
credentials: request.credentials,
destination: request.destination,
integrity: request.integrity,
redirect: request.redirect,
referrer: request.referrer,
referrerPolicy: request.referrerPolicy,
body,
bodyUsed: request.bodyUsed,
keepalive: request.keepalive,
},
})

switch (clientMessage.type) {
case 'MOCK_SUCCESS': {
return delayPromise(
() => respondWithMock(clientMessage),
clientMessage.payload.delay,
)
}

case 'MOCK_NOT_FOUND': {
return getOriginalResponse()
}

case 'NETWORK_ERROR': {
const { name, message } = clientMessage.payload
const networkError = new Error(message)
networkError.name = name

// Rejecting a request Promise emulates a network error.
throw networkError
}

case 'INTERNAL_ERROR': {
const parsedBody = JSON.parse(clientMessage.payload.body)

console.error(
`\
[MSW] Uncaught exception in the request handler for "%s %s":

${parsedBody.location}

This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\
`,
request.method,
request.url,
)

return respondWithMock(clientMessage)
}
}

return getOriginalResponse()
}

self.addEventListener('fetch', function (event) {
const { request } = event
const accept = request.headers.get('accept') || ''

// Bypass server-sent events.
if (accept.includes('text/event-stream')) {
return
}

// Bypass navigation requests.
if (request.mode === 'navigate') {
return
}

// Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests.
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
return
}

// Bypass all requests when there are no active clients.
// Prevents the self-unregistered worked from handling requests
// after it's been deleted (still remains active until the next reload).
if (activeClientIds.size === 0) {
return
}

const requestId = uuidv4()

return event.respondWith(
handleRequest(event, requestId).catch((error) => {
if (error.name === 'NetworkError') {
console.warn(
'[MSW] Successfully emulated a network error for the "%s %s" request.',
request.method,
request.url,
)
return
}

// At this point, any exception indicates an issue with the original request/response.
console.error(
`\
[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`,
request.method,
request.url,
`${error.name}: ${error.message}`,
)
}),
)
})

function serializeHeaders(headers) {
const reqHeaders = {}
headers.forEach((value, name) => {
reqHeaders[name] = reqHeaders[name]
? [].concat(reqHeaders[name]).concat(value)
: value
})
return reqHeaders
}

function sendToClient(client, message) {
return new Promise((resolve, reject) => {
const channel = new MessageChannel()

channel.port1.onmessage = (event) => {
if (event.data && event.data.error) {
return reject(event.data.error)
}

resolve(event.data)
}

client.postMessage(JSON.stringify(message), [channel.port2])
})
}

function delayPromise(cb, duration) {
return new Promise((resolve) => {
setTimeout(() => resolve(cb()), duration)
})
}

function respondWithMock(clientMessage) {
return new Response(clientMessage.payload.body, {
...clientMessage.payload,
headers: clientMessage.payload.headers,
})
}

function uuidv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0
const v = c == 'x' ? r : (r & 0x3) | 0x8
return v.toString(16)
})
}
Loading