diff --git a/.eslintrc.cjs b/.eslintrc.cjs
index 5701aaa77..3de581150 100644
--- a/.eslintrc.cjs
+++ b/.eslintrc.cjs
@@ -73,10 +73,7 @@ module.exports = {
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': [
'warn',
- {
- additionalHooks:
- 'usePromise|useLazyPromise|usePromiseOnSituationChange',
- },
+ { additionalHooks: 'usePromise|useLazyPromise' },
],
'@typescript-eslint/no-unsafe-call': 'warn',
diff --git a/package.json b/package.json
index b095dab56..82b2af072 100644
--- a/package.json
+++ b/package.json
@@ -64,8 +64,8 @@
"rollup": "^3.10.0",
"@types/koa": "^2.13.8",
"@types/react": "^18.2.18",
- "react": "^18.2.0",
- "react-dom": "^18.2.0",
+ "react": "18.3.0-canary-e5205658f-20230913",
+ "react-dom": "18.3.0-canary-e5205658f-20230913",
"styled-components": "^6.0.7",
"@publicodes/api": "betagouv/publicodes#head=publicodes-in-worker&workspace=@publicodes/api&v0",
"publicodes": "betagouv/publicodes#head=publicodes-in-worker&workspace=publicodes&v0",
diff --git a/site/build/prerender-worker.ts b/site/build/prerender-worker.ts
index 1ee58cb10..e264d8198 100644
--- a/site/build/prerender-worker.ts
+++ b/site/build/prerender-worker.ts
@@ -16,18 +16,14 @@ const headTagsEnd = ''
const regexHTML = new RegExp(htmlBodyStart + '[\\s\\S]+' + htmlBodyEnd, 'm')
const regexHelmet = new RegExp(headTagsStart + '[\\s\\S]+' + headTagsEnd, 'm')
+const script = ``
+
interface Params {
site: string
url: string
lang: string
}
-const script = `
-
-`
-
export default async ({ site, url, lang }: Params) => {
const template =
cache[site] ??
@@ -36,13 +32,20 @@ export default async ({ site, url, lang }: Params) => {
cache[site] ??= template
// // TODO: Add CI test to enforce meta tags on SSR pages
- const { html, styleTags, helmet } = await render(url, lang)
+ const { html, styleTags, helmet } = (await render(url, lang)) as {
+ html: string
+ styleTags: string
+ helmet?: { title: string; meta: string }
+ }
const page = template
- .replace(regexHTML, html)
+ .replace(regexHTML, html.trim())
.replace('', script)
.replace('', styleTags)
- .replace(regexHelmet, helmet.title.toString() + helmet.meta.toString())
+ .replace(
+ regexHelmet,
+ (helmet?.title.toString() ?? '') + (helmet?.meta.toString() ?? '')
+ )
const dir = path.join(dirname, '../dist/prerender', site, decodeURI(url))
diff --git a/site/build/prerender.ts b/site/build/prerender.ts
index 2eebb239f..298f1e1c6 100644
--- a/site/build/prerender.ts
+++ b/site/build/prerender.ts
@@ -21,6 +21,7 @@ export const pagesToPrerender: {
infrance: string[]
} = {
'mon-entreprise': [
+ '/test-worker',
'/documentation/artiste‑auteur/cotisations/CSG‑CRDS/abattement',
// '/iframes/pamc',
// '/iframes/simulateur-embauche',
diff --git a/site/package.json b/site/package.json
index 04fa66a62..b1979e9b2 100644
--- a/site/package.json
+++ b/site/package.json
@@ -75,10 +75,10 @@
"modele-social": "workspace:^",
"publicodes": "^1.0.0-beta.73",
"publicodes-react": "^1.0.0-beta.73",
- "react": "^18.2.0",
+ "react": "18.3.0-canary-e5205658f-20230913",
"react-aria": "^3.24.0",
"react-day-picker": "^8.7.1",
- "react-dom": "^18.2.0",
+ "react-dom": "18.3.0-canary-e5205658f-20230913",
"react-easy-emoji": "^1.8.1",
"react-flip-move": "^3.0.5",
"react-helmet-async": "^1.3.0",
@@ -86,7 +86,7 @@
"react-instantsearch": "^6.38.1",
"react-instantsearch-dom": "^6.38.1",
"react-redux": "^8.0.5",
- "react-router-dom": "^6.14.2",
+ "react-router-dom": "^6.15.0",
"react-signature-pad-wrapper": "^3.3.1",
"react-spring": "^9.5.5",
"react-stately": "^3.22.0",
@@ -118,7 +118,7 @@
"@storybook/react-vite": "^7.0.5",
"@storybook/testing-library": "^0.1.0",
"@types/history": "^5.0.0",
- "@types/react": "^18.2.21",
+ "@types/react": "^18.2.18",
"@types/react-dom": "^18.2.7",
"@types/react-instantsearch-dom": "^6.12.3",
"@types/react-redux": "^7.1.25",
diff --git a/site/source/components/App.tsx b/site/source/components/App.tsx
index c023d98f4..17005b6e4 100644
--- a/site/source/components/App.tsx
+++ b/site/source/components/App.tsx
@@ -1,13 +1,18 @@
import {
- SuspensePromise,
- useAsyncShallowCopy,
- useLazyPromise,
+ PromiseSSR,
usePromise,
useWorkerEngine,
} from '@publicodes/worker-react'
import { ErrorBoundary } from '@sentry/react'
import { FallbackRender } from '@sentry/react/types/errorboundary'
-import { ComponentProps, StrictMode, useEffect, useState } from 'react'
+import {
+ ComponentProps,
+ StrictMode,
+ Suspense,
+ use,
+ useEffect,
+ useState,
+} from 'react'
import { useTranslation } from 'react-i18next'
import { Route, Routes } from 'react-router-dom'
import { css, styled } from 'styled-components'
@@ -42,15 +47,22 @@ type RootProps = {
basename: ProviderProps['basename']
}
+const TestWorkerEngineWrapper = () => (
+
+
+
+)
+
const TestWorkerEngine = () => {
const [refresh, setRefresh] = useState(0)
const workerEngine = useWorkerEngine()
- const [, trigger] = useLazyPromise(
- async () => workerEngine.asyncSetSituation({ SMIC: '1000€/mois' }),
- [workerEngine],
- { defaultValue: 'loading...' }
- )
+ // const [, trigger] = useLazyPromise(
+ // async () => workerEngine.asyncSetSituation({ SMIC: '1000€/mois' }),
+ // [workerEngine],
+ // { defaultValue: 'loading...' }
+ // )
+ const trigger = () => workerEngine.asyncSetSituation({ SMIC: '1000€/mois' })
const date = workerEngine.getRule('date')
const SMIC = workerEngine.getRule('SMIC')
@@ -58,38 +70,63 @@ const TestWorkerEngine = () => {
// const parsedRules = useAsyncParsedRules()
const parsedRules = workerEngine.getParsedRules()
+ // const resultSmic = usePromise(
+ // () => workerEngine.asyncEvaluate('SMIC'),
+ // [workerEngine],
+ // 'loading...'
+ // )
+
const resultSmic = usePromise(
- () => workerEngine.asyncEvaluate('SMIC'),
- [workerEngine],
- 'loading...'
+ () =>
+ workerEngine.asyncEvaluate('SMIC').then((val) => {
+ console.log('**************************************')
+
+ return val
+ }),
+ [workerEngine]
+ )
+ const resultSmicx = usePromise(
+ () =>
+ workerEngine.asyncEvaluate('SMIC').then((val) => {
+ console.log('¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤')
+
+ return val
+ }),
+ [workerEngine]
+ )
+ console.log('#####>', resultSmic, resultSmicx)
+
+ // const [resultLazySmic, triggerLazySmic] = useLazyPromise(
+ // () => workerEngine.asyncEvaluate('SMIC'),
+ // [workerEngine],
+ // 'wait 3sec...'
+ // )
+
+ useEffect(
+ () => {
+ void (async () => {
+ await workerEngine.isWorkerReady
+ setTimeout(() => {
+ // void triggerLazySmic()
+ }, 3000)
+ })()
+ },
+ [
+ // triggerLazySmic, workerEngine.isWorkerReady
+ ]
)
- const [resultLazySmic, triggerLazySmic] = useLazyPromise(
- () => workerEngine.asyncEvaluate('SMIC'),
- [workerEngine],
- 'wait 3sec...'
- )
-
- useEffect(() => {
- void (async () => {
- await workerEngine.isWorkerReady
- setTimeout(() => {
- void triggerLazySmic()
- }, 3000)
- })()
- }, [triggerLazySmic, workerEngine.isWorkerReady])
-
- const workerEngineCopy = useAsyncShallowCopy(workerEngine)
+ // const workerEngineCopy = useAsyncShallowCopy(workerEngine)
// // const workerEngineCopy = workerEngine
- console.log('=========>', workerEngine, workerEngineCopy)
+ // console.log('=========>', workerEngine, workerEngineCopy)
- const [, triggerCopy] = useLazyPromise(async () => {
- console.log('+++++++++>', workerEngineCopy)
+ // const [, triggerCopy] = useLazyPromise(async () => {
+ // console.log('+++++++++>', workerEngineCopy)
- await workerEngineCopy?.asyncSetSituation({
- SMIC: '2000€/mois',
- })
- }, [workerEngineCopy])
+ // await workerEngineCopy?.asyncSetSituation({
+ // SMIC: '2000€/mois',
+ // })
+ // }, [workerEngineCopy])
// const dateCopy = useAsyncGetRule('date', {
// defaultValue: 'loading...',
@@ -100,54 +137,80 @@ const TestWorkerEngine = () => {
// workerEngine: workerEngineCopy,
// })
- const dateCopy = workerEngineCopy?.getRule('date')
- const parsedRulesCopy = workerEngineCopy?.getParsedRules()
+ // const dateCopy = workerEngineCopy?.getRule('date')
+ // const parsedRulesCopy = workerEngineCopy?.getParsedRules()
- const resultSmicCopy = usePromise(
- async () =>
- !workerEngineCopy
- ? 'still loading...'
- : workerEngineCopy.asyncEvaluate('SMIC'),
- [workerEngineCopy],
- 'loading...'
- )
+ // const resultSmicCopy = usePromise(
+ // async () =>
+ // !workerEngineCopy
+ // ? 'still loading...'
+ // : workerEngineCopy.asyncEvaluate('SMIC'),
+ // [workerEngineCopy],
+ // 'loading...'
+ // )
+ // const resultSmicCopy = !workerEngineCopy
+ // ? 'still loading...'
+ // : use(workerEngineCopy.asyncEvaluate('SMIC'))
- const [resultLazySmicCopy, triggerLazySmicCopy] = useLazyPromise(
- async () =>
- !workerEngineCopy
- ? 'still loading...'
- : workerEngineCopy.asyncEvaluate('SMIC'),
- [workerEngineCopy],
- 'wait 3sec...'
- )
+ // const [resultLazySmicCopy, triggerLazySmicCopy] = useLazyPromise(
+ // async () =>
+ // !workerEngineCopy
+ // ? 'still loading...'
+ // : workerEngineCopy.asyncEvaluate('SMIC'),
+ // [workerEngineCopy],
+ // 'wait 3sec...'
+ // )
- useEffect(() => {
- // console.log('useEffect')
+ // useEffect(
+ // () => {
+ // // console.log('useEffect')
- void (async () => {
- await workerEngine.isWorkerReady
- setTimeout(() => {
- void triggerLazySmicCopy()
- }, 3000)
- })()
- }, [triggerLazySmicCopy, workerEngine.isWorkerReady])
+ // void (async () => {
+ // await workerEngine.isWorkerReady
+ // setTimeout(() => {
+ // // void triggerLazySmicCopy()
+ // }, 3000)
+ // })()
+ // },
+ // [
+ // // triggerLazySmicCopy, workerEngine.isWorkerReady
+ // ]
+ // )
- const { asyncSetSituation } = workerEngineCopy ?? {}
- usePromise(async () => {
- // console.log('**************>', workerEngineCopy, resultSmic)
+ // const { asyncSetSituation } = workerEngineCopy ?? {}
+ // usePromise(async () => {
+ // // console.log('**************>', workerEngineCopy, resultSmic)
- if (
- resultSmic &&
- typeof resultSmic !== 'string' &&
- typeof resultSmic.nodeValue === 'number'
- ) {
- // console.log('ooooooooooooooooooo', resultSmic)
+ // if (
+ // resultSmic &&
+ // typeof resultSmic !== 'string' &&
+ // typeof resultSmic.nodeValue === 'number'
+ // ) {
+ // // console.log('ooooooooooooooooooo', resultSmic)
- await asyncSetSituation?.({
- SMIC: resultSmic.nodeValue + '€/mois',
- })
- }
- }, [asyncSetSituation, resultSmic])
+ // await asyncSetSituation?.({
+ // SMIC: resultSmic.nodeValue + '€/mois',
+ // })
+ // }
+ // }, [asyncSetSituation, resultSmic])
+
+ // use(
+ // (async () => {
+ // // console.log('**************>', workerEngineCopy, resultSmic)
+
+ // if (
+ // resultSmic &&
+ // typeof resultSmic !== 'string' &&
+ // typeof resultSmic.nodeValue === 'number'
+ // ) {
+ // // console.log('ooooooooooooooooooo', resultSmic)
+
+ // await asyncSetSituation?.({
+ // SMIC: resultSmic.nodeValue + '€/mois',
+ // })
+ // }
+ // })()
+ // )
return (
@@ -178,40 +241,40 @@ const TestWorkerEngine = () => {
resultLazySmic:{' '}
- {JSON.stringify(
+ {/* {JSON.stringify(
typeof resultLazySmic === 'string'
? resultLazySmic
: resultLazySmic?.nodeValue
- )}
+ )} */}
-
workerEngineCopy: {JSON.stringify(workerEngineCopy?.engineId)}
+ {/*
workerEngineCopy: {JSON.stringify(workerEngineCopy?.engineId)}
*/}
dateCopy title:{' '}
- {JSON.stringify(
+ {/* {JSON.stringify(
typeof dateCopy === 'string' ? dateCopy : dateCopy?.title
- )}
+ )} */}
parsedRulesCopy length:{' '}
- {JSON.stringify(Object.entries(parsedRulesCopy ?? {}).length)}
+ {/* {JSON.stringify(Object.entries(parsedRulesCopy ?? {}).length)} */}
-
+ {/*
resultSmicCopy:{' '}
{JSON.stringify(
typeof resultSmicCopy === 'string'
? resultSmicCopy
: resultSmicCopy?.nodeValue
)}
-
+ */}
resultLazySmicCopy:{' '}
- {JSON.stringify(
+ {/* {JSON.stringify(
typeof resultLazySmicCopy === 'string'
? resultLazySmicCopy
: resultLazySmicCopy?.nodeValue
- )}
+ )} */}
)
@@ -233,73 +296,39 @@ RootProps) {
// [rules]
// )
+ const [promiseSSR, setPromiseSSR] = useState(false)
+
+ const elems = (
+
+
+
+
+
+ )
+
return (
-
-
-
-
-
+
+ {promiseSSR ? {elems} : elems}
)
}
const Router = () => {
- /*
- const exampleSyncValue = usePromiseOnSituationChange(
- () => asyncEvaluate('SMIC'),
- []
- )?.nodeValue
-
- const exampleSyncValueWithDefault = usePromiseOnSituationChange(
- async () => (await asyncEvaluate('SMIC')).nodeValue,
- [],
- 'loading...'
- )
-
- const [exampleAsyncValue, fireEvaluate] = useLazyPromise(
- async (param: PublicodesExpression) =>
- (await asyncEvaluate(param)).nodeValue,
- [],
- 42
- )
-
- usePromise(async () => {
- let count = 0
- const interval = setInterval(() => {
- void fireEvaluate(count++ % 2 === 0 ? 'date' : 'SMIC')
- if (count === 7) clearInterval(interval)
- }, 1000)
-
- await new Promise((resolve) => setTimeout(resolve, 3000))
- await asyncSetSituation({ date: '01/01/2022' })
- await new Promise((resolve) => setTimeout(resolve, 3000))
- await asyncSetSituation({ date: '01/01/2021' })
- await new Promise((resolve) => setTimeout(resolve, 3000))
- }, [fireEvaluate])
-
- */
-
return (
<>
- {/* exemple sans valeur par defaut : {JSON.stringify(exampleSyncValue)}
-
- exemple avec valeur par defaut :{' '}
- {JSON.stringify(exampleSyncValueWithDefault)}
- exemple d'execution manuel : {JSON.stringify(exampleAsyncValue)} */}
- {/* */}
-
- {/* */}
-
-
-
-
- >
+
}
/>
@@ -355,52 +384,54 @@ const App = () => {
-
- } />
+
+
+ } />
- {/* }
/> */}
- }
- />
- }
- />
-
- }
- />
- }
- />
- }
- />
- } />
- } />
- }
- />
- }
- />
- } />
+ }
+ />
+ }
+ />
+
+ }
+ />
+ }
+ />
+ }
+ />
+ } />
+ } />
+ }
+ />
+ }
+ />
+ } />
- } />
-
+ } />
+
+
diff --git a/site/source/components/Provider.tsx b/site/source/components/Provider.tsx
index 332b9e7da..802e6720b 100644
--- a/site/source/components/Provider.tsx
+++ b/site/source/components/Provider.tsx
@@ -1,28 +1,28 @@
import NodeWorker from '@eshaz/web-worker'
import { createWorkerEngineClient } from '@publicodes/worker'
-import {
- SuspensePromise,
- useWorkerEngine,
- WorkerEngineProvider,
-} from '@publicodes/worker-react'
+import { useWorkerEngine, WorkerEngineProvider } from '@publicodes/worker-react'
import { OverlayProvider } from '@react-aria/overlays'
import { ErrorBoundary } from '@sentry/react'
import i18next from 'i18next'
-import { createContext, ReactNode } from 'react'
+import { createContext, ReactNode, Suspense } from 'react'
import { HelmetProvider } from 'react-helmet-async'
import { I18nextProvider, Trans, useTranslation } from 'react-i18next'
import { Provider as ReduxProvider } from 'react-redux'
import { BrowserRouter } from 'react-router-dom'
+// import NodeWorker from 'whatwg-worker'
+
import logo from '@/assets/images/logo-monentreprise.svg'
import FeedbackForm from '@/components/Feedback/FeedbackForm'
import { ThemeColorsProvider } from '@/components/utils/colors'
import { DisableAnimationOnPrintProvider } from '@/components/utils/DisableAnimationContext'
+import { Loader } from '@/design-system/icons/Loader'
import { Container, Grid } from '@/design-system/layout'
import DesignSystemThemeProvider from '@/design-system/root'
import { H1, H4 } from '@/design-system/typography/heading'
import { Link } from '@/design-system/typography/link'
import { Body, Intro } from '@/design-system/typography/paragraphs'
+import { ClientOnly } from '@/hooks/useClientOnly'
// import { workerClient } from '@/entries/entry-fr'
import { EmbededContextProvider } from '@/hooks/useIsEmbedded'
import { Actions } from '@/worker/socialWorkerEngine.worker'
@@ -43,11 +43,13 @@ console.time('start!')
export const worker = import.meta.env.SSR
? // Node doesn't support web worker :( upvote issue here: https://github.com/nodejs/node/issues/43583
new NodeWorker(
- new URL('../worker/socialWorkerEngine.worker.js', import.meta.url),
+ new URL('./worker/socialWorkerEngine.worker.js', import.meta.url),
{ type: 'module' }
)
: new SocialeWorkerEngine()
+console.log('worker', worker)
+
const workerClient = createWorkerEngineClient(worker, {
initParams: [{ basename: 'mon-entreprise' }],
})
@@ -84,7 +86,7 @@ export default function Provider({
-
+ }>
)}
>
- {!import.meta.env.SSR &&
- import.meta.env.MODE === 'production' &&
- 'serviceWorker' in navigator && }
+
+ {!import.meta.env.SSR &&
+ 'serviceWorker' in navigator && }
+
@@ -109,7 +112,7 @@ export default function Provider({
-
+
diff --git a/site/source/components/SimulateurOrAssistantPage.tsx b/site/source/components/SimulateurOrAssistantPage.tsx
index e150f3cb0..199a3beb8 100644
--- a/site/source/components/SimulateurOrAssistantPage.tsx
+++ b/site/source/components/SimulateurOrAssistantPage.tsx
@@ -1,4 +1,4 @@
-import { ComponentPropsWithoutRef } from 'react'
+import { ComponentPropsWithoutRef, Suspense } from 'react'
import { useSelector } from 'react-redux'
import { useLocation } from 'react-router-dom'
import { styled } from 'styled-components'
@@ -102,7 +102,9 @@ export default function SimulateurOrAssistantPage() {
>
)}
-
+
+
+
{!inIframe && (
<>
diff --git a/site/source/components/Simulation/SimulationGoal.tsx b/site/source/components/Simulation/SimulationGoal.tsx
index bc6cf862b..5205d08ca 100644
--- a/site/source/components/Simulation/SimulationGoal.tsx
+++ b/site/source/components/Simulation/SimulationGoal.tsx
@@ -1,7 +1,7 @@
-import { useWorkerEngine } from '@publicodes/worker-react'
+import { usePromise, useWorkerEngine } from '@publicodes/worker-react'
import { DottedName } from 'modele-social'
import { formatValue, PublicodesExpression } from 'publicodes'
-import React, { useCallback, useState } from 'react'
+import React, { Suspense, useCallback, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { styled } from 'styled-components'
@@ -9,7 +9,6 @@ import { ForceThemeProvider } from '@/components/utils/DarkModeContext'
import { Grid } from '@/design-system/layout'
import { Strong } from '@/design-system/typography'
import { Body, SmallBody } from '@/design-system/typography/paragraphs'
-import { usePromise } from '@/hooks/usePromise'
import { updateSituation } from '@/store/actions/actions'
import { targetUnitSelector } from '@/store/selectors/simulationSelectors'
@@ -59,7 +58,7 @@ export function SimulationGoal({
arrondi: round ? 'oui' : 'non',
...(!isTypeBoolean ? { unité: currentUnit } : {}),
}),
- [workerEngine, dottedName, round, isTypeBoolean, currentUnit]
+ [currentUnit, dottedName, isTypeBoolean, round, workerEngine]
)
const rule = workerEngine.getRule(dottedName)
@@ -143,33 +142,35 @@ export function SimulationGoal({
{!isFocused && !small && evaluation && (
)}
- setFocused(true)}
- onBlur={() => setFocused(false)}
- onChange={onChange}
- missing={
- evaluation && dottedName in evaluation.missingVariables
- }
- small={small}
- formatOptions={{
- maximumFractionDigits: round ? 0 : 2,
- }}
- />
+
+ setFocused(true)}
+ onBlur={() => setFocused(false)}
+ onChange={onChange}
+ missing={
+ evaluation && dottedName in evaluation.missingVariables
+ }
+ small={small}
+ formatOptions={{
+ maximumFractionDigits: round ? 0 : 2,
+ }}
+ />
+
) : (
diff --git a/site/source/components/conversation/Conversation.tsx b/site/source/components/conversation/Conversation.tsx
index dfacae56c..59c813824 100644
--- a/site/source/components/conversation/Conversation.tsx
+++ b/site/source/components/conversation/Conversation.tsx
@@ -1,7 +1,7 @@
import { useWorkerEngine, WorkerEngine } from '@publicodes/worker-react'
import { DottedName } from 'modele-social'
import { PublicodesExpression, RuleNode } from 'publicodes'
-import React, { useCallback, useEffect, useState } from 'react'
+import React, { Suspense, useCallback, useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useDispatch, useSelector } from 'react-redux'
@@ -143,13 +143,15 @@ export default function Conversation({
'Répondez à quelques questions additionnelles afin de préciser votre résultat.'
)}
-
+
+
+
diff --git a/site/source/components/conversation/RuleInput.tsx b/site/source/components/conversation/RuleInput.tsx
index 429165921..10169b134 100644
--- a/site/source/components/conversation/RuleInput.tsx
+++ b/site/source/components/conversation/RuleInput.tsx
@@ -108,9 +108,6 @@ export default function RuleInput({
const value = evaluation?.nodeValue
- const isMultipleChoices =
- rule && isMultiplePossibilities(workerEngine, dottedName)
-
const choice = usePromise(
() => getOnePossibilityOptions(workerEngine, dottedName),
[workerEngine, dottedName]
@@ -139,7 +136,7 @@ export default function RuleInput({
}
const meta = getMeta<{ affichage?: string }>(rule.rawNode, {})
- if (isMultipleChoices) {
+ if (rule && isMultiplePossibilities(workerEngine, dottedName)) {
return (
- {i18n.language === 'fr' && }
+ {i18n.language === 'fr' && }
)
diff --git a/site/source/components/utils/EngineContext.tsx b/site/source/components/utils/EngineContext.tsx
index 786daf885..b1f2f4504 100644
--- a/site/source/components/utils/EngineContext.tsx
+++ b/site/source/components/utils/EngineContext.tsx
@@ -170,6 +170,7 @@ export const useSetupSafeSituation = (workerEngine?: WorkerEngine) => {
console.log('set rawSituation', rawSituation, workerEngine)
void asyncSetSituation(rawSituation)
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [asyncSetSituation, rawSituation])
// try {
diff --git a/site/source/entries/entry-en.tsx b/site/source/entries/entry-en.tsx
index a51b1238d..172298bf6 100644
--- a/site/source/entries/entry-en.tsx
+++ b/site/source/entries/entry-en.tsx
@@ -1,27 +1,28 @@
import { I18nProvider } from '@react-aria/i18n'
import { withProfiler } from '@sentry/react'
-import { createRoot } from 'react-dom/client'
+import { createRoot, hydrateRoot } from 'react-dom/client'
import App from '../components/App'
import i18next from '../locales/i18n'
-import ruleTranslations from '../locales/rules-en.yaml'
-import translateRules from '../locales/translateRules'
+// import ruleTranslations from '../locales/rules-en.yaml'
+// import translateRules from '../locales/translateRules'
import translations from '../locales/ui-en.yaml'
import '../api/sentry'
-export const AppEn = () => (
+const AppEn = () => (
- translateRules('en', ruleTranslations, rules)
- }
+ // TODO: translate worker
+ // rulesPreTransform={(rules) =>
+ // translateRules('en', ruleTranslations, rules)
+ // }
/>
)
-const AppEnWithProfiler = withProfiler(AppEn)
+export const AppEnWithProfiler = withProfiler(AppEn)
i18next.addResourceBundle('en', 'translation', translations)
@@ -32,6 +33,12 @@ if (!import.meta.env.SSR) {
)
const container = document.querySelector('#js') as Element
- const root = createRoot(container)
- root.render()
+ if (window.PRERENDER) {
+ container.innerHTML = container.innerHTML.trim() // Trim before hydrating to avoid mismatche error.
+ const root = hydrateRoot(container, )
+ console.log('>>> hydrateRoot DONE', root)
+ } else {
+ const root = createRoot(container)
+ root.render()
+ }
}
diff --git a/site/source/entries/entry-fr.tsx b/site/source/entries/entry-fr.tsx
index 54bbf2e93..eebefa874 100644
--- a/site/source/entries/entry-fr.tsx
+++ b/site/source/entries/entry-fr.tsx
@@ -13,7 +13,7 @@ declare global {
}
}
-export const AppFr = () => {
+const AppFr = () => {
return (
@@ -21,7 +21,7 @@ export const AppFr = () => {
)
}
-const AppFrWithProfiler = withProfiler(AppFr)
+export const AppFrWithProfiler = withProfiler(AppFr)
if (!import.meta.env.SSR) {
i18next.changeLanguage('fr').catch((err) =>
@@ -30,7 +30,9 @@ if (!import.meta.env.SSR) {
)
const container = document.querySelector('#js') as Element
if (window.PRERENDER) {
+ container.innerHTML = container.innerHTML.trim() // Trim before hydrating to avoid mismatche error.
const root = hydrateRoot(container, )
+ console.log('>>> hydrateRoot DONE', root)
} else {
const root = createRoot(container)
root.render()
diff --git a/site/source/entries/entry-server.tsx b/site/source/entries/entry-server.tsx
index 5fce28906..610170789 100644
--- a/site/source/entries/entry-server.tsx
+++ b/site/source/entries/entry-server.tsx
@@ -1,5 +1,5 @@
+import { PromiseSSR } from '@publicodes/worker-react'
import { SSRProvider } from '@react-aria/ssr'
-import { lazy } from 'react'
import ReactDomServerType from 'react-dom/server'
// @ts-ignore
import ReactDomServer from 'react-dom/server.browser'
@@ -8,6 +8,8 @@ import { StaticRouter } from 'react-router-dom/server'
import { ServerStyleSheet, StyleSheetManager } from 'styled-components'
import i18next from '../locales/i18n'
+import { AppEnWithProfiler as AppEn } from './entry-en'
+import { AppFrWithProfiler as AppFr } from './entry-fr'
const { renderToReadableStream } = ReactDomServer as typeof ReactDomServerType
@@ -15,14 +17,6 @@ function streamToString(stream: ReadableStream) {
return new Response(stream).text()
}
-const AppFrLazy = lazy(async () => ({
- default: (await import('./entry-fr')).AppFr,
-}))
-
-const AppEnLazy = lazy(async () => ({
- default: (await import('./entry-en')).AppEn,
-}))
-
// @ts-ignore
global.window = {
// @ts-ignore
@@ -38,7 +32,6 @@ interface Result {
export async function render(url: string, lang: 'fr' | 'en'): Promise {
global.window.location.href = url
global.window.location.search = ''
- console.log({ url, lang })
const sheet = new ServerStyleSheet()
const helmetContext = {} as FilledContext
@@ -52,35 +45,30 @@ export async function render(url: string, lang: 'fr' | 'en'): Promise {
- [prerender] window: {JSON.stringify(window)}
- {lang === 'fr' ? : }
+ {lang === 'fr' ? : }
)
- console.log('!!! STARTING !!!')
-
try {
const stream = await renderToReadableStream(element, {
onError(error, errorInfo) {
+ // eslint-disable-next-line no-console
console.error({ error, errorInfo })
},
})
- console.log('!!! LOADING !!!')
-
await stream.allReady
- console.log('!!! DONE !!!')
-
const html = await streamToString(stream)
const styleTags = sheet.getStyleTags()
return { html, styleTags, helmet: helmetContext.helmet }
} catch (error) {
+ // eslint-disable-next-line no-console
console.error(error)
throw error
diff --git a/site/source/hooks/useClientOnly.ts b/site/source/hooks/useClientOnly.ts
new file mode 100644
index 000000000..2d58d6fd2
--- /dev/null
+++ b/site/source/hooks/useClientOnly.ts
@@ -0,0 +1,16 @@
+import { useEffect, useState } from 'react'
+
+// Refacto of https://github.com/gfmio/react-client-only/blob/master/index.ts
+
+/** React hook that returns true if the component has mounted client-side */
+export const useClientOnly = () => {
+ const [hasMounted, setHasMounted] = useState(false)
+
+ useEffect(() => setHasMounted(true), [])
+
+ return hasMounted
+}
+
+/** React component that renders its children client-side only / after first mount */
+export const ClientOnly = ({ children }: { children: React.ReactNode }) =>
+ useClientOnly() ? children : null
diff --git a/site/source/pages/Documentation.tsx b/site/source/pages/Documentation.tsx
index 8f4f84a20..191536f5b 100644
--- a/site/source/pages/Documentation.tsx
+++ b/site/source/pages/Documentation.tsx
@@ -1,12 +1,8 @@
-import {
- SuspensePromise,
- useWorkerEngine,
- WorkerEngine,
-} from '@publicodes/worker-react'
+import { useWorkerEngine, WorkerEngine } from '@publicodes/worker-react'
import rules, { DottedName } from 'modele-social'
import Engine from 'publicodes'
import { RulePage, useDocumentationSiteMap } from 'publicodes-react'
-import { ComponentProps, useMemo, useRef } from 'react'
+import { ComponentProps, Suspense, useMemo, useRef } from 'react'
import { Helmet } from 'react-helmet-async'
import { Trans, useTranslation } from 'react-i18next'
import { useSelector } from 'react-redux'
@@ -45,16 +41,12 @@ interface DocumentationProps {
export default function DocumentationWrapper(props: DocumentationProps) {
return (
- DocumentationWrapper loading...}
- activateInBrowser
- >
+ DocumentationWrapper loading...}>
-
+
)
}
diff --git a/site/source/pages/simulateurs/index.tsx b/site/source/pages/simulateurs/index.tsx
index ee8b124ee..3a30419ef 100644
--- a/site/source/pages/simulateurs/index.tsx
+++ b/site/source/pages/simulateurs/index.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useMemo } from 'react'
+import { Suspense, useEffect, useMemo } from 'react'
import { Trans } from 'react-i18next'
import { Navigate, Route, Routes, useLocation } from 'react-router-dom'
@@ -42,7 +42,11 @@ export default function Simulateurs() {
path={
s.path.replace(absoluteSitePaths.simulateurs.index, '') + '/*'
}
- element={}
+ element={
+
+
+
+ }
/>
)),
[simulatorsData, absoluteSitePaths]
diff --git a/site/source/worker/socialWorkerEngine.worker.ts b/site/source/worker/socialWorkerEngine.worker.ts
index 9e2a3f0d1..4529b52e7 100644
--- a/site/source/worker/socialWorkerEngine.worker.ts
+++ b/site/source/worker/socialWorkerEngine.worker.ts
@@ -23,7 +23,7 @@ function getUnitKey(unit: string): string {
}
let warnCount = 0
-let timeout: NodeJS.Timeout | null = null
+let timeout: ReturnType | null = null
const logger = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
warn: (message: string) => {
@@ -57,12 +57,12 @@ const init = ({ basename }: Pick) => {
const engine = new Engine(rules, { getUnitKey, logger })
- console.timeEnd('[createWorkerEngine] init')
+ console.timeEnd('(createWorkerEngine) init')
return engine
}
-console.time('[createWorkerEngine] init')
+console.time('(createWorkerEngine) init')
createWorkerEngine(init, {
...publicodesReactActions(),
diff --git a/site/tsconfig.json b/site/tsconfig.json
index 643409f0a..ce6afecc2 100644
--- a/site/tsconfig.json
+++ b/site/tsconfig.json
@@ -14,7 +14,7 @@
"paths": {
"@/*": ["*"]
},
- "types": ["vite/client", "vite-plugin-pwa/client"],
+ "types": ["vite/client", "vite-plugin-pwa/client", "react/canary"],
"typeRoots": [
"../node_modules/@types",
"../node_modules",
diff --git a/site/vite.config.ts b/site/vite.config.ts
index 931efb629..a4a45d7f3 100644
--- a/site/vite.config.ts
+++ b/site/vite.config.ts
@@ -139,8 +139,13 @@ export default defineConfig(({ command, mode }) => ({
optimizeDeps: {
entries: ['./source/entries/entry-fr.tsx', './source/entries/entry-en.tsx'],
- include: ['publicodes-react > react/jsx-runtime'],
- exclude: ['publicodes-react', 'publicodes'],
+ include: [],
+ exclude: [
+ 'publicodes-react',
+ 'publicodes',
+ '@publicodes/worker',
+ '@publicodes/worker-react',
+ ],
},
ssr: {
diff --git a/yarn.lock b/yarn.lock
index b35392b58..9c31490ac 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7390,7 +7390,7 @@ __metadata:
"@publicodes/api@betagouv/publicodes#head=publicodes-in-worker&workspace=@publicodes/api&v0":
version: 1.0.0-beta.72
- resolution: "@publicodes/api@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fapi&v0=&commit=6eab7e0019e133a012b216da6d60e3314aec5707"
+ resolution: "@publicodes/api@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fapi&v0=&commit=2125c306e130ea2a67e547539e47a6792e203b0f"
dependencies:
"@koa/cors": ^3.3.0
"@koa/router": ^10.1.1
@@ -7405,23 +7405,23 @@ __metadata:
"@publicodes/worker-react@betagouv/publicodes#head=publicodes-in-worker&workspace=@publicodes/worker-react&v0":
version: 1.0.0-beta.71
- resolution: "@publicodes/worker-react@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fworker-react&v0=&commit=6eab7e0019e133a012b216da6d60e3314aec5707"
+ resolution: "@publicodes/worker-react@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fworker-react&v0=&commit=2125c306e130ea2a67e547539e47a6792e203b0f"
dependencies:
"@publicodes/worker": ^1.0.0-beta.71
peerDependencies:
publicodes: ^1.0.0-beta.40
- react: ^17 || ^18
- react-dom: ^17 || ^18
- checksum: 2428c2acd4a5cde2432c532562044b94fef0e9aa430406cc07c164caa71ec6484cdcf7906face107968d42bba70b1aa86e35f37bbcc63b9b2f000ba17c7e327d
+ react: 18.3.0-canary-e5205658f-20230913
+ react-dom: 18.3.0-canary-e5205658f-20230913
+ checksum: 24c7a4067e1b8055e850be2ae5c00bea501295478afb894b7ca014456a0337e92535ba20eda00514a15caca47a80c353e9db5364105fe61d7ae3577d786b340f
languageName: node
linkType: hard
"@publicodes/worker@betagouv/publicodes#head=publicodes-in-worker&workspace=@publicodes/worker&v0":
version: 1.0.0-beta.71
- resolution: "@publicodes/worker@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fworker&v0=&commit=6eab7e0019e133a012b216da6d60e3314aec5707"
+ resolution: "@publicodes/worker@https://github.com/betagouv/publicodes.git#workspace=%40publicodes%2Fworker&v0=&commit=2125c306e130ea2a67e547539e47a6792e203b0f"
peerDependencies:
publicodes: ^1.0.0-beta.40
- checksum: 26c9335ef5b4f28f241ed21f2409dc2509293432f070b76524dea877ffdf82f08e349183f87463e9f5c61ee6548640af741c40e5970f13973c8b1a250d39f6c1
+ checksum: 75967563fa5d4c7eb8980d0f5625028bdf7d997f3d368949669ac3ebbd82800573ecfc5eede9baa2ccb184d8ed766ec45f988acd48a985e4a493276b07d0d7e4
languageName: node
linkType: hard
@@ -9401,10 +9401,10 @@ __metadata:
languageName: node
linkType: hard
-"@remix-run/router@npm:1.7.2":
- version: 1.7.2
- resolution: "@remix-run/router@npm:1.7.2"
- checksum: ea43bb662f1f5c93965989b1667fb6e8a301cb69c44341ee92c81cb15ea685b494168e5905593b5777d59058f1455b4b58083d5b895f04382e49362e420d7af4
+"@remix-run/router@npm:1.8.0":
+ version: 1.8.0
+ resolution: "@remix-run/router@npm:1.8.0"
+ checksum: f754f02d3b4fc86791b88acf16065000609e2324b9436027844a76831c7107c0994067cb83abdd6093c282bd518a5c89b5e02aead585782978586e3a04534428
languageName: node
linkType: hard
@@ -25150,21 +25150,21 @@ __metadata:
"publicodes-react@betagouv/publicodes#head=publicodes-in-worker&workspace=publicodes-react&v0":
version: 1.0.0-beta.72
- resolution: "publicodes-react@https://github.com/betagouv/publicodes.git#workspace=publicodes-react&v0=&commit=6eab7e0019e133a012b216da6d60e3314aec5707"
+ resolution: "publicodes-react@https://github.com/betagouv/publicodes.git#workspace=publicodes-react&v0=&commit=2125c306e130ea2a67e547539e47a6792e203b0f"
dependencies:
"@publicodes/worker-react": ^1.0.0-beta.71
styled-components: ^6.0.7
peerDependencies:
publicodes: ^1.0.0-beta.72
- react: ^18
- react-dom: ^18
- checksum: e775ffb71a63949fbb2f3f55e97981b376464e3cc075f3c4f4c443e516d66910d7346a1f3952ffc905237680ba532253fde57a24b17a46e48c6940321383dedb
+ react: 18.3.0-canary-e5205658f-20230913
+ react-dom: 18.3.0-canary-e5205658f-20230913
+ checksum: 676b1bee77dabd644726259640cd08c5a59c316390b3036b2d3f06df39478cb5666399baae501447a455ec67ae1604c9d6b6f1dcb090fbbbfa4b7b614ea351e0
languageName: node
linkType: hard
"publicodes@betagouv/publicodes#head=publicodes-in-worker&workspace=publicodes&v0":
version: 1.0.0-beta.72
- resolution: "publicodes@https://github.com/betagouv/publicodes.git#workspace=publicodes&v0=&commit=6eab7e0019e133a012b216da6d60e3314aec5707"
+ resolution: "publicodes@https://github.com/betagouv/publicodes.git#workspace=publicodes&v0=&commit=2125c306e130ea2a67e547539e47a6792e203b0f"
peerDependencies:
"@types/mocha": ^9.0.0
checksum: ab67797de175ae5b6991cf6de0163d927160599afb5d002b611b7e39844d06a3c855615cd4ebced250c60e1e9e86335579ba61e417e3fdcac9cf18f5c8ec003d
@@ -25496,15 +25496,15 @@ __metadata:
languageName: node
linkType: hard
-"react-dom@npm:^18.2.0":
- version: 18.2.0
- resolution: "react-dom@npm:18.2.0"
+"react-dom@npm:18.3.0-canary-e5205658f-20230913":
+ version: 18.3.0-canary-e5205658f-20230913
+ resolution: "react-dom@npm:18.3.0-canary-e5205658f-20230913"
dependencies:
loose-envify: ^1.1.0
- scheduler: ^0.23.0
+ scheduler: 0.24.0-canary-e5205658f-20230913
peerDependencies:
- react: ^18.2.0
- checksum: 7d323310bea3a91be2965f9468d552f201b1c27891e45ddc2d6b8f717680c95a75ae0bc1e3f5cf41472446a2589a75aed4483aee8169287909fcd59ad149e8cc
+ react: 18.3.0-canary-e5205658f-20230913
+ checksum: da09fd41323281c79403666ef57ac5ec30998dd88dd0b2875cbdd9faf413410b930ef8e08b292c965743d9c2005991580cc1ed1e754e4899175da3616f89569c
languageName: node
linkType: hard
@@ -25746,27 +25746,27 @@ __metadata:
languageName: node
linkType: hard
-"react-router-dom@npm:^6.14.2":
- version: 6.14.2
- resolution: "react-router-dom@npm:6.14.2"
+"react-router-dom@npm:^6.15.0":
+ version: 6.15.0
+ resolution: "react-router-dom@npm:6.15.0"
dependencies:
- "@remix-run/router": 1.7.2
- react-router: 6.14.2
+ "@remix-run/router": 1.8.0
+ react-router: 6.15.0
peerDependencies:
react: ">=16.8"
react-dom: ">=16.8"
- checksum: a53dbc566ecab7890b829d42d38553684f704803c1f615db1bd6aa2d71542c369a1a79e4385be31ae71a14b72ddbcd0d8b51188248c2bccd44e015050d1927df
+ checksum: 95301837e293654f00934de6a4bdb27bfb06f613503e4cce7a93f19384793729832e7479d50faf3b9457d149014d4df40a3ee3a5193d7e3a3caadb7aaa6ec0f9
languageName: node
linkType: hard
-"react-router@npm:6.14.2":
- version: 6.14.2
- resolution: "react-router@npm:6.14.2"
+"react-router@npm:6.15.0":
+ version: 6.15.0
+ resolution: "react-router@npm:6.15.0"
dependencies:
- "@remix-run/router": 1.7.2
+ "@remix-run/router": 1.8.0
peerDependencies:
react: ">=16.8"
- checksum: 7507bf5732b3a8ddbd901c2061216eebca73e194449bff58acc1445171e22bdda36b455b8af066e467748ebfb5875b3c0a565941c46af65c6f653a6ed0dc4fe4
+ checksum: 345b29277e13997f2625f0037f537eaf1955bb9f44ebfea80dd3ff83fc06273f7b64e1be944bfc75945fd2af5af917874133a8a93ed5ecaca523be8f045ae166
languageName: node
linkType: hard
@@ -25885,12 +25885,12 @@ __metadata:
languageName: node
linkType: hard
-"react@npm:^18.2.0":
- version: 18.2.0
- resolution: "react@npm:18.2.0"
+"react@npm:18.3.0-canary-e5205658f-20230913":
+ version: 18.3.0-canary-e5205658f-20230913
+ resolution: "react@npm:18.3.0-canary-e5205658f-20230913"
dependencies:
loose-envify: ^1.1.0
- checksum: 88e38092da8839b830cda6feef2e8505dec8ace60579e46aa5490fc3dc9bba0bd50336507dc166f43e3afc1c42939c09fe33b25fae889d6f402721dcd78fca1b
+ checksum: 5f76591c029feec8e664739ef9bf1bb41ee68fbca5e43e3cb4673b0793f01b59207519cd58c8ddd381768032d7972b90ae4937da1f059e57b897b3bd5d7644ff
languageName: node
linkType: hard
@@ -26992,6 +26992,15 @@ __metadata:
languageName: node
linkType: hard
+"scheduler@npm:0.24.0-canary-e5205658f-20230913":
+ version: 0.24.0-canary-e5205658f-20230913
+ resolution: "scheduler@npm:0.24.0-canary-e5205658f-20230913"
+ dependencies:
+ loose-envify: ^1.1.0
+ checksum: 6c95ebfe834cc515366cb7bacf83f464e01eec2387d43665d5ce2af1eb6ff0c3ff3d92d9c4f2720d79380b1f5420c3d89a756d632bc4310ead045bf379e321c7
+ languageName: node
+ linkType: hard
+
"scheduler@npm:^0.17.0":
version: 0.17.0
resolution: "scheduler@npm:0.17.0"
@@ -27002,15 +27011,6 @@ __metadata:
languageName: node
linkType: hard
-"scheduler@npm:^0.23.0":
- version: 0.23.0
- resolution: "scheduler@npm:0.23.0"
- dependencies:
- loose-envify: ^1.1.0
- checksum: d79192eeaa12abef860c195ea45d37cbf2bbf5f66e3c4dcd16f54a7da53b17788a70d109ee3d3dde1a0fd50e6a8fc171f4300356c5aee4fc0171de526bf35f8a
- languageName: node
- linkType: hard
-
"scripts@workspace:site/scripts/NAFAndGuichetData":
version: 0.0.0-use.local
resolution: "scripts@workspace:site/scripts/NAFAndGuichetData"
@@ -27397,7 +27397,7 @@ __metadata:
"@storybook/react-vite": ^7.0.5
"@storybook/testing-library": ^0.1.0
"@types/history": ^5.0.0
- "@types/react": ^18.2.21
+ "@types/react": ^18.2.18
"@types/react-dom": ^18.2.7
"@types/react-instantsearch-dom": ^6.12.3
"@types/react-redux": ^7.1.25
@@ -27423,10 +27423,10 @@ __metadata:
netlify-cli: ^15.11.0
publicodes: ^1.0.0-beta.73
publicodes-react: ^1.0.0-beta.73
- react: ^18.2.0
+ react: 18.3.0-canary-e5205658f-20230913
react-aria: ^3.24.0
react-day-picker: ^8.7.1
- react-dom: ^18.2.0
+ react-dom: 18.3.0-canary-e5205658f-20230913
react-easy-emoji: ^1.8.1
react-flip-move: ^3.0.5
react-helmet-async: ^1.3.0
@@ -27434,7 +27434,7 @@ __metadata:
react-instantsearch: ^6.38.1
react-instantsearch-dom: ^6.38.1
react-redux: ^8.0.5
- react-router-dom: ^6.14.2
+ react-router-dom: ^6.15.0
react-signature-pad-wrapper: ^3.3.1
react-spring: ^9.5.5
react-stately: ^3.22.0
@@ -30260,9 +30260,9 @@ __metadata:
linkType: hard
"whatwg-fetch@npm:^3.6.2":
- version: 3.6.2
- resolution: "whatwg-fetch@npm:3.6.2"
- checksum: ee976b7249e7791edb0d0a62cd806b29006ad7ec3a3d89145921ad8c00a3a67e4be8f3fb3ec6bc7b58498724fd568d11aeeeea1f7827e7e1e5eae6c8a275afed
+ version: 3.6.19
+ resolution: "whatwg-fetch@npm:3.6.19"
+ checksum: 2896bc9ca867ea514392c73e2a272f65d5c4916248fe0837a9df5b1b92f247047bc76cf7c29c28a01ac6c5fb4314021d2718958c8a08292a96d56f72b2f56806
languageName: node
linkType: hard