@plitzi/sdk-server 0.37.1 → 0.37.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1296 -0
- package/README.md +126 -7
- package/dist/actions.d.ts +20 -8
- package/dist/actions.js +11 -4
- package/dist/adapters/cloudAdapters.js +4 -3
- package/dist/adapters/jsonAdapters.js +28 -6
- package/dist/auth.d.ts +7 -4
- package/dist/auth.js +8 -6
- package/dist/core/auth/api.d.ts +29 -1
- package/dist/core/auth/api.js +47 -13
- package/dist/core/auth/createAuth.d.ts +4 -0
- package/dist/core/auth/createAuth.js +3 -3
- package/dist/core/auth/credentials.d.ts +3 -0
- package/dist/core/auth/credentials.js +1 -1
- package/dist/core/auth/csrf.d.ts +25 -1
- package/dist/core/auth/csrf.js +29 -4
- package/dist/core/auth/renewal.d.ts +26 -0
- package/dist/core/auth/renewal.js +24 -0
- package/dist/core/auth/routes.js +8 -6
- package/dist/core/auth/session.d.ts +45 -0
- package/dist/core/auth/session.js +47 -1
- package/dist/core/auth/sessionActivity.d.ts +11 -0
- package/dist/core/auth/sessionActivity.js +14 -0
- package/dist/core/auth/throttle.d.ts +15 -0
- package/dist/core/auth/throttle.js +29 -1
- package/dist/core/auth/totp.d.ts +9 -1
- package/dist/core/auth/totp.js +11 -6
- package/dist/core/createServer.actions.test.d.ts +1 -0
- package/dist/core/createServer.d.ts +14 -1
- package/dist/core/createServer.functions.test.d.ts +1 -0
- package/dist/core/createServer.js +22 -12
- package/dist/core/fontStore.js +1 -1
- package/dist/core/handlers/authRouteHandlers.d.ts +1 -1
- package/dist/core/handlers/authRouteHandlers.js +57 -21
- package/dist/core/handlers/csrfMiddleware.d.ts +23 -0
- package/dist/core/handlers/csrfMiddleware.js +31 -7
- package/dist/core/handlers/csrfMiddleware.test.d.ts +1 -0
- package/dist/core/handlers/oauthRouteHandlers.js +5 -3
- package/dist/core/handlers/socialRouteHandlers.d.ts +1 -1
- package/dist/core/handlers/socialRouteHandlers.js +2 -1
- package/dist/core/http/dispatcher.d.ts +9 -1
- package/dist/core/http/dispatcher.js +38 -11
- package/dist/core/http/navigation.d.ts +5 -2
- package/dist/core/http/navigation.js +7 -4
- package/dist/core/http/socketResponse.d.ts +18 -0
- package/dist/core/http/socketResponse.js +59 -0
- package/dist/core/http/sse.d.ts +26 -0
- package/dist/core/http/sse.js +78 -0
- package/dist/core/http/stages/authRoutes.js +3 -1
- package/dist/core/http/stages/exchangeRoute.test.d.ts +1 -0
- package/dist/core/http/stages/middlewares.d.ts +1 -1
- package/dist/core/http/stages/middlewares.js +16 -10
- package/dist/core/http/stages/middlewares.test.d.ts +1 -0
- package/dist/core/http/stages/oauth.js +2 -2
- package/dist/core/http/stages/sessionRenewal.d.ts +16 -0
- package/dist/core/http/stages/sessionRenewal.js +81 -0
- package/dist/core/http/stages/sessionRenewal.test.d.ts +1 -0
- package/dist/core/http/stages/signInRoute.d.ts +2 -0
- package/dist/core/http/stages/signInRoute.js +139 -0
- package/dist/core/http/stages/signInRoute.test.d.ts +1 -0
- package/dist/core/http/types.d.ts +9 -0
- package/dist/core/http/webExchange.d.ts +18 -0
- package/dist/core/http/webExchange.js +53 -0
- package/dist/core/oauth/authorize.js +37 -13
- package/dist/core/oauth/consentPage.js +11 -0
- package/dist/core/oauth/issueContext.d.ts +14 -0
- package/dist/core/oauth/issueContext.js +32 -0
- package/dist/core/oauth/records.d.ts +7 -0
- package/dist/core/oauth/register.d.ts +2 -0
- package/dist/core/oauth/register.js +32 -11
- package/dist/core/oauth/register.test.d.ts +1 -0
- package/dist/core/oauth/token.js +21 -6
- package/dist/core/oauth/token.test.d.ts +1 -0
- package/dist/core/requestParser.d.ts +4 -0
- package/dist/core/requestParser.js +14 -7
- package/dist/core/sdkAssets.js +1 -1
- package/dist/core/server/baseServer.d.ts +14 -1
- package/dist/core/server/baseServer.js +43 -11
- package/dist/core/server/closeOnSignals.d.ts +28 -0
- package/dist/core/server/closeOnSignals.js +47 -0
- package/dist/core/server/closeOnSignals.test.d.ts +1 -0
- package/dist/core/server/drain.d.ts +18 -0
- package/dist/core/server/drain.js +62 -0
- package/dist/core/server/drain.test.d.ts +1 -0
- package/dist/core/server/fleet/channel.d.ts +103 -0
- package/dist/core/server/fleet/channel.js +191 -0
- package/dist/core/server/fleet/channel.test.d.ts +1 -0
- package/dist/core/server/fleet/fixtures/fleetServer.d.ts +1 -0
- package/dist/core/server/fleet/fleet.integration.test.d.ts +1 -0
- package/dist/core/server/fleet/link.d.ts +23 -0
- package/dist/core/server/fleet/link.js +70 -0
- package/dist/core/server/fleet/relay.d.ts +11 -0
- package/dist/core/server/fleet/relay.js +104 -0
- package/dist/core/server/fleet/relay.test.d.ts +1 -0
- package/dist/core/server/fleet/role.d.ts +46 -0
- package/dist/core/server/fleet/role.js +59 -0
- package/dist/core/server/fleet/role.test.d.ts +1 -0
- package/dist/core/server/fleet/stores.d.ts +7 -0
- package/dist/core/server/fleet/stores.js +19 -0
- package/dist/core/server/fleet/supervisor.d.ts +26 -0
- package/dist/core/server/fleet/supervisor.js +108 -0
- package/dist/core/server/fleet/supervisor.test.d.ts +1 -0
- package/dist/core/server/pageServer.js +36 -5
- package/dist/core/services/action.js +10 -2
- package/dist/core/services/functionRoutes.d.ts +9 -0
- package/dist/core/services/functionRoutes.js +47 -0
- package/dist/core/services/realtime.d.ts +8 -0
- package/dist/core/services/realtime.js +57 -0
- package/dist/core/services/registry.js +6 -2
- package/dist/core/staticFiles.js +12 -4
- package/dist/core/staticFiles.test.d.ts +1 -0
- package/dist/core/transports.d.ts +13 -3
- package/dist/core/transports.js +14 -5
- package/dist/functions-api.d.ts +281 -0
- package/dist/functions.d.ts +19 -0
- package/dist/functions.js +5 -0
- package/dist/functionsRunner.d.ts +15 -0
- package/dist/functionsRunner.js +6 -0
- package/dist/handlers.d.ts +2 -2
- package/dist/handlers.js +2 -2
- package/dist/helpers/atomicFile.d.ts +10 -0
- package/dist/helpers/atomicFile.js +33 -0
- package/dist/helpers/atomicFile.test.d.ts +1 -0
- package/dist/helpers/buildResponseHelpers.js +35 -11
- package/dist/helpers/buildServerInfo.js +4 -2
- package/dist/helpers/buildServerInfo.test.d.ts +1 -0
- package/dist/helpers/cache/CompressedFileCache.d.ts +18 -0
- package/dist/helpers/cache/CompressedFileCache.js +44 -0
- package/dist/helpers/cache/CompressedFileCache.test.d.ts +1 -0
- package/dist/helpers/cache/cacheManager.d.ts +1 -1
- package/dist/helpers/cache/cacheManager.js +2 -1
- package/dist/helpers/cache/cacheManager.test.d.ts +1 -0
- package/dist/helpers/cache/index.d.ts +1 -1
- package/dist/helpers/cache/keys.d.ts +15 -1
- package/dist/helpers/cache/keys.js +47 -5
- package/dist/helpers/cache/serverCaches.d.ts +7 -1
- package/dist/helpers/compress.d.ts +3 -1
- package/dist/helpers/compress.js +11 -3
- package/dist/helpers/hydrationPayload.d.ts +11 -0
- package/dist/helpers/hydrationPayload.js +51 -0
- package/dist/helpers/hydrationPayload.test.d.ts +1 -0
- package/dist/helpers/metrics.d.ts +1 -1
- package/dist/helpers/metrics.js +3 -2
- package/dist/helpers/outboundGuard.d.ts +14 -6
- package/dist/helpers/outboundGuard.js +132 -8
- package/dist/helpers/paintedCookie.d.ts +8 -0
- package/dist/helpers/paintedCookie.js +13 -0
- package/dist/helpers/reportReactBuild.d.ts +9 -0
- package/dist/helpers/reportReactBuild.js +18 -0
- package/dist/helpers/reportReactBuild.test.d.ts +1 -0
- package/dist/helpers/serverLog.d.ts +25 -1
- package/dist/helpers/serverLog.js +68 -3
- package/dist/helpers/serverLog.test.d.ts +1 -0
- package/dist/helpers/wsFrame.d.ts +3 -0
- package/dist/helpers/wsFrame.js +5 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +6 -2
- package/dist/kernel.d.ts +2 -1
- package/dist/kernel.js +3 -2
- package/dist/modules/actions/connectorWrite.js +2 -1
- package/dist/modules/actions/index.d.ts +41 -13
- package/dist/modules/actions/index.js +52 -9
- package/dist/modules/actions/jobs/failureStreak.d.ts +17 -0
- package/dist/modules/actions/jobs/failureStreak.js +47 -0
- package/dist/modules/actions/jobs/failureStreak.test.d.ts +1 -0
- package/dist/modules/actions/jobs/index.d.ts +33 -0
- package/dist/modules/actions/jobs/index.js +59 -0
- package/dist/modules/actions/jobs/memoryQueue.d.ts +33 -0
- package/dist/modules/actions/jobs/memoryQueue.js +194 -0
- package/dist/modules/actions/jobs/memoryStores.test.d.ts +1 -0
- package/dist/modules/actions/jobs/scheduler.d.ts +64 -0
- package/dist/modules/actions/jobs/scheduler.js +130 -0
- package/dist/modules/actions/jobs/scheduler.test.d.ts +1 -0
- package/dist/modules/actions/jobs/schedules.d.ts +23 -0
- package/dist/modules/actions/jobs/schedules.js +47 -0
- package/dist/modules/actions/jobs/storeClock.d.ts +16 -0
- package/dist/modules/actions/jobs/storeClock.js +32 -0
- package/dist/modules/actions/jobs/testing/jobQueueContract.d.ts +25 -0
- package/dist/modules/actions/jobs/worker.d.ts +64 -0
- package/dist/modules/actions/jobs/worker.js +267 -0
- package/dist/modules/actions/jobs/worker.test.d.ts +1 -0
- package/dist/modules/actions/moduleFor.js +6 -2
- package/dist/modules/actions/runtime/errors.d.ts +12 -0
- package/dist/modules/actions/runtime/errors.js +16 -1
- package/dist/modules/actions/runtime/kvChange.d.ts +27 -0
- package/dist/modules/actions/runtime/kvChange.js +23 -0
- package/dist/modules/actions/runtime/kvList.d.ts +51 -0
- package/dist/modules/actions/runtime/kvList.js +52 -0
- package/dist/modules/actions/runtime/kvStore.d.ts +8 -0
- package/dist/modules/actions/runtime/kvStore.js +46 -20
- package/dist/modules/actions/runtime/memoryKv.d.ts +3 -0
- package/dist/modules/actions/runtime/memoryKv.js +19 -1
- package/dist/modules/actions/runtime/namespaceKv.d.ts +4 -6
- package/dist/modules/actions/runtime/namespaceKv.js +15 -3
- package/dist/modules/actions/runtime/namespaceKv.test.d.ts +1 -0
- package/dist/modules/actions/runtime/precheck.js +5 -9
- package/dist/modules/actions/runtime/rateLimit.d.ts +19 -0
- package/dist/modules/actions/runtime/rateLimit.js +19 -0
- package/dist/modules/actions/runtime/redisKv.d.ts +27 -0
- package/dist/modules/actions/runtime/redisKv.integration.test.d.ts +1 -0
- package/dist/modules/actions/runtime/redisKv.js +46 -0
- package/dist/modules/actions/runtime/renderResolver.js +2 -2
- package/dist/modules/actions/runtime/report.js +2 -1
- package/dist/modules/actions/runtime/runAction.d.ts +10 -2
- package/dist/modules/actions/runtime/runAction.js +52 -116
- package/dist/modules/actions/runtime/runLogger.d.ts +5 -0
- package/dist/modules/actions/runtime/runLogger.js +8 -2
- package/dist/modules/actions/runtime/signing.d.ts +20 -0
- package/dist/modules/actions/runtime/signing.js +25 -0
- package/dist/modules/actions/runtime/signing.test.d.ts +1 -0
- package/dist/modules/actions/runtime/taskContext.d.ts +33 -0
- package/dist/modules/actions/runtime/taskContext.js +124 -0
- package/dist/modules/actions/tasks/builtins.js +5 -1
- package/dist/modules/actions/tasks/flow.js +81 -10
- package/dist/modules/actions/tasks/helpers.js +2 -2
- package/dist/modules/actions/tasks/http.js +2 -3
- package/dist/modules/actions/tasks/kv.js +39 -0
- package/dist/modules/actions/tasks/list.d.ts +2 -0
- package/dist/modules/actions/tasks/list.js +145 -0
- package/dist/modules/actions/tasks/realtime.d.ts +2 -0
- package/dist/modules/actions/tasks/realtime.js +104 -0
- package/dist/modules/actions/tasks/registry.d.ts +10 -1
- package/dist/modules/actions/tasks/registry.js +17 -6
- package/dist/modules/actions/transport/callHandler.js +6 -3
- package/dist/modules/actions/transport/catalogHandler.d.ts +5 -2
- package/dist/modules/actions/transport/catalogHandler.js +3 -2
- package/dist/modules/actions/transport/stream.d.ts +4 -5
- package/dist/modules/actions/transport/stream.js +12 -76
- package/dist/modules/actions/transport/webhookHandler.js +5 -4
- package/dist/modules/actions/types.d.ts +162 -4
- package/dist/modules/connectors/engine.js +3 -5
- package/dist/modules/functions/build.d.ts +22 -0
- package/dist/modules/functions/build.js +122 -0
- package/dist/modules/functions/build.test.d.ts +1 -0
- package/dist/modules/functions/capabilities.d.ts +22 -0
- package/dist/modules/functions/capabilities.js +228 -0
- package/dist/modules/functions/config.d.ts +34 -0
- package/dist/modules/functions/config.js +24 -0
- package/dist/modules/functions/context.d.ts +17 -0
- package/dist/modules/functions/context.js +88 -0
- package/dist/modules/functions/contract.d.ts +121 -0
- package/dist/modules/functions/contract.js +9 -0
- package/dist/modules/functions/driver.d.ts +36 -0
- package/dist/modules/functions/driver.js +150 -0
- package/dist/modules/functions/load.d.ts +15 -0
- package/dist/modules/functions/load.js +45 -0
- package/dist/modules/functions/load.test.d.ts +1 -0
- package/dist/modules/functions/local.d.ts +29 -0
- package/dist/modules/functions/local.js +61 -0
- package/dist/modules/functions/local.test.d.ts +1 -0
- package/dist/modules/functions/manifest.d.ts +24 -0
- package/dist/modules/functions/manifest.js +163 -0
- package/dist/modules/functions/manifest.test.d.ts +1 -0
- package/dist/modules/functions/native.d.ts +8 -0
- package/dist/modules/functions/native.js +21 -0
- package/dist/modules/functions/native.test.d.ts +1 -0
- package/dist/modules/functions/protocol.d.ts +216 -0
- package/dist/modules/functions/protocol.js +18 -0
- package/dist/modules/functions/routes.d.ts +36 -0
- package/dist/modules/functions/routes.js +181 -0
- package/dist/modules/functions/routes.test.d.ts +1 -0
- package/dist/modules/functions/runner/messages.d.ts +5 -0
- package/dist/modules/functions/runner/messages.js +188 -0
- package/dist/modules/functions/runner/remote.d.ts +19 -0
- package/dist/modules/functions/runner/remote.js +116 -0
- package/dist/modules/functions/runner/remote.test.d.ts +1 -0
- package/dist/modules/functions/runner/service.d.ts +32 -0
- package/dist/modules/functions/runner/service.js +209 -0
- package/dist/modules/functions/sandbox/guest.d.ts +45 -0
- package/dist/modules/functions/sandbox/guest.js +660 -0
- package/dist/modules/functions/sandbox/isolate.d.ts +37 -0
- package/dist/modules/functions/sandbox/isolate.js +347 -0
- package/dist/modules/functions/sandbox/isolate.test.d.ts +1 -0
- package/dist/modules/functions/sandbox/prelude.d.ts +2 -0
- package/dist/modules/functions/sandbox/prelude.js +49 -0
- package/dist/modules/functions/space.d.ts +40 -0
- package/dist/modules/functions/space.js +162 -0
- package/dist/modules/functions/testing/tasksOf.d.ts +4 -0
- package/dist/modules/functions/tryEntry.d.ts +9 -0
- package/dist/modules/functions/tryEntry.js +49 -0
- package/dist/modules/mongo/index.d.ts +4 -0
- package/dist/modules/mongo/jobQueue.d.ts +38 -0
- package/dist/modules/mongo/jobQueue.js +335 -0
- package/dist/modules/mongo/kv.d.ts +15 -0
- package/dist/modules/mongo/kv.js +129 -0
- package/dist/modules/mongo/stores.integration.test.d.ts +1 -0
- package/dist/modules/mysql/accounts.js +19 -9
- package/dist/modules/mysql/index.d.ts +2 -1
- package/dist/modules/mysql/jobs/index.d.ts +5 -0
- package/dist/modules/mysql/jobs/jobQueue.d.ts +40 -0
- package/dist/modules/mysql/jobs/jobQueue.js +375 -0
- package/dist/modules/mysql/jobs/kv.d.ts +18 -0
- package/dist/modules/mysql/jobs/kv.js +108 -0
- package/dist/modules/mysql/jobs/schema.d.ts +33 -0
- package/dist/modules/mysql/jobs/schema.js +113 -0
- package/dist/modules/mysql/jobs/stores.integration.test.d.ts +1 -0
- package/dist/modules/mysql/schema.js +25 -0
- package/dist/modules/mysql/sessions.d.ts +1 -11
- package/dist/modules/mysql/sessions.js +6 -1
- package/dist/modules/realtime/declarations.d.ts +11 -0
- package/dist/modules/realtime/declarations.js +26 -0
- package/dist/modules/realtime/grants.d.ts +23 -0
- package/dist/modules/realtime/grants.js +61 -0
- package/dist/modules/realtime/handlers.d.ts +74 -0
- package/dist/modules/realtime/handlers.js +224 -0
- package/dist/modules/realtime/hub.d.ts +62 -0
- package/dist/modules/realtime/hub.js +141 -0
- package/dist/modules/realtime/index.d.ts +51 -0
- package/dist/modules/realtime/index.js +62 -0
- package/dist/modules/realtime/memoryPubSub.d.ts +10 -0
- package/dist/modules/realtime/memoryPubSub.js +43 -0
- package/dist/modules/realtime/realtime.test.d.ts +1 -0
- package/dist/modules/realtime/redisPubSub.d.ts +24 -0
- package/dist/modules/realtime/redisPubSub.js +36 -0
- package/dist/modules/realtime/redisPubSub.test.d.ts +1 -0
- package/dist/modules/realtime/socket.d.ts +25 -0
- package/dist/modules/realtime/socket.js +122 -0
- package/dist/modules/realtime/socket.test.d.ts +1 -0
- package/dist/modules/rsc/handler.d.ts +16 -0
- package/dist/modules/rsc/handler.js +17 -10
- package/dist/modules/rsc/handler.test.d.ts +1 -0
- package/dist/modules/rsc/resolveRscData.js +2 -1
- package/dist/modules/runtime/bundle.d.ts +24 -0
- package/dist/modules/runtime/bundle.js +102 -0
- package/dist/modules/runtime/contract.d.ts +37 -0
- package/dist/modules/runtime/contract.js +21 -0
- package/dist/modules/runtime/entry.test.d.ts +1 -0
- package/dist/modules/runtime/host.d.ts +38 -0
- package/dist/modules/runtime/host.js +68 -0
- package/dist/modules/runtime/inside.d.ts +15 -0
- package/dist/modules/runtime/inside.js +47 -0
- package/dist/modules/runtime/inside.test.d.ts +1 -0
- package/dist/modules/runtime/runner.d.ts +11 -0
- package/dist/modules/runtime/runner.js +38 -0
- package/dist/modules/runtime/runtime.test.d.ts +1 -0
- package/dist/modules/runtime/stages.d.ts +50 -0
- package/dist/modules/runtime/stages.js +117 -0
- package/dist/modules/ssr/Component.d.ts +4 -5
- package/dist/modules/ssr/Component.js +2 -2
- package/dist/modules/ssr/handler.js +10 -2
- package/dist/modules/ssr/loadPluginComponents.js +2 -1
- package/dist/modules/ssr/prepareRender.js +39 -13
- package/dist/modules/ssr/preview.d.ts +3 -0
- package/dist/modules/ssr/preview.js +17 -7
- package/dist/modules/ssr/redirect.test.d.ts +1 -0
- package/dist/modules/ssr/registerExternalPlugins.d.ts +6 -1
- package/dist/modules/ssr/registerExternalPlugins.js +19 -16
- package/dist/modules/ssr/registerExternalPlugins.test.d.ts +1 -0
- package/dist/modules/ssr/reportMissingPlugins.d.ts +9 -0
- package/dist/modules/ssr/reportMissingPlugins.js +24 -0
- package/dist/modules/ssr/reportMissingPlugins.test.d.ts +1 -0
- package/dist/modules/ssr/streamBody.d.ts +2 -2
- package/dist/modules/ssr/streamBody.js +4 -1
- package/dist/modules/ssr/template.js +1 -1
- package/dist/modules/ssr/views/template.ejs +8 -5
- package/dist/mongo.d.ts +25 -0
- package/dist/mongo.js +3 -0
- package/dist/mysql.d.ts +11 -0
- package/dist/mysql.js +4 -1
- package/dist/oauth.js +2 -2
- package/dist/plugins/compile.js +9 -4
- package/dist/plugins/copy.js +3 -3
- package/dist/plugins/manager.d.ts +35 -3
- package/dist/plugins/manager.js +109 -38
- package/dist/runtime.d.ts +15 -0
- package/dist/runtime.js +7 -0
- package/package.json +52 -11
- package/skills/plitzi-authoring/SKILL.md +153 -263
- package/skills/plitzi-authoring/reference/accessibility.md +111 -0
- package/skills/plitzi-authoring/reference/authoring-errors.md +70 -0
- package/skills/plitzi-authoring/reference/data-and-visibility.md +180 -0
- package/skills/plitzi-authoring/reference/elements-and-styles.md +161 -0
- package/skills/plitzi-authoring/reference/flows.md +171 -0
- package/skills/plitzi-authoring/reference/layouts.md +140 -0
- package/skills/plitzi-authoring/reference/lists.md +74 -0
- package/skills/plitzi-authoring/reference/performance.md +67 -0
- package/skills/plitzi-authoring/reference/plugins.md +167 -0
- package/skills/plitzi-authoring/reference/review-checklist.md +67 -0
- package/skills/plitzi-authoring/reference/structure.md +83 -0
- package/skills/plitzi-authoring/reference/templates-and-export.md +54 -0
- package/skills/plitzi-authoring/reference/templates.md +109 -0
- package/skills/plitzi-authoring/reference/testing.md +119 -0
- package/skills/plitzi-authoring/reference/validation.md +73 -0
- package/dist/modules/actions/runtime/schedule.d.ts +0 -35
- package/dist/modules/actions/runtime/schedule.js +0 -76
- /package/dist/{modules/actions/runtime/schedule.test.d.ts → adapters/jsonAdapters.test.d.ts} +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { authorizesDebugging } from "../../helpers/debugAuthorization.js";
|
|
2
|
+
import { realtimeModuleFor } from "../realtime/index.js";
|
|
2
3
|
import { matchRscPage } from "../rsc/matchRscPage.js";
|
|
4
|
+
import { ssrPaintedCookieName } from "../../helpers/paintedCookie.js";
|
|
3
5
|
import { readCookie } from "../../helpers/readCookie.js";
|
|
4
6
|
import { buildOfflineDataCacheKey } from "../../helpers/cache/keys.js";
|
|
5
7
|
import { loadPluginComponents } from "./loadPluginComponents.js";
|
|
@@ -7,18 +9,30 @@ import "../../core/previewToken.js";
|
|
|
7
9
|
import { resolveActionEndpoint, resolveRscEndpoint } from "../../core/services/resolve.js";
|
|
8
10
|
import { createOfflineDataLoader } from "../../helpers/offlineDataLoader.js";
|
|
9
11
|
import { registerExternalPlugins } from "./registerExternalPlugins.js";
|
|
12
|
+
import { reportMissingPlugins } from "./reportMissingPlugins.js";
|
|
10
13
|
import { resolvePageSeo } from "./resolvePageSeo.js";
|
|
11
14
|
import { sdkAssetVersion } from "../../core/sdkAssets.js";
|
|
12
15
|
import { buildServerInfo } from "../../helpers/buildServerInfo.js";
|
|
13
|
-
import {
|
|
16
|
+
import { hydrationPayload } from "../../helpers/hydrationPayload.js";
|
|
14
17
|
import { resolveDebugMode } from "../../helpers/resolveDebugMode.js";
|
|
15
18
|
import { hasServerElements } from "@plitzi/sdk-shared/schema/serverElements";
|
|
16
19
|
import { debugCookieName } from "@plitzi/sdk-shared/devTools";
|
|
17
20
|
import { themeFromCookies } from "@plitzi/sdk-shared/theme";
|
|
21
|
+
import { paintedKeys, paintedStateFor } from "@plitzi/sdk-shared/state/paintedState";
|
|
18
22
|
import { fontUrlResolver, fontsToHead } from "@plitzi/sdk-shared/style";
|
|
19
23
|
//#region src/modules/ssr/prepareRender.tsx
|
|
20
24
|
/** Last resort only: used for a page that declares no SEO title and a deployment that supplies none either. */
|
|
21
25
|
var DEFAULT_TITLE = "Plitzi App";
|
|
26
|
+
/**
|
|
27
|
+
* The theme a space declares a first visit starts in, when it declares one other than `system`.
|
|
28
|
+
*
|
|
29
|
+
* `Partial`, because a style document written before themes existed has no `theme` at all, and a published space
|
|
30
|
+
* is rendered from whatever document it was published with.
|
|
31
|
+
*/
|
|
32
|
+
var declaredTheme = (style) => {
|
|
33
|
+
const declared = style?.theme?.default;
|
|
34
|
+
return declared && declared !== "system" ? declared : void 0;
|
|
35
|
+
};
|
|
22
36
|
var prepareRender = async (req, config, spaceId, environment, revision, pluginManager, offlineDataCache, metrics, offlineDataOverride) => {
|
|
23
37
|
const m = (name, fn) => metrics ? metrics.measure(name, fn) : Promise.resolve(fn());
|
|
24
38
|
const offlineCacheKey = environment !== "main" ? buildOfflineDataCacheKey(spaceId, environment, revision) : void 0;
|
|
@@ -44,7 +58,9 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
44
58
|
const server = buildServerInfo(req, config, {
|
|
45
59
|
rscPath,
|
|
46
60
|
rscData,
|
|
47
|
-
actionPath: resolveActionEndpoint(config)
|
|
61
|
+
actionPath: resolveActionEndpoint(config),
|
|
62
|
+
realtimePath: realtimeModuleFor(config)?.path,
|
|
63
|
+
realtimeTransport: realtimeModuleFor(config)?.transport
|
|
48
64
|
});
|
|
49
65
|
if (offlineDataOverride === void 0 && !cachedOfflineStr && offlineCacheKey && offlineData !== void 0) offlineDataCache?.set(offlineCacheKey, JSON.stringify(offlineData));
|
|
50
66
|
const version = config.assetVersion ?? sdkAssetVersion();
|
|
@@ -80,7 +96,6 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
80
96
|
...analytics,
|
|
81
97
|
firstViewCounted: true
|
|
82
98
|
} : void 0;
|
|
83
|
-
const branding = degrade ? true : void 0;
|
|
84
99
|
const overQuota = degrade ? true : void 0;
|
|
85
100
|
/**
|
|
86
101
|
* The visitor's theme, from the cookie the SDK writes it to.
|
|
@@ -93,23 +108,33 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
93
108
|
* `{{ theme.resolved }}` or gate a rule on the scheme, and a client that started at `system` while the server
|
|
94
109
|
* rendered `dark` would hydrate different markup and throw away the tree.
|
|
95
110
|
*
|
|
96
|
-
* Absent — a first visit —
|
|
97
|
-
*
|
|
111
|
+
* Absent — a first visit — the space's own default applies (`style.theme.default`), painted by the server like a
|
|
112
|
+
* choice would be. A default of `system` stamps nothing and the stylesheet's media queries answer, which is exactly
|
|
113
|
+
* right for a space that did not pick.
|
|
114
|
+
*/
|
|
115
|
+
const theme = themeFromCookies(req.headers.cookie) ?? declaredTheme(offlineData?.style);
|
|
116
|
+
/**
|
|
117
|
+
* The kept state the first paint depends on, from the cookie the SDK writes the space's `settings.paintedState` to.
|
|
118
|
+
*
|
|
119
|
+
* The theme's reasoning, for the space's own state: web storage is the browser's alone, so what a visitor chose — the
|
|
120
|
+
* tool a toolbar shows, their name in an avatar — would reach the page only after hydration, and be swapped in over
|
|
121
|
+
* the defaults the server drew. Read here, the server draws with it, and the page starts from the same values: it
|
|
122
|
+
* travels as the SDK's `state`, the starting `runtime.state`, in the render and in the payload alike, or the client
|
|
123
|
+
* would hydrate other markup. Only the keys the space declares, and only with `keepState` on.
|
|
98
124
|
*/
|
|
99
|
-
const
|
|
100
|
-
const offlineDataStr =
|
|
101
|
-
offlineData,
|
|
125
|
+
const paintedState = schema?.settings.keepState ? paintedStateFor(req.headers.cookie, ssrPaintedCookieName(req.headers.host), paintedKeys(schema.settings)) : void 0;
|
|
126
|
+
const offlineDataStr = hydrationPayload(offlineData, {
|
|
102
127
|
offlineMode: true,
|
|
103
128
|
environment,
|
|
104
129
|
renderMode: "raw",
|
|
105
130
|
server,
|
|
106
131
|
sdkDevToolsStylePath,
|
|
107
132
|
...theme ? { theme } : {},
|
|
133
|
+
...paintedState ? { state: paintedState } : {},
|
|
108
134
|
...clientAnalytics ? { analytics: clientAnalytics } : {},
|
|
109
|
-
...branding ? { branding } : {},
|
|
110
135
|
...overQuota ? { overQuota } : {},
|
|
111
136
|
...actionRuns ? { actionRuns } : {}
|
|
112
|
-
})
|
|
137
|
+
});
|
|
113
138
|
const pluginNames = req.ctx.spaceDeployment?.pluginNames ?? [];
|
|
114
139
|
const pluginSources = req.ctx.spaceDeployment?.pluginSources;
|
|
115
140
|
const pluginBaseNames = new Set(pluginNames.map((n) => n.replace(/@[^@]*$/, "")));
|
|
@@ -118,7 +143,7 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
118
143
|
const key = pluginManager.ensure(pluginName, pluginSource);
|
|
119
144
|
if (!pluginBaseNames.has(pluginName)) dynamicNames.push(key);
|
|
120
145
|
}
|
|
121
|
-
const externalNamesFiltered = (config.autoLoadSchemaPlugins !== false ? await m("extPlugins", () => registerExternalPlugins(pluginManager, offlineData)) : []).filter((k) => !pluginBaseNames.has(k.replace(/@[^@]*$/, "")));
|
|
146
|
+
const externalNamesFiltered = (config.autoLoadSchemaPlugins !== false ? await m("extPlugins", () => registerExternalPlugins(pluginManager, offlineData, { allowPrivateHosts: config.allowPrivatePluginHosts === true })) : []).filter((k) => !pluginBaseNames.has(k.replace(/@[^@]*$/, "")));
|
|
122
147
|
const allPluginNames = [
|
|
123
148
|
...pluginNames,
|
|
124
149
|
...dynamicNames,
|
|
@@ -126,6 +151,7 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
126
151
|
];
|
|
127
152
|
const entries = allPluginNames.length > 0 ? await pluginManager.getEntries(allPluginNames) : [];
|
|
128
153
|
const pluginComponents = await m("plugins", () => loadPluginComponents(entries, pluginManager.getComponents()));
|
|
154
|
+
reportMissingPlugins(spaceId, schema, /* @__PURE__ */ new Set([...Object.keys(pluginComponents), ...entries.map((entry) => entry.keyName)]));
|
|
129
155
|
const templatePlugins = (entries.length > 0 ? entries : req.ctx.spaceDeployment?.templateProps?.plugins)?.map((entry) => ({
|
|
130
156
|
...entry,
|
|
131
157
|
ssr: entry.keyName in pluginComponents
|
|
@@ -139,9 +165,9 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
139
165
|
environment: req.ctx.spaceDeployment?.environment ?? environment,
|
|
140
166
|
debugMode: debugRendered,
|
|
141
167
|
sdkDevToolsStylePath,
|
|
142
|
-
branding,
|
|
143
168
|
overQuota,
|
|
144
|
-
theme
|
|
169
|
+
theme,
|
|
170
|
+
...paintedState ? { state: paintedState } : {}
|
|
145
171
|
},
|
|
146
172
|
entries,
|
|
147
173
|
templateParams: {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { StoreMethods } from '../../core/server/fleet/channel';
|
|
1
2
|
import { DraftStore, OfflineDataRaw, SSRRequest, SSRServerConfig } from '@plitzi/sdk-shared';
|
|
2
3
|
/** The READ side of draft-preview: a render resolving a stashed draft from its token. The write side — applying
|
|
3
4
|
* unsaved operations and rendering the result — lives in `@plitzi/sdk-mcp`, which is what knows how to interpret an
|
|
4
5
|
* operation; a page-only deployment keeps this much and never loads that. */
|
|
6
|
+
/** Every method of the store, for the copy a server's workers share (see `fleet/stores.ts`). */
|
|
7
|
+
export declare const DRAFT_STORE_METHODS: StoreMethods<DraftStore>;
|
|
5
8
|
/** In-memory draft store — the default when the consumer injects none. Fine for a single replica; a multi-replica
|
|
6
9
|
* deployment must inject a shared store so a preview URL resolves on any replica. */
|
|
7
10
|
export declare const createMemoryDraftStore: () => DraftStore;
|
|
@@ -3,16 +3,23 @@ import { PREVIEW_COOKIE, readDraftToken } from "../../core/previewToken.js";
|
|
|
3
3
|
/** The READ side of draft-preview: a render resolving a stashed draft from its token. The write side — applying
|
|
4
4
|
* unsaved operations and rendering the result — lives in `@plitzi/sdk-mcp`, which is what knows how to interpret an
|
|
5
5
|
* operation; a page-only deployment keeps this much and never loads that. */
|
|
6
|
+
/** Every method of the store, for the copy a server's workers share (see `fleet/stores.ts`). */
|
|
7
|
+
var DRAFT_STORE_METHODS = {
|
|
8
|
+
put: true,
|
|
9
|
+
take: true,
|
|
10
|
+
drop: true
|
|
11
|
+
};
|
|
6
12
|
/** In-memory draft store — the default when the consumer injects none. Fine for a single replica; a multi-replica
|
|
7
13
|
* deployment must inject a shared store so a preview URL resolves on any replica. */
|
|
8
14
|
var createMemoryDraftStore = () => {
|
|
9
15
|
const store = /* @__PURE__ */ new Map();
|
|
10
16
|
return {
|
|
11
|
-
put(token, data, { ttlMs, reusable = false }) {
|
|
17
|
+
put(token, data, { ttlMs, reusable = false, spaceId }) {
|
|
12
18
|
store.set(token, {
|
|
13
19
|
data,
|
|
14
20
|
expiresAt: Date.now() + ttlMs,
|
|
15
|
-
reusable
|
|
21
|
+
reusable,
|
|
22
|
+
spaceId
|
|
16
23
|
});
|
|
17
24
|
},
|
|
18
25
|
take(token) {
|
|
@@ -21,7 +28,8 @@ var createMemoryDraftStore = () => {
|
|
|
21
28
|
if (!hit.reusable || hit.expiresAt <= Date.now()) store.delete(token);
|
|
22
29
|
return hit.expiresAt > Date.now() ? {
|
|
23
30
|
data: hit.data,
|
|
24
|
-
reusable: hit.reusable
|
|
31
|
+
reusable: hit.reusable,
|
|
32
|
+
spaceId: hit.spaceId
|
|
25
33
|
} : void 0;
|
|
26
34
|
},
|
|
27
35
|
drop(token) {
|
|
@@ -39,10 +47,12 @@ var takeDraftOverride = async (req, config) => {
|
|
|
39
47
|
const token = readDraftToken(req);
|
|
40
48
|
if (!token || !config.draftStore) return;
|
|
41
49
|
const entry = await config.draftStore.take(token);
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
if (!entry || entry.spaceId !== req.ctx.spaceDeployment?.spaceId) return;
|
|
51
|
+
return {
|
|
52
|
+
data: entry.data,
|
|
53
|
+
reusable: entry.reusable,
|
|
44
54
|
token
|
|
45
|
-
}
|
|
55
|
+
};
|
|
46
56
|
};
|
|
47
57
|
/** The `Set-Cookie` that carries a draft session through the rest of the visit. */
|
|
48
58
|
var draftSessionCookie = (req, token, ttlMs) => [
|
|
@@ -54,4 +64,4 @@ var draftSessionCookie = (req, token, ttlMs) => [
|
|
|
54
64
|
...req.protocol === "https" ? ["Secure"] : []
|
|
55
65
|
].join("; ");
|
|
56
66
|
//#endregion
|
|
57
|
-
export { createMemoryDraftStore, draftSessionCookie, takeDraftOverride };
|
|
67
|
+
export { DRAFT_STORE_METHODS, createMemoryDraftStore, draftSessionCookie, takeDraftOverride };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { PluginManager } from '../../plugins/manager';
|
|
2
2
|
import { OfflineDataRaw } from '@plitzi/sdk-shared';
|
|
3
|
+
/** Where a plugin may be read from: anywhere public, and — on a development machine only — a private address too. */
|
|
4
|
+
type ManifestReach = {
|
|
5
|
+
allowPrivateHosts: boolean;
|
|
6
|
+
};
|
|
3
7
|
/**
|
|
4
8
|
* Reads plugins listed in offlineData.plugins, fetches their manifests, downloads and caches
|
|
5
9
|
* JS/CSS via the PluginManager, and returns the effective plugin keys to pass to getEntries().
|
|
6
10
|
*/
|
|
7
|
-
export declare const registerExternalPlugins: (pluginManager: PluginManager, offlineData: OfflineDataRaw | undefined) => Promise<string[]>;
|
|
11
|
+
export declare const registerExternalPlugins: (pluginManager: PluginManager, offlineData: OfflineDataRaw | undefined, reach?: ManifestReach) => Promise<string[]>;
|
|
12
|
+
export {};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { serverLog } from "../../helpers/serverLog.js";
|
|
2
|
+
import { fetchOutbound } from "../../helpers/outboundGuard.js";
|
|
3
|
+
import { writeFileAtomic } from "../../helpers/atomicFile.js";
|
|
1
4
|
import crypto from "node:crypto";
|
|
2
5
|
import path from "node:path";
|
|
3
6
|
import fs from "node:fs/promises";
|
|
@@ -22,17 +25,17 @@ var readDiskEntry = async (dir, resource) => {
|
|
|
22
25
|
var writeDiskEntry = async (dir, resource, entry) => {
|
|
23
26
|
try {
|
|
24
27
|
await fs.mkdir(dir, { recursive: true });
|
|
25
|
-
await
|
|
28
|
+
await writeFileAtomic(cacheFilePath(dir, resource), JSON.stringify(entry));
|
|
26
29
|
} catch (err) {
|
|
27
|
-
|
|
30
|
+
serverLog.warn("SSR", `Failed to persist plugin manifest cache for ${resource}`, err);
|
|
28
31
|
}
|
|
29
32
|
};
|
|
30
|
-
var fetchAndStore = async (dir, resource) => {
|
|
33
|
+
var fetchAndStore = async (dir, resource, reach) => {
|
|
31
34
|
try {
|
|
32
35
|
const url = `${resource}/plugin-manifest.json`;
|
|
33
|
-
const res = await fetch(url);
|
|
36
|
+
const res = reach.allowPrivateHosts ? await fetch(url) : await fetchOutbound(fetch, new URL(url));
|
|
34
37
|
if (!res.ok) {
|
|
35
|
-
|
|
38
|
+
serverLog.warn("SSR", `Failed to fetch plugin manifest from ${url}: HTTP ${res.status}`);
|
|
36
39
|
return null;
|
|
37
40
|
}
|
|
38
41
|
const manifest = await res.json();
|
|
@@ -44,24 +47,24 @@ var fetchAndStore = async (dir, resource) => {
|
|
|
44
47
|
await writeDiskEntry(dir, resource, entry);
|
|
45
48
|
return manifest;
|
|
46
49
|
} catch (err) {
|
|
47
|
-
|
|
50
|
+
serverLog.warn("SSR", `Error fetching plugin manifest from ${resource}`, err);
|
|
48
51
|
return null;
|
|
49
52
|
}
|
|
50
53
|
};
|
|
51
|
-
var revalidate = (dir, resource) => {
|
|
54
|
+
var revalidate = (dir, resource, reach) => {
|
|
52
55
|
if (refreshing.has(resource)) return;
|
|
53
56
|
refreshing.add(resource);
|
|
54
|
-
fetchAndStore(dir, resource).finally(() => refreshing.delete(resource));
|
|
57
|
+
fetchAndStore(dir, resource, reach).finally(() => refreshing.delete(resource));
|
|
55
58
|
};
|
|
56
|
-
var fetchManifest = async (pluginManager, resource) => {
|
|
59
|
+
var fetchManifest = async (pluginManager, resource, reach) => {
|
|
57
60
|
const dir = manifestCacheDir(pluginManager);
|
|
58
61
|
const cached = manifestCache.get(resource) ?? await readDiskEntry(dir, resource) ?? void 0;
|
|
59
62
|
if (cached) {
|
|
60
63
|
manifestCache.set(resource, cached);
|
|
61
|
-
if (cached.expiresAt <= Date.now()) revalidate(dir, resource);
|
|
64
|
+
if (cached.expiresAt <= Date.now()) revalidate(dir, resource, reach);
|
|
62
65
|
return cached.manifest;
|
|
63
66
|
}
|
|
64
|
-
return fetchAndStore(dir, resource);
|
|
67
|
+
return fetchAndStore(dir, resource, reach);
|
|
65
68
|
};
|
|
66
69
|
var resolveAssetUrl = (resource, asset) => {
|
|
67
70
|
if (asset.url) return asset.url;
|
|
@@ -74,13 +77,13 @@ var findAsset = (manifest, type, resource) => {
|
|
|
74
77
|
return main ? resolveAssetUrl(resource, main) ?? void 0 : void 0;
|
|
75
78
|
};
|
|
76
79
|
var isAbsoluteUrl = (url) => url.startsWith("http://") || url.startsWith("https://");
|
|
77
|
-
var registerPlugin = async (pluginManager, plugin) => {
|
|
80
|
+
var registerPlugin = async (pluginManager, plugin, reach) => {
|
|
78
81
|
if (!plugin.resource || !isAbsoluteUrl(plugin.resource)) return null;
|
|
79
|
-
const manifest = await fetchManifest(pluginManager, plugin.resource);
|
|
82
|
+
const manifest = await fetchManifest(pluginManager, plugin.resource, reach);
|
|
80
83
|
if (!manifest) return null;
|
|
81
84
|
const jsUrl = findAsset(manifest, "script", plugin.resource);
|
|
82
85
|
if (!jsUrl) {
|
|
83
|
-
|
|
86
|
+
serverLog.warn("SSR", `Plugin "${plugin.type}" has no JS asset in manifest, skipping`);
|
|
84
87
|
return null;
|
|
85
88
|
}
|
|
86
89
|
const source = {
|
|
@@ -95,10 +98,10 @@ var registerPlugin = async (pluginManager, plugin) => {
|
|
|
95
98
|
* Reads plugins listed in offlineData.plugins, fetches their manifests, downloads and caches
|
|
96
99
|
* JS/CSS via the PluginManager, and returns the effective plugin keys to pass to getEntries().
|
|
97
100
|
*/
|
|
98
|
-
var registerExternalPlugins = async (pluginManager, offlineData) => {
|
|
101
|
+
var registerExternalPlugins = async (pluginManager, offlineData, reach = { allowPrivateHosts: false }) => {
|
|
99
102
|
const plugins = offlineData?.plugins;
|
|
100
103
|
if (!plugins || plugins.length === 0) return [];
|
|
101
|
-
return (await Promise.all(plugins.map((p) => registerPlugin(pluginManager, p)))).filter((k) => k !== null);
|
|
104
|
+
return (await Promise.all(plugins.map((p) => registerPlugin(pluginManager, p, reach)))).filter((k) => k !== null);
|
|
102
105
|
};
|
|
103
106
|
//#endregion
|
|
104
107
|
export { registerExternalPlugins };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Schema } from '@plitzi/sdk-shared';
|
|
2
|
+
/**
|
|
3
|
+
* The plugin types a space renders that this server has nothing for — neither a component in the render nor a bundle
|
|
4
|
+
* for the browser. Each prints "Custom Component … Not Found" where the plugin should be, and nothing else anywhere
|
|
5
|
+
* says why, so it is said here: once per space and type, at `error`, because a visitor is looking at the placeholder.
|
|
6
|
+
*
|
|
7
|
+
* A `custom` element carrying its own `scriptUrl` loads itself in the browser and is not this server's to supply.
|
|
8
|
+
*/
|
|
9
|
+
export declare const reportMissingPlugins: (spaceId: number, schema: Schema | undefined, available: ReadonlySet<string>) => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { serverLog } from "../../helpers/serverLog.js";
|
|
2
|
+
//#region src/modules/ssr/reportMissingPlugins.ts
|
|
3
|
+
var reported = /* @__PURE__ */ new Set();
|
|
4
|
+
/**
|
|
5
|
+
* The plugin types a space renders that this server has nothing for — neither a component in the render nor a bundle
|
|
6
|
+
* for the browser. Each prints "Custom Component … Not Found" where the plugin should be, and nothing else anywhere
|
|
7
|
+
* says why, so it is said here: once per space and type, at `error`, because a visitor is looking at the placeholder.
|
|
8
|
+
*
|
|
9
|
+
* A `custom` element carrying its own `scriptUrl` loads itself in the browser and is not this server's to supply.
|
|
10
|
+
*/
|
|
11
|
+
var reportMissingPlugins = (spaceId, schema, available) => {
|
|
12
|
+
if (!schema || !serverLog.enabled("error")) return;
|
|
13
|
+
for (const element of Object.values(schema.flat)) {
|
|
14
|
+
const { renderType, isPlugin, scriptUrl } = element.attributes;
|
|
15
|
+
const loadsItself = isPlugin === true && typeof scriptUrl === "string" && scriptUrl !== "";
|
|
16
|
+
if (element.definition.type !== "custom" || typeof renderType !== "string" || renderType === "" || loadsItself) continue;
|
|
17
|
+
const key = `${spaceId}:${renderType}`;
|
|
18
|
+
if (available.has(renderType) || reported.has(key)) continue;
|
|
19
|
+
reported.add(key);
|
|
20
|
+
serverLog.error("SSR", `Space ${String(spaceId)} renders the plugin "${renderType}" (element "${element.id}"), and this server has none by that name, so the page shows "Custom Component ${renderType} Not Found". Register it in \`plugins\` and name it in the deployment's \`pluginNames\`.`);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
//#endregion
|
|
24
|
+
export { reportMissingPlugins };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { TtlCache } from '../../helpers/cache';
|
|
1
|
+
import { CachedPage, TtlCache } from '../../helpers/cache';
|
|
2
2
|
import { RequestMetrics } from '../../helpers/metrics';
|
|
3
3
|
import { PluginManager } from '../../plugins/manager';
|
|
4
4
|
import { Environment, OfflineDataRaw, SSRPageServerConfig, SSRRequest, SSRResponseHelpers, SSRTemplateFn } from '@plitzi/sdk-shared';
|
|
5
|
-
export declare const streamBody: (req: SSRRequest, res: SSRResponseHelpers, config: SSRPageServerConfig, spaceId: number, environment: Environment, revision: number, renderFn: SSRTemplateFn, pluginManager: PluginManager, offlineDataCache?: TtlCache<string>, htmlCache?: TtlCache<
|
|
5
|
+
export declare const streamBody: (req: SSRRequest, res: SSRResponseHelpers, config: SSRPageServerConfig, spaceId: number, environment: Environment, revision: number, renderFn: SSRTemplateFn, pluginManager: PluginManager, offlineDataCache?: TtlCache<string>, htmlCache?: TtlCache<CachedPage>, cacheKey?: string, metrics?: RequestMetrics, offlineDataOverride?: OfflineDataRaw) => Promise<void>;
|
|
@@ -30,7 +30,10 @@ var streamBody = async (req, res, config, spaceId, environment, revision, render
|
|
|
30
30
|
const tailBuf = Buffer.from(tail, "utf-8");
|
|
31
31
|
res.write(tailBuf);
|
|
32
32
|
res.end();
|
|
33
|
-
if (chunks && cacheKey && htmlCache) htmlCache.set(cacheKey,
|
|
33
|
+
if (chunks && cacheKey && htmlCache) htmlCache.set(cacheKey, {
|
|
34
|
+
html: head + Buffer.concat(chunks).toString("utf-8") + tail,
|
|
35
|
+
compressed: {}
|
|
36
|
+
});
|
|
34
37
|
resolve();
|
|
35
38
|
cb();
|
|
36
39
|
}
|
|
@@ -122,18 +122,21 @@
|
|
|
122
122
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
123
123
|
<div id="plitzi" class="plitzi-root-container"><%- locals.html || '' %></div>
|
|
124
124
|
<% if (!locals.ssrOnly) { %>
|
|
125
|
+
<%# The payload is data, so it travels as JSON: parsing it as a JavaScript literal cost the browser several times
|
|
126
|
+
what JSON.parse does, on megabytes of it. Escaped by the server — no `<` reaches this block. %>
|
|
127
|
+
<script type="application/json" id="plitzi-ssr-data"><%- locals.offlineData || '{}' %></script>
|
|
125
128
|
<script type="module">
|
|
126
129
|
import { render } from '<%= locals.jsPath || '' %>';
|
|
127
130
|
<% const activePlugins = (locals.plugins || []).filter(p => p.js); %>
|
|
128
|
-
<% if (activePlugins.length > 0) { %>
|
|
129
131
|
<% for (const plugin of activePlugins) { %>
|
|
130
132
|
import { default as <%= plugin.varName %> } from '<%= plugin.js %>';
|
|
131
133
|
<% } %>
|
|
132
134
|
const __plitziPlugins = { <%- activePlugins.map(p => `'${p.keyName}': {component: ${p.varName}, props: ${JSON.stringify(p.props)}, clientOnly: ${p.ssr === false}}`).join(', ') %> };
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
const __plitziData = document.getElementById('plitzi-ssr-data');
|
|
136
|
+
const __plitziParams = JSON.parse(__plitziData.textContent);
|
|
137
|
+
// Read once: the page would otherwise hold the space twice, as this text and as what it was parsed into.
|
|
138
|
+
__plitziData.remove();
|
|
139
|
+
render('plitzi', __plitziParams, __plitziPlugins, <%= locals.debugMode ? true : false %>, true);
|
|
137
140
|
</script>
|
|
138
141
|
<% } %>
|
|
139
142
|
</body>
|
package/dist/mongo.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Job queue and key/value helpers for a deployment that runs Mongo. Import them as `@plitzi/sdk-server/mongo`.
|
|
2
|
+
*
|
|
3
|
+
* The scheduler and the workers are the package's; WHERE the jobs wait is the deployment's — `action.jobs.queue`
|
|
4
|
+
* and `action.kv` are adapters, and the defaults keep everything in one process's memory. That is right for one
|
|
5
|
+
* replica and wrong for two: each gets its own copy of every schedule, and the jobs a replica was holding go with it
|
|
6
|
+
* when it stops. These are those adapters, already written for Mongo, over a database the deployment connects to
|
|
7
|
+
* and owns:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { MongoClient } from 'mongodb';
|
|
11
|
+
* import { createServer } from '@plitzi/sdk-server';
|
|
12
|
+
* import { createMongoJobQueue, createMongoKv } from '@plitzi/sdk-server/mongo';
|
|
13
|
+
*
|
|
14
|
+
* const db = new MongoClient(process.env.MONGO_URL).db('app');
|
|
15
|
+
*
|
|
16
|
+
* createServer({
|
|
17
|
+
* adapters,
|
|
18
|
+
* action: { lookups, kv: createMongoKv({ db }), jobs: { queue: createMongoJobQueue({ db }) } }
|
|
19
|
+
* });
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* The package holds no connection and keeps no data of its own: it creates the indexes its queries need, in the
|
|
23
|
+
* collections it is told to use. `mongodb` is an optional peer dependency, used for its types alone. */
|
|
24
|
+
export { createMongoJobQueue, createMongoKv } from './modules/mongo';
|
|
25
|
+
export type { MongoDbSource, MongoJobQueue, MongoJobQueueOptions, MongoKvOptions } from './modules/mongo';
|
package/dist/mongo.js
ADDED
package/dist/mysql.d.ts
CHANGED
|
@@ -22,5 +22,16 @@
|
|
|
22
22
|
* The tables are documented in `docs/auth/mysql-schema.md` — what each one is for, and what a deployment mapping
|
|
23
23
|
* its existing schema onto the adapters has to be able to answer. */
|
|
24
24
|
export { createMysqlStore, mysqlSchemaStatements } from './modules/mysql';
|
|
25
|
+
/**
|
|
26
|
+
* The job queue and the key/value store server actions run on, for a deployment that keeps them in MySQL rather than
|
|
27
|
+
* in one process's memory — which is what running more than one replica needs. They borrow connections from a pool
|
|
28
|
+
* the deployment opened (`store.pool` works) and create their three tables on first use:
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* createServer({ action: { lookups, kv: createMysqlKv({ pool }), jobs: { queue: createMysqlJobQueue({ pool }) } } });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export { createMysqlJobQueue, createMysqlKv, mysqlJobSchemaStatements, mysqlJobSchemaUpgrades } from './modules/mysql/jobs';
|
|
35
|
+
export type { MysqlJobQueue, MysqlJobQueueOptions, MysqlKvOptions } from './modules/mysql/jobs';
|
|
25
36
|
export { SCHEMA_VERSION, TABLE_NAMES, tableNames } from './modules/mysql';
|
|
26
37
|
export type { AccountSeed, MysqlAdmin, MysqlConfig, IdentityStore, LinkedIdentity, MysqlStore, SessionStore, SessionSummary, SpaceTokenSeed, TableKey, Tables } from './modules/mysql';
|
package/dist/mysql.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { TABLE_NAMES, tableNames } from "./modules/mysql/config.js";
|
|
2
2
|
import { SCHEMA_VERSION } from "./modules/mysql/schema.js";
|
|
3
3
|
import { createMysqlStore, mysqlSchemaStatements } from "./modules/mysql/index.js";
|
|
4
|
-
|
|
4
|
+
import { mysqlJobSchemaStatements, mysqlJobSchemaUpgrades } from "./modules/mysql/jobs/schema.js";
|
|
5
|
+
import { createMysqlJobQueue } from "./modules/mysql/jobs/jobQueue.js";
|
|
6
|
+
import { createMysqlKv } from "./modules/mysql/jobs/kv.js";
|
|
7
|
+
export { SCHEMA_VERSION, TABLE_NAMES, createMysqlJobQueue, createMysqlKv, createMysqlStore, mysqlJobSchemaStatements, mysqlJobSchemaUpgrades, mysqlSchemaStatements, tableNames };
|
package/dist/oauth.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { dropPending, getAccess, getClient, getPending, putCode, putPending } from "./core/oauth/records.js";
|
|
1
2
|
import { AUTHORIZATION_SERVER_PATH, AUTHORIZE_PATH, PROTECTED_RESOURCE_PATH, REGISTER_PATH, TOKEN_PATH, authorizationServerMetadata, protectedResourceMetadata } from "./core/oauth/metadata.js";
|
|
2
3
|
import { randomId, verifyChallenge } from "./core/oauth/pkce.js";
|
|
3
|
-
import { dropPending, getAccess, getClient, getPending, putCode, putPending } from "./core/oauth/records.js";
|
|
4
4
|
import { redirectToSignIn, redirectWithCode, redirectWithError, sendErrorJson, sendJson } from "./core/oauth/respond.js";
|
|
5
|
+
import { handleRegister } from "./core/oauth/register.js";
|
|
5
6
|
import { handleAuthorizeStart, handleAuthorizeSubmit } from "./core/oauth/authorize.js";
|
|
6
7
|
import { bearerOf, sendChallenge } from "./core/oauth/challenge.js";
|
|
7
|
-
import { handleRegister } from "./core/oauth/register.js";
|
|
8
8
|
import { handleRevoke, handleToken } from "./core/oauth/token.js";
|
|
9
9
|
import { createOAuthGuardStage, createOAuthStage } from "./core/http/stages/oauth.js";
|
|
10
10
|
export { AUTHORIZATION_SERVER_PATH, AUTHORIZE_PATH, PROTECTED_RESOURCE_PATH, REGISTER_PATH, TOKEN_PATH, authorizationServerMetadata, bearerOf, createOAuthGuardStage, createOAuthStage, dropPending, getAccess, getClient, getPending, handleAuthorizeStart, handleAuthorizeSubmit, handleRegister, handleRevoke, handleToken, protectedResourceMetadata, putCode, putPending, randomId, redirectToSignIn, redirectWithCode, redirectWithError, sendChallenge, sendErrorJson, sendJson, verifyChallenge };
|
package/dist/plugins/compile.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { writeFileAtomic } from "../helpers/atomicFile.js";
|
|
1
2
|
import path from "node:path";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
3
|
import esbuild from "esbuild";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
4
5
|
//#region src/plugins/compile.ts
|
|
5
6
|
var EXTERNAL = [
|
|
6
7
|
"react",
|
|
@@ -29,7 +30,8 @@ var ASSET_LOADERS = {
|
|
|
29
30
|
".woff2": "dataurl"
|
|
30
31
|
};
|
|
31
32
|
/**
|
|
32
|
-
* Everything that went into the bundle, so a
|
|
33
|
+
* Everything that went into the bundle, so a server can tell when any of it has moved on: a dev server as it is
|
|
34
|
+
* edited, and any server — a deployment — when it finds a bundle built from something else (its content digest).
|
|
33
35
|
*
|
|
34
36
|
* The entry file is one file and a plugin is a directory: a component edited beside its `index.ts` leaves the entry's
|
|
35
37
|
* timestamp exactly where it was, and a watcher looking only at that never rebuilds. esbuild already knows the answer
|
|
@@ -52,10 +54,13 @@ var compilePlugin = async (jsPath, outDir, devMode = false) => {
|
|
|
52
54
|
minify: !devMode,
|
|
53
55
|
splitting: false,
|
|
54
56
|
logLevel: "warning",
|
|
55
|
-
metafile:
|
|
57
|
+
metafile: true,
|
|
58
|
+
write: false
|
|
56
59
|
});
|
|
60
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
61
|
+
await Promise.all(result.outputFiles.map((output) => writeFileAtomic(output.path, output.contents)));
|
|
57
62
|
return {
|
|
58
|
-
hasCSS:
|
|
63
|
+
hasCSS: result.outputFiles.some((output) => path.basename(output.path) === "index.css"),
|
|
59
64
|
inputs: sourceInputs(result.metafile)
|
|
60
65
|
};
|
|
61
66
|
};
|
package/dist/plugins/copy.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
+
import { copyFileAtomic, writeFileAtomic } from "../helpers/atomicFile.js";
|
|
1
2
|
import path from "node:path";
|
|
2
|
-
import fs from "node:fs/promises";
|
|
3
3
|
//#region src/plugins/copy.ts
|
|
4
4
|
var copyPlugin = async (src, destDir, filename) => {
|
|
5
5
|
const dest = path.join(destDir, filename);
|
|
6
6
|
if (src.startsWith("http://") || src.startsWith("https://")) {
|
|
7
7
|
const res = await fetch(src);
|
|
8
8
|
if (!res.ok) throw new Error(`[SSR] Plugin fetch failed ${src}: ${res.status}`);
|
|
9
|
-
await
|
|
10
|
-
} else await
|
|
9
|
+
await writeFileAtomic(dest, await res.text());
|
|
10
|
+
} else await copyFileAtomic(src, dest);
|
|
11
11
|
};
|
|
12
12
|
//#endregion
|
|
13
13
|
export { copyPlugin };
|
|
@@ -14,9 +14,18 @@ export declare class PluginManager {
|
|
|
14
14
|
hasPlugin(name: string): boolean;
|
|
15
15
|
register(name: string, source: PluginSource): void;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* Keeps a source a render names, and returns the key to pass to getEntries(): `name@version+<identity>`, or
|
|
18
|
+
* `name@<identity>` without a version.
|
|
19
|
+
*
|
|
20
|
+
* The identity is what the source IS — where its files are, how they are served, the props it carries — because a
|
|
21
|
+
* name and a version are only what its author said about it. Keyed on those alone, the first source to arrive held
|
|
22
|
+
* the key for as long as the process ran: a plugin published again under the same version kept its old, now missing
|
|
23
|
+
* URLs, and two spaces each with a `board@1.0.0` of their own were served whichever this process had met first.
|
|
24
|
+
* Worked out from the source rather than handed out in order of arrival, so every worker names one source the same
|
|
25
|
+
* way — the key is also the folder a built bundle is written to, and all of them share it.
|
|
26
|
+
*
|
|
27
|
+
* Never taken as what a bare name means: {@link resolveKey} answers for the plugins this server was set up with, not
|
|
28
|
+
* for whichever space rendered last.
|
|
20
29
|
*/
|
|
21
30
|
ensure(name: string, source: PluginSource): string;
|
|
22
31
|
/**
|
|
@@ -46,6 +55,18 @@ export declare class PluginManager {
|
|
|
46
55
|
* `checkedAt` is stamped on the cached entry rather than kept in a second map, so it cannot outlive what it is about.
|
|
47
56
|
*/
|
|
48
57
|
private isStaleInMemory;
|
|
58
|
+
/**
|
|
59
|
+
* Whether what a bundle on disk was built from reads differently now — asked once, when a process first finds the
|
|
60
|
+
* bundle, in production as much as in development.
|
|
61
|
+
*
|
|
62
|
+
* A version names a release, and a release is only as good as whoever bumps it: a deployment rebuilt from new source
|
|
63
|
+
* under the same version found last deployment's bundle in its cache folder and served it, with nothing anywhere
|
|
64
|
+
* saying so. The content decides instead. A bundle written before digests were recorded has none, and is built again
|
|
65
|
+
* once. What this server does not build from files — a download, a CDN, a component — is its version's business.
|
|
66
|
+
*/
|
|
67
|
+
private contentChanged;
|
|
68
|
+
/** The local files a bundle is built from: what the compiler reported, or the files it was copied from. */
|
|
69
|
+
private inputsOf;
|
|
49
70
|
private isStale;
|
|
50
71
|
/**
|
|
51
72
|
* The bundle's URL, stamped with when it was built.
|
|
@@ -68,10 +89,21 @@ export declare class PluginManager {
|
|
|
68
89
|
*/
|
|
69
90
|
private toRemoteEntry;
|
|
70
91
|
private isWebUrl;
|
|
92
|
+
/**
|
|
93
|
+
* Builds every registered plugin now rather than on first use. A primary does it before starting its workers, so
|
|
94
|
+
* the workers find each one built — instead of all of them compiling the same plugin into the same folder at once.
|
|
95
|
+
*/
|
|
96
|
+
prepareAll(): Promise<void>;
|
|
71
97
|
prepare(name: string): Promise<PluginEntry | null>;
|
|
72
98
|
private build;
|
|
73
99
|
getEntries(names: string[]): Promise<PluginEntry[]>;
|
|
74
100
|
getComponents(): Record<string, unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* Drops what this process remembers of a plugin — its entry, its failure, which version its name means — and
|
|
103
|
+
* leaves the disk alone. What an invalidation elsewhere in the fleet does here: that process removes the files,
|
|
104
|
+
* and each of the others only has to stop pointing at them.
|
|
105
|
+
*/
|
|
106
|
+
forget(name?: string, version?: string): void;
|
|
75
107
|
invalidate(name?: string, version?: string): Promise<void>;
|
|
76
108
|
destroy(): void;
|
|
77
109
|
private readMeta;
|