@pikku/core 0.12.107 → 0.12.112
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 +357 -0
- package/dist/analytics/analytics.d.ts +6 -0
- package/dist/analytics/analytics.js +58 -0
- package/dist/analytics/analytics.types.d.ts +156 -0
- package/dist/analytics/analytics.types.js +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
- package/dist/analytics/anonymous-analytics-identity.js +27 -0
- package/dist/analytics/compose-analytics-identity.d.ts +14 -0
- package/dist/analytics/compose-analytics-identity.js +33 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
- package/dist/analytics/cookie-analytics-identity.js +37 -0
- package/dist/analytics/define-analytics-events.d.ts +22 -0
- package/dist/analytics/define-analytics-events.js +9 -0
- package/dist/analytics/fan-out-analytics.d.ts +15 -0
- package/dist/analytics/fan-out-analytics.js +36 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.js +8 -0
- package/dist/analytics/logger-analytics-service.d.ts +14 -0
- package/dist/analytics/logger-analytics-service.js +23 -0
- package/dist/analytics/mint-cookie.d.ts +44 -0
- package/dist/analytics/mint-cookie.js +55 -0
- package/dist/dev/hot-reload.d.ts +0 -1
- package/dist/dev/hot-reload.js +4 -25
- package/dist/dev/module-runner.js +104 -25
- package/dist/errors/errors.d.ts +7 -0
- package/dist/errors/errors.js +17 -0
- package/dist/function/function-meta.types.d.ts +2 -0
- package/dist/function/function-runner.js +29 -0
- package/dist/function/functions.types.d.ts +22 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/pikku-state.d.ts +1 -1
- package/dist/scopes.d.ts +11 -0
- package/dist/scopes.js +17 -0
- package/dist/services/credential-wire-service.d.ts +1 -1
- package/dist/services/feature-flag-service.d.ts +100 -0
- package/dist/services/feature-flag-service.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/meta-service.d.ts +16 -0
- package/dist/services/meta-service.js +19 -0
- package/dist/services/webhook-service.d.ts +7 -2
- package/dist/services/webhook-service.js +11 -6
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
- package/dist/types/core.types.d.ts +23 -0
- package/dist/wirings/agent/agent-rpc.d.ts +1 -1
- package/dist/wirings/agent/agent-turn.d.ts +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +1 -1
- package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
- package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
- package/dist/wirings/flag/assert-feature-available.js +23 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
- package/dist/wirings/flag/cached-flag-source.js +96 -0
- package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
- package/dist/wirings/flag/define-feature-flags.js +32 -0
- package/dist/wirings/flag/flag.types.d.ts +97 -0
- package/dist/wirings/flag/flag.types.js +1 -0
- package/dist/wirings/flag/index.d.ts +7 -0
- package/dist/wirings/flag/index.js +5 -0
- package/dist/wirings/flag/resolve-flag.d.ts +52 -0
- package/dist/wirings/flag/resolve-flag.js +90 -0
- package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
- package/dist/wirings/flag/validate-flag-definitions.js +103 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
- package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +50 -0
- package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +38 -0
- package/knowledge/decisions/internals/index.md +2 -0
- package/package.json +11 -5
- package/run-tests.sh +17 -9
- package/src/public-surface.json +26 -0
- package/src/agent-naming.test.ts +0 -68
- package/src/api-report.test.ts +0 -138
- package/src/app-alias-surface.test.ts +0 -179
- package/src/app-leaf-surface.test.ts +0 -222
- package/src/bootstrap-compat/root.ts +0 -20
- package/src/classification/column-form.test.ts +0 -97
- package/src/classification/column-form.ts +0 -55
- package/src/classification/data-classification.ts +0 -73
- package/src/classification/index.ts +0 -40
- package/src/classification/key-ids.ts +0 -2
- package/src/classification/secret-value.test.ts +0 -204
- package/src/classification/secret-value.ts +0 -106
- package/src/crypto-utils.test.ts +0 -668
- package/src/crypto-utils.ts +0 -460
- package/src/dev/hot-reload.test.ts +0 -587
- package/src/dev/hot-reload.ts +0 -225
- package/src/dev/module-runner.test.ts +0 -235
- package/src/dev/module-runner.ts +0 -138
- package/src/dev/reload-meta.test.ts +0 -183
- package/src/dev/reload-meta.ts +0 -144
- package/src/ecosystem-tier-removed.test.ts +0 -72
- package/src/env.ts +0 -1
- package/src/errors/error-handler.ts +0 -77
- package/src/errors/error.test.ts +0 -229
- package/src/errors/errors.ts +0 -393
- package/src/errors/index.ts +0 -11
- package/src/errors/serialized-error.ts +0 -12
- package/src/factory-functions.test.ts +0 -111
- package/src/function/abort-scope.test.ts +0 -97
- package/src/function/abort-scope.ts +0 -80
- package/src/function/function-meta.types.ts +0 -151
- package/src/function/function-runner.test.ts +0 -1619
- package/src/function/function-runner.ts +0 -499
- package/src/function/functions.types.ts +0 -319
- package/src/function/index.ts +0 -40
- package/src/function/list.types.test.ts +0 -100
- package/src/function/list.types.ts +0 -69
- package/src/function/pikku-request.test.ts +0 -35
- package/src/function/pikku-request.ts +0 -17
- package/src/gopass-secrets-removed.test.ts +0 -51
- package/src/handle-error.test.ts +0 -532
- package/src/handle-error.ts +0 -64
- package/src/middleware/auth-apikey.test.ts +0 -362
- package/src/middleware/auth-apikey.ts +0 -39
- package/src/middleware/auth-bearer.test.ts +0 -566
- package/src/middleware/auth-bearer.ts +0 -83
- package/src/middleware/auth-cookie.test.ts +0 -572
- package/src/middleware/auth-cookie.ts +0 -107
- package/src/middleware/cors.test.ts +0 -579
- package/src/middleware/cors.ts +0 -103
- package/src/middleware/index.ts +0 -30
- package/src/middleware/middleware-factories.ts +0 -76
- package/src/middleware/middleware.types.ts +0 -61
- package/src/middleware/remote-auth.test.ts +0 -547
- package/src/middleware/remote-auth.ts +0 -95
- package/src/middleware/remote-jobs-secret.ts +0 -35
- package/src/middleware/require-origin.test.ts +0 -115
- package/src/middleware/require-origin.ts +0 -79
- package/src/middleware/telemetry.ts +0 -83
- package/src/middleware-runner.test.ts +0 -578
- package/src/middleware-runner.ts +0 -232
- package/src/no-any-casts.test.ts +0 -57
- package/src/no-root-barrel.test.ts +0 -122
- package/src/permissions.test.ts +0 -256
- package/src/permissions.ts +0 -217
- package/src/pikku-state.test.ts +0 -198
- package/src/pikku-state.ts +0 -206
- package/src/production-barrels-stay-lean.test.ts +0 -110
- package/src/public-surface.test.ts +0 -133
- package/src/remote.test.ts +0 -173
- package/src/remote.ts +0 -56
- package/src/removed-legacy-exports.test.ts +0 -66
- package/src/run-tests-script.test.ts +0 -67
- package/src/schema.test.ts +0 -430
- package/src/schema.ts +0 -204
- package/src/scopes.test.ts +0 -203
- package/src/scopes.ts +0 -67
- package/src/services/agent-run-state-service.ts +0 -37
- package/src/services/agent-runner-service.ts +0 -238
- package/src/services/agent-storage-service.ts +0 -39
- package/src/services/ai-embedding-service.ts +0 -9
- package/src/services/audit-service.test.ts +0 -44
- package/src/services/audit-service.ts +0 -280
- package/src/services/content-service.ts +0 -65
- package/src/services/credential-service.ts +0 -20
- package/src/services/credential-wire-service.test.ts +0 -235
- package/src/services/credential-wire-service.ts +0 -120
- package/src/services/deployment-service.ts +0 -32
- package/src/services/email-service.test.ts +0 -100
- package/src/services/email-service.ts +0 -60
- package/src/services/email-template.test.ts +0 -311
- package/src/services/email-template.ts +0 -254
- package/src/services/file-scenario-run-store.test.ts +0 -349
- package/src/services/file-scenario-run-store.ts +0 -282
- package/src/services/gateway-service.ts +0 -5
- package/src/services/http-personas-converse.test.ts +0 -274
- package/src/services/http-personas.test.ts +0 -379
- package/src/services/http-personas.ts +0 -508
- package/src/services/in-memory-agent-run-state-service.ts +0 -87
- package/src/services/in-memory-queue-service.test.ts +0 -162
- package/src/services/in-memory-queue-service.ts +0 -78
- package/src/services/in-memory-session-store.test.ts +0 -58
- package/src/services/in-memory-session-store.ts +0 -20
- package/src/services/in-memory-trigger-service.ts +0 -47
- package/src/services/in-memory-workflow-service.test.ts +0 -430
- package/src/services/in-memory-workflow-service.ts +0 -595
- package/src/services/index.ts +0 -192
- package/src/services/istanbul-coverage-service.test.ts +0 -66
- package/src/services/istanbul-coverage-service.ts +0 -59
- package/src/services/jwt-service.ts +0 -15
- package/src/services/local-content-request-handler.test.ts +0 -240
- package/src/services/local-content-request-handler.ts +0 -295
- package/src/services/local-content.test.ts +0 -186
- package/src/services/local-content.ts +0 -242
- package/src/services/local-credential-service.ts +0 -63
- package/src/services/local-email-service.test.ts +0 -182
- package/src/services/local-email-service.ts +0 -43
- package/src/services/local-gateway-service.ts +0 -51
- package/src/services/local-secrets.test.ts +0 -95
- package/src/services/local-secrets.ts +0 -71
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -45
- package/src/services/logger-console.test.ts +0 -117
- package/src/services/logger-console.ts +0 -174
- package/src/services/logger.ts +0 -48
- package/src/services/meta-service.test.ts +0 -75
- package/src/services/meta-service.ts +0 -767
- package/src/services/persona-actor-secret.test.ts +0 -68
- package/src/services/persona-actor-secret.ts +0 -70
- package/src/services/persona-sign-in.test.ts +0 -219
- package/src/services/persona-sign-in.ts +0 -238
- package/src/services/personas-service.ts +0 -191
- package/src/services/pikku-user-id.test.ts +0 -62
- package/src/services/pikku-user-id.ts +0 -13
- package/src/services/queue-webhook-service.test.ts +0 -409
- package/src/services/queue-webhook-service.ts +0 -150
- package/src/services/remote-jobs.test.ts +0 -106
- package/src/services/remote-jobs.ts +0 -92
- package/src/services/scheduler-service.ts +0 -37
- package/src/services/schema-service.ts +0 -10
- package/src/services/scope-service.ts +0 -91
- package/src/services/scoped-credential-service.test.ts +0 -86
- package/src/services/scoped-credential-service.ts +0 -63
- package/src/services/scoped-secret-service.test.ts +0 -93
- package/src/services/scoped-secret-service.ts +0 -40
- package/src/services/secret-host-binding.test.ts +0 -138
- package/src/services/secret-host-binding.ts +0 -51
- package/src/services/secret-service.ts +0 -25
- package/src/services/secretless.test.ts +0 -54
- package/src/services/secretless.ts +0 -29
- package/src/services/session-store.ts +0 -9
- package/src/services/stub-tracker.test.ts +0 -104
- package/src/services/stub-tracker.ts +0 -175
- package/src/services/system-role-guard.test.ts +0 -96
- package/src/services/system-role-guard.ts +0 -71
- package/src/services/temporary-file-service.ts +0 -76
- package/src/services/trigger-service.ts +0 -5
- package/src/services/typed-credential-service.ts +0 -83
- package/src/services/typed-secret-service.test.ts +0 -204
- package/src/services/typed-secret-service.ts +0 -132
- package/src/services/typed-variables-service.test.ts +0 -166
- package/src/services/typed-variables-service.ts +0 -166
- package/src/services/user-session-service.test.ts +0 -147
- package/src/services/user-session-service.ts +0 -85
- package/src/services/v8-coverage-service.test.ts +0 -69
- package/src/services/v8-coverage-service.ts +0 -163
- package/src/services/variables-service.ts +0 -13
- package/src/services/webhook-service.ts +0 -147
- package/src/services/workflow-service.ts +0 -120
- package/src/side-effects-are-declared.test.ts +0 -84
- package/src/source-files-stay-composable.test.ts +0 -41
- package/src/template-alias-surface.test.ts +0 -240
- package/src/test-utils.ts +0 -38
- package/src/testing/index.ts +0 -3
- package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
- package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
- package/src/testing/service-tests/channel-store-tests.ts +0 -98
- package/src/testing/service-tests/credential-service-tests.ts +0 -143
- package/src/testing/service-tests/deployment-service-tests.ts +0 -33
- package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
- package/src/testing/service-tests/secret-service-tests.ts +0 -105
- package/src/testing/service-tests/session-store-tests.ts +0 -62
- package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
- package/src/testing/service-tests/workflow-service-tests.ts +0 -308
- package/src/testing/service-tests.ts +0 -95
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -89
- package/src/types/core.types.ts +0 -446
- package/src/types/index.ts +0 -25
- package/src/types/state.types.ts +0 -226
- package/src/types/typed-credentials.test.ts +0 -72
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils/hmac.ts +0 -21
- package/src/utils/node-host-resolver.ts +0 -20
- package/src/utils/safe-fetch.test.ts +0 -515
- package/src/utils/safe-fetch.ts +0 -347
- package/src/utils.test.ts +0 -359
- package/src/utils.ts +0 -165
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
- package/src/wirings/actor-flow/index.ts +0 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
- package/src/wirings/actor-flow/run-conversation.ts +0 -280
- package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
- package/src/wirings/addon/addon-runner.ts +0 -236
- package/src/wirings/addon/addon-scopes.test.ts +0 -225
- package/src/wirings/addon/addon-secrets.test.ts +0 -391
- package/src/wirings/addon/index.ts +0 -12
- package/src/wirings/addon/remote-addon-auth.ts +0 -65
- package/src/wirings/addon/wire-addon.test.ts +0 -102
- package/src/wirings/addon/wire-addon.ts +0 -202
- package/src/wirings/addon/wire-remote-addon.ts +0 -41
- package/src/wirings/agent/agent-agui.test.ts +0 -1213
- package/src/wirings/agent/agent-agui.ts +0 -405
- package/src/wirings/agent/agent-authorization.test.ts +0 -208
- package/src/wirings/agent/agent-finalize.test.ts +0 -187
- package/src/wirings/agent/agent-finalize.ts +0 -197
- package/src/wirings/agent/agent-helpers.test.ts +0 -215
- package/src/wirings/agent/agent-helpers.ts +0 -96
- package/src/wirings/agent/agent-interrupt.test.ts +0 -833
- package/src/wirings/agent/agent-interrupt.ts +0 -400
- package/src/wirings/agent/agent-memory.test.ts +0 -397
- package/src/wirings/agent/agent-memory.ts +0 -496
- package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
- package/src/wirings/agent/agent-model-config.test.ts +0 -103
- package/src/wirings/agent/agent-model-config.ts +0 -59
- package/src/wirings/agent/agent-prepare.test.ts +0 -977
- package/src/wirings/agent/agent-prepare.ts +0 -1083
- package/src/wirings/agent/agent-registry.test.ts +0 -455
- package/src/wirings/agent/agent-registry.ts +0 -99
- package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
- package/src/wirings/agent/agent-rpc.ts +0 -116
- package/src/wirings/agent/agent-runner.test.ts +0 -1229
- package/src/wirings/agent/agent-runner.ts +0 -858
- package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
- package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
- package/src/wirings/agent/agent-stream.test.ts +0 -1800
- package/src/wirings/agent/agent-stream.ts +0 -1639
- package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
- package/src/wirings/agent/agent-turn.test.ts +0 -65
- package/src/wirings/agent/agent-turn.ts +0 -122
- package/src/wirings/agent/agent-utils.ts +0 -20
- package/src/wirings/agent/agent.types.ts +0 -676
- package/src/wirings/agent/index.ts +0 -58
- package/src/wirings/agent/voice-input.test.ts +0 -220
- package/src/wirings/agent/voice-input.ts +0 -180
- package/src/wirings/agent/voice-output.test.ts +0 -510
- package/src/wirings/agent/voice-output.ts +0 -311
- package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
- package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
- package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
- package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
- package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
- package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
- package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
- package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
- package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
- package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
- package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
- package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
- package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
- package/src/wirings/agent-scorer/index.ts +0 -23
- package/src/wirings/channel/channel-common.ts +0 -102
- package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
- package/src/wirings/channel/channel-handler.test.ts +0 -322
- package/src/wirings/channel/channel-handler.ts +0 -259
- package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
- package/src/wirings/channel/channel-host-rpc.ts +0 -69
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
- package/src/wirings/channel/channel-middleware-runner.ts +0 -126
- package/src/wirings/channel/channel-rpc-registry.ts +0 -116
- package/src/wirings/channel/channel-rpc-responder.ts +0 -117
- package/src/wirings/channel/channel-rpc-service.ts +0 -132
- package/src/wirings/channel/channel-rpc-validators.ts +0 -65
- package/src/wirings/channel/channel-rpc.test.ts +0 -841
- package/src/wirings/channel/channel-rpc.ts +0 -5
- package/src/wirings/channel/channel-rpc.types.ts +0 -160
- package/src/wirings/channel/channel-runner.ts +0 -164
- package/src/wirings/channel/channel-store.ts +0 -35
- package/src/wirings/channel/channel.types.ts +0 -193
- package/src/wirings/channel/define-channel-routes.ts +0 -5
- package/src/wirings/channel/eventhub-service.ts +0 -16
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -40
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -98
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
- package/src/wirings/channel/local/local-channel-runner.ts +0 -271
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
- package/src/wirings/channel/log-channels.ts +0 -16
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
- package/src/wirings/channel/serverless/index.ts +0 -6
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
- package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
- package/src/wirings/cli/channel/cli-approval.ts +0 -135
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
- package/src/wirings/cli/channel/index.ts +0 -6
- package/src/wirings/cli/cli-runner.test.ts +0 -969
- package/src/wirings/cli/cli-runner.ts +0 -538
- package/src/wirings/cli/cli.types.ts +0 -388
- package/src/wirings/cli/command-parser.test.ts +0 -1120
- package/src/wirings/cli/command-parser.ts +0 -713
- package/src/wirings/cli/define-cli-commands.ts +0 -13
- package/src/wirings/cli/format-cli-error.test.ts +0 -91
- package/src/wirings/cli/format-cli-error.ts +0 -96
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/credential/credential.types.ts +0 -37
- package/src/wirings/credential/define-credential.ts +0 -49
- package/src/wirings/credential/index.ts +0 -7
- package/src/wirings/credential/validate-credential-definitions.ts +0 -63
- package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
- package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
- package/src/wirings/gateway/gateway-runner.test.ts +0 -581
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -137
- package/src/wirings/gateway/index.ts +0 -15
- package/src/wirings/http/http-routes.test.ts +0 -318
- package/src/wirings/http/http-routes.ts +0 -111
- package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
- package/src/wirings/http/http-runner.test.ts +0 -503
- package/src/wirings/http/http-runner.ts +0 -462
- package/src/wirings/http/http.types.ts +0 -307
- package/src/wirings/http/index.ts +0 -27
- package/src/wirings/http/log-http-routes.ts +0 -18
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
- package/src/wirings/http/routers/path-to-regex.ts +0 -115
- package/src/wirings/http/web-request.test.ts +0 -382
- package/src/wirings/http/web-request.ts +0 -162
- package/src/wirings/mcp/index.ts +0 -26
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.test.ts +0 -588
- package/src/wirings/mcp/mcp-runner.ts +0 -330
- package/src/wirings/mcp/mcp.types.ts +0 -199
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -1
- package/src/wirings/oauth2/oauth2.types.ts +0 -12
- package/src/wirings/persona/define-personas.ts +0 -33
- package/src/wirings/persona/index.ts +0 -75
- package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
- package/src/wirings/persona/persona-app-scopes.ts +0 -74
- package/src/wirings/persona/persona-email.ts +0 -87
- package/src/wirings/persona/persona-environments.test.ts +0 -194
- package/src/wirings/persona/persona-environments.ts +0 -138
- package/src/wirings/persona/persona-mailbox.ts +0 -156
- package/src/wirings/persona/persona.test.ts +0 -230
- package/src/wirings/persona/persona.types.ts +0 -156
- package/src/wirings/persona/validate-personas.ts +0 -137
- package/src/wirings/queue/index.ts +0 -29
- package/src/wirings/queue/queue-identity.test.ts +0 -454
- package/src/wirings/queue/queue-identity.ts +0 -176
- package/src/wirings/queue/queue-runner.test.ts +0 -705
- package/src/wirings/queue/queue-runner.ts +0 -181
- package/src/wirings/queue/queue.types.ts +0 -161
- package/src/wirings/queue/register-queue-helper.ts +0 -46
- package/src/wirings/queue/signed-queue-service.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -90
- package/src/wirings/role/define-system-role.ts +0 -33
- package/src/wirings/role/index.ts +0 -13
- package/src/wirings/role/role.test.ts +0 -104
- package/src/wirings/role/role.types.ts +0 -47
- package/src/wirings/role/validate-role-definitions.ts +0 -93
- package/src/wirings/rpc/index.ts +0 -8
- package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
- package/src/wirings/rpc/rpc-runner.ts +0 -569
- package/src/wirings/rpc/rpc-types.ts +0 -87
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -16
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
- package/src/wirings/scheduler/scheduler-runner.ts +0 -138
- package/src/wirings/scheduler/scheduler.types.ts +0 -42
- package/src/wirings/scope/define-scope.ts +0 -33
- package/src/wirings/scope/index.ts +0 -15
- package/src/wirings/scope/scope.test.ts +0 -159
- package/src/wirings/scope/scope.types.ts +0 -42
- package/src/wirings/scope/validate-scope-definitions.ts +0 -107
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -70
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
- package/src/wirings/secret/validate-secret-definitions.ts +0 -88
- package/src/wirings/trigger/index.ts +0 -9
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
- package/src/wirings/trigger/trigger-runner.test.ts +0 -78
- package/src/wirings/trigger/trigger-runner.ts +0 -113
- package/src/wirings/trigger/trigger.types.ts +0 -100
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
- package/src/wirings/variable/validate-variable-definitions.ts +0 -71
- package/src/wirings/variable/variable.types.ts +0 -40
- package/src/wirings/virtual-user/index.ts +0 -107
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
- package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
- package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
- package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
- package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
- package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
- package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
- package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
- package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
- package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
- package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
- package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
- package/src/wirings/workflow/feature.test.ts +0 -131
- package/src/wirings/workflow/feature.ts +0 -59
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
- package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
- package/src/wirings/workflow/graph/graph-node.ts +0 -115
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
- package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
- package/src/wirings/workflow/graph/graph-validation.ts +0 -41
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
- package/src/wirings/workflow/index.ts +0 -107
- package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
- package/src/wirings/workflow/run-timeline.test.ts +0 -199
- package/src/wirings/workflow/run-timeline.ts +0 -185
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
- package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
- package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
- package/src/wirings/workflow/scenario-poll.test.ts +0 -64
- package/src/wirings/workflow/scenario-poll.ts +0 -27
- package/src/wirings/workflow/scenario-prose.test.ts +0 -275
- package/src/wirings/workflow/scenario-prose.ts +0 -86
- package/src/wirings/workflow/scenario-run.types.ts +0 -193
- package/src/wirings/workflow/scenario-service.test.ts +0 -147
- package/src/wirings/workflow/scenario-step-guards.ts +0 -23
- package/src/wirings/workflow/scenario-step.test.ts +0 -800
- package/src/wirings/workflow/scenario-step.types.ts +0 -262
- package/src/wirings/workflow/scenario-surface.test.ts +0 -146
- package/src/wirings/workflow/scenario-surface.ts +0 -71
- package/src/wirings/workflow/scenario.types.ts +0 -63
- package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
- package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
- package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
- package/src/wirings/workflow/workflow-approval.ts +0 -290
- package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
- package/src/wirings/workflow/workflow-constants.ts +0 -66
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
- package/src/wirings/workflow/workflow-errors.ts +0 -132
- package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
- package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
- package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
- package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
- package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
- package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
- package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
- package/src/wirings/workflow/workflow-recovery.ts +0 -192
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
- package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
- package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
- package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
- package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
- package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
- package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
- package/src/wirings/workflow/workflow-status-stream.ts +0 -144
- package/src/wirings/workflow/workflow-step-claim.ts +0 -46
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
- package/src/wirings/workflow/workflow-suspend.ts +0 -61
- package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
- package/src/wirings/workflow/workflow.types.ts +0 -268
- package/src/wirings-stay-decoupled.test.ts +0 -130
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.type-tests.json +0 -15
package/src/dev/hot-reload.ts
DELETED
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
import { watch, type FSWatcher } from 'node:fs'
|
|
2
|
-
import { stat } from 'node:fs/promises'
|
|
3
|
-
import { basename, join, resolve, relative } from 'node:path'
|
|
4
|
-
|
|
5
|
-
import { pikkuState } from '../pikku-state.js'
|
|
6
|
-
import { clearMiddlewareCache } from '../middleware-runner.js'
|
|
7
|
-
import { clearPermissionsCache } from '../permissions.js'
|
|
8
|
-
import { clearChannelMiddlewareCache } from '../wirings/channel/channel-middleware-runner.js'
|
|
9
|
-
import { httpRouter } from '../wirings/http/routers/http-router.js'
|
|
10
|
-
import type { Logger } from '../services/logger.js'
|
|
11
|
-
import type { CorePikkuFunctionConfig } from '../function/functions.types.js'
|
|
12
|
-
import {
|
|
13
|
-
createModuleRunner,
|
|
14
|
-
isTopLevelAwaitLimitation,
|
|
15
|
-
} from './module-runner.js'
|
|
16
|
-
|
|
17
|
-
export { reloadGeneratedMeta, reconcileAddonRegistry } from './reload-meta.js'
|
|
18
|
-
|
|
19
|
-
interface PikkuDevReloaderOptions {
|
|
20
|
-
srcDirectories: string[]
|
|
21
|
-
logger: Logger
|
|
22
|
-
pikkuDir?: string
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const isFunctionConfig = (
|
|
26
|
-
value: unknown
|
|
27
|
-
): value is CorePikkuFunctionConfig<any, any> => {
|
|
28
|
-
return (
|
|
29
|
-
typeof value === 'object' &&
|
|
30
|
-
value !== null &&
|
|
31
|
-
'func' in value &&
|
|
32
|
-
typeof (value as { func?: unknown }).func === 'function'
|
|
33
|
-
)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const findCompiledFile = async (
|
|
37
|
-
tsFile: string,
|
|
38
|
-
srcDir: string,
|
|
39
|
-
pikkuDir: string
|
|
40
|
-
): Promise<string | null> => {
|
|
41
|
-
const rel = relative(srcDir, tsFile).replace(/\.ts$/, '.js')
|
|
42
|
-
const candidates = [
|
|
43
|
-
join(pikkuDir, 'dist', rel),
|
|
44
|
-
join(srcDir, rel),
|
|
45
|
-
tsFile.replace(/\.ts$/, '.js'),
|
|
46
|
-
]
|
|
47
|
-
for (const candidate of candidates) {
|
|
48
|
-
try {
|
|
49
|
-
await stat(candidate)
|
|
50
|
-
return candidate
|
|
51
|
-
} catch {
|
|
52
|
-
// not found, try next
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return null
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const isWatchedTsFile = (filename: string): boolean => {
|
|
59
|
-
return (
|
|
60
|
-
filename.endsWith('.ts') &&
|
|
61
|
-
!filename.endsWith('.test.ts') &&
|
|
62
|
-
!filename.endsWith('.d.ts') &&
|
|
63
|
-
!filename.endsWith('.gen.ts') &&
|
|
64
|
-
// Hidden files: editor/sed atomic-write temps must never trigger a reload.
|
|
65
|
-
!basename(filename).startsWith('.')
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Not every reload failure is a mistake in the file: pikku's reloader emits
|
|
70
|
-
* `cjs`, which has no way to express top-level `await`, so a perfectly valid
|
|
71
|
-
* module can fail here forever. Saying so outright saves the reader from
|
|
72
|
-
* hunting a bug that is not in their code. The stack is dropped in that case
|
|
73
|
-
* because it points into esbuild rather than at anything actionable. */
|
|
74
|
-
const reloadFailureReason = (error: Error): string => {
|
|
75
|
-
if (isTopLevelAwaitLimitation(error)) {
|
|
76
|
-
return (
|
|
77
|
-
` ${error.message}\n` +
|
|
78
|
-
' This is a pikku limitation, not a mistake in your file: the hot-reloader compiles to `cjs`, ' +
|
|
79
|
-
'which cannot express top-level `await`. Move the awaited work into a function, or restart the ' +
|
|
80
|
-
'dev server to pick the file up.'
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
return ` ${error.stack ?? error.message}`
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export interface PikkuDevReloaderHandle {
|
|
87
|
-
close: () => void
|
|
88
|
-
/** Re-import every file changed since the last drain (post-codegen, once
|
|
89
|
-
* fresh meta is in state). */
|
|
90
|
-
reimportPending: () => Promise<void>
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export async function pikkuDevReloader(
|
|
94
|
-
options: PikkuDevReloaderOptions
|
|
95
|
-
): Promise<PikkuDevReloaderHandle> {
|
|
96
|
-
const { srcDirectories, logger, pikkuDir = '.pikku' } = options
|
|
97
|
-
const absSrcDirs = srcDirectories.map((d) => resolve(d))
|
|
98
|
-
const absPikkuDir = resolve(pikkuDir)
|
|
99
|
-
const watchers: FSWatcher[] = []
|
|
100
|
-
|
|
101
|
-
const functionsMap = pikkuState(null, 'function', 'functions')
|
|
102
|
-
const moduleRunner = createModuleRunner()
|
|
103
|
-
|
|
104
|
-
const handleFileChange = async (changedTsFile: string) => {
|
|
105
|
-
const start = Date.now()
|
|
106
|
-
const reloadedNames: string[] = []
|
|
107
|
-
const addedNames: string[] = []
|
|
108
|
-
|
|
109
|
-
const srcDir = absSrcDirs.find((d) => changedTsFile.startsWith(d))
|
|
110
|
-
if (!srcDir) return
|
|
111
|
-
|
|
112
|
-
const compiledFile = await findCompiledFile(
|
|
113
|
-
changedTsFile,
|
|
114
|
-
srcDir,
|
|
115
|
-
absPikkuDir
|
|
116
|
-
)
|
|
117
|
-
const importPath = compiledFile ?? changedTsFile
|
|
118
|
-
|
|
119
|
-
const result = await moduleRunner.run(importPath)
|
|
120
|
-
if (!result.ok) {
|
|
121
|
-
// Keeping the old code leaves the process disagreeing with the file on
|
|
122
|
-
// disk, and the only symptom is stale output from a function that looks
|
|
123
|
-
// correct in the editor — so the reason has to be printed here, where it
|
|
124
|
-
// is still known, rather than left for the developer to reconstruct.
|
|
125
|
-
logger.error(
|
|
126
|
-
`Failed to import: ${relative(process.cwd(), importPath)} (keeping old code)\n` +
|
|
127
|
-
reloadFailureReason(result.error)
|
|
128
|
-
)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
const mod = result.exports
|
|
132
|
-
|
|
133
|
-
// knowledge: decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md
|
|
134
|
-
for (const [exportName, exportValue] of Object.entries(mod)) {
|
|
135
|
-
if (!isFunctionConfig(exportValue)) continue
|
|
136
|
-
const isNew = !functionsMap.has(exportName)
|
|
137
|
-
functionsMap.set(exportName, exportValue)
|
|
138
|
-
if (isNew) addedNames.push(exportName)
|
|
139
|
-
else reloadedNames.push(exportName)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Re-importing re-ran the module’s wire* side effects, so reset the router
|
|
143
|
-
// and caches even when no function export changed — a wiring-only edit has
|
|
144
|
-
// to rebuild the route matchers too.
|
|
145
|
-
clearMiddlewareCache()
|
|
146
|
-
clearPermissionsCache()
|
|
147
|
-
clearChannelMiddlewareCache()
|
|
148
|
-
httpRouter.reset()
|
|
149
|
-
|
|
150
|
-
if (reloadedNames.length > 0 || addedNames.length > 0) {
|
|
151
|
-
const elapsed = Date.now() - start
|
|
152
|
-
const parts: string[] = []
|
|
153
|
-
if (reloadedNames.length > 0) parts.push(reloadedNames.join(', '))
|
|
154
|
-
if (addedNames.length > 0) parts.push(`new: ${addedNames.join(', ')}`)
|
|
155
|
-
logger.info(`Hot-reloaded: ${parts.join('; ')} (${elapsed}ms)`)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
let debounceTimer: ReturnType<typeof setTimeout> | undefined
|
|
160
|
-
const pendingChanges = new Set<string>()
|
|
161
|
-
// Files re-imported since the last reimportPending() drain, re-run after the
|
|
162
|
-
// dev server's codegen pass so registrations skipped for missing meta retry.
|
|
163
|
-
const postCodegenQueue = new Set<string>()
|
|
164
|
-
|
|
165
|
-
const safeHandleFileChange = async (file: string) => {
|
|
166
|
-
try {
|
|
167
|
-
await handleFileChange(file)
|
|
168
|
-
} catch (err) {
|
|
169
|
-
logger.error(
|
|
170
|
-
`Hot-reload error for ${relative(process.cwd(), file)}: ${err instanceof Error ? err.message : String(err)}`
|
|
171
|
-
)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const scheduleReload = (filePath: string) => {
|
|
176
|
-
pendingChanges.add(filePath)
|
|
177
|
-
if (debounceTimer) clearTimeout(debounceTimer)
|
|
178
|
-
debounceTimer = setTimeout(async () => {
|
|
179
|
-
const files = [...pendingChanges]
|
|
180
|
-
pendingChanges.clear()
|
|
181
|
-
for (const file of files) {
|
|
182
|
-
postCodegenQueue.add(file)
|
|
183
|
-
await safeHandleFileChange(file)
|
|
184
|
-
}
|
|
185
|
-
}, 50)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
for (const srcDir of absSrcDirs) {
|
|
189
|
-
try {
|
|
190
|
-
const watcher = watch(
|
|
191
|
-
srcDir,
|
|
192
|
-
{ recursive: true },
|
|
193
|
-
(eventType, filename) => {
|
|
194
|
-
if (filename && isWatchedTsFile(filename)) {
|
|
195
|
-
scheduleReload(join(srcDir, filename))
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
)
|
|
199
|
-
watchers.push(watcher)
|
|
200
|
-
} catch (err: any) {
|
|
201
|
-
logger.error(
|
|
202
|
-
`Failed to watch directory ${srcDir}: ${err?.message || err}`
|
|
203
|
-
)
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
logger.info(`Hot-reload active for: ${srcDirectories.join(', ')}`)
|
|
208
|
-
|
|
209
|
-
return {
|
|
210
|
-
close: () => {
|
|
211
|
-
if (debounceTimer) clearTimeout(debounceTimer)
|
|
212
|
-
for (const watcher of watchers) {
|
|
213
|
-
watcher.close()
|
|
214
|
-
}
|
|
215
|
-
moduleRunner.clear()
|
|
216
|
-
},
|
|
217
|
-
reimportPending: async () => {
|
|
218
|
-
const files = [...postCodegenQueue]
|
|
219
|
-
postCodegenQueue.clear()
|
|
220
|
-
for (const file of files) {
|
|
221
|
-
await safeHandleFileChange(file)
|
|
222
|
-
}
|
|
223
|
-
},
|
|
224
|
-
}
|
|
225
|
-
}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import { describe, test, beforeEach, afterEach } from 'node:test'
|
|
2
|
-
import assert from 'node:assert/strict'
|
|
3
|
-
import v8 from 'node:v8'
|
|
4
|
-
import vm from 'node:vm'
|
|
5
|
-
import { mkdtemp, writeFile, rm } from 'node:fs/promises'
|
|
6
|
-
import { createRequire } from 'node:module'
|
|
7
|
-
import { join } from 'node:path'
|
|
8
|
-
import { pathToFileURL } from 'node:url'
|
|
9
|
-
import { tmpdir } from 'node:os'
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
createModuleRunner,
|
|
13
|
-
isTopLevelAwaitLimitation,
|
|
14
|
-
} from './module-runner.js'
|
|
15
|
-
|
|
16
|
-
// A forced-GC hook without launching the process with a flag: on Bun use the
|
|
17
|
-
// native collector; on Node flip --expose-gc on just long enough to grab `gc`.
|
|
18
|
-
const getGc = (): (() => void) => {
|
|
19
|
-
const bun = (globalThis as any).Bun
|
|
20
|
-
if (bun) return () => bun.gc(true)
|
|
21
|
-
v8.setFlagsFromString('--expose-gc')
|
|
22
|
-
const gc = vm.runInNewContext('gc') as () => void
|
|
23
|
-
v8.setFlagsFromString('--no-expose-gc')
|
|
24
|
-
return () => gc()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const heapUsedMb = () => process.memoryUsage().heapUsed / 1048576
|
|
28
|
-
|
|
29
|
-
// V8's --experimental-test-coverage retains coverage data for every compiled
|
|
30
|
-
// script for the life of the run, which pins the runner's per-reload compiled
|
|
31
|
-
// functions (and would equally pin the old leaky mechanism), so a heap-growth
|
|
32
|
-
// measurement can't discriminate a leak from a non-leak while it's on. run-tests.sh
|
|
33
|
-
// exports this marker in --coverage mode (the flag itself is not visible to the
|
|
34
|
-
// isolated test child). The single-slot registry guarantee below still runs
|
|
35
|
-
// unconditionally.
|
|
36
|
-
const UNDER_COVERAGE = process.env.PIKKU_TEST_COVERAGE === '1'
|
|
37
|
-
|
|
38
|
-
describe('createModuleRunner', { concurrency: false }, () => {
|
|
39
|
-
let tmpDir: string
|
|
40
|
-
|
|
41
|
-
beforeEach(async () => {
|
|
42
|
-
tmpDir = await mkdtemp(join(tmpdir(), 'pikku-module-runner-'))
|
|
43
|
-
await writeFile(
|
|
44
|
-
join(tmpDir, 'package.json'),
|
|
45
|
-
JSON.stringify({ type: 'module' })
|
|
46
|
-
)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
afterEach(async () => {
|
|
50
|
-
await rm(tmpDir, { recursive: true, force: true })
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
test('runs a TS module and returns its exports', async () => {
|
|
54
|
-
const runner = createModuleRunner()
|
|
55
|
-
const file = join(tmpDir, 'todo.ts')
|
|
56
|
-
await writeFile(
|
|
57
|
-
file,
|
|
58
|
-
`interface Todo { id: string }
|
|
59
|
-
export const createTodo = { func: async (_s: any, d: Todo) => ({ id: d.id }) }`
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
const result = await runner.run(file)
|
|
63
|
-
assert.equal(result.ok, true)
|
|
64
|
-
const createTodo = (result as { exports: Record<string, unknown> }).exports
|
|
65
|
-
.createTodo as {
|
|
66
|
-
func: (...a: any[]) => Promise<any>
|
|
67
|
-
}
|
|
68
|
-
assert.equal(typeof createTodo.func, 'function')
|
|
69
|
-
assert.deepEqual(await createTodo.func({}, { id: 'abc' }), { id: 'abc' })
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
test('top-level import side effects hit the live singleton dependency', async () => {
|
|
73
|
-
// Delegated imports must resolve to the SAME module instance the rest of
|
|
74
|
-
// the process holds, so a user file's wire* side effect mutates live state.
|
|
75
|
-
await writeFile(
|
|
76
|
-
join(tmpDir, 'registry.js'),
|
|
77
|
-
`export const registry = new Map()
|
|
78
|
-
export const wire = (name, cfg) => registry.set(name, cfg)`
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
const runner = createModuleRunner()
|
|
82
|
-
const userFile = join(tmpDir, 'wired.ts')
|
|
83
|
-
await writeFile(
|
|
84
|
-
userFile,
|
|
85
|
-
`import { wire } from './registry.js'
|
|
86
|
-
export const createTodo = { func: async () => ({ ok: true }) }
|
|
87
|
-
wire('createTodo', createTodo)`
|
|
88
|
-
)
|
|
89
|
-
|
|
90
|
-
const result = await runner.run(userFile)
|
|
91
|
-
assert.equal(result.ok, true)
|
|
92
|
-
const mod = (result as { exports: Record<string, unknown> }).exports
|
|
93
|
-
|
|
94
|
-
// Read the dependency through the same resolver the runner uses, so we
|
|
95
|
-
// observe the exact instance the user module's `import` bound to (using a
|
|
96
|
-
// separate `import()` would resolve a distinct copy under the tsx test
|
|
97
|
-
// loader and prove nothing about live-singleton delegation).
|
|
98
|
-
const dep = createRequire(pathToFileURL(userFile))('./registry.js') as {
|
|
99
|
-
registry: Map<string, unknown>
|
|
100
|
-
}
|
|
101
|
-
assert.equal(dep.registry.has('createTodo'), true)
|
|
102
|
-
assert.strictEqual(dep.registry.get('createTodo'), mod!.createTodo)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
test('re-running the same path overwrites a single registry slot', async () => {
|
|
106
|
-
const runner = createModuleRunner()
|
|
107
|
-
const file = join(tmpDir, 'value.ts')
|
|
108
|
-
|
|
109
|
-
await writeFile(file, `export const value = { func: async () => 'v1' }`)
|
|
110
|
-
const first = await runner.run(file)
|
|
111
|
-
assert.equal(first.ok, true)
|
|
112
|
-
assert.equal(await ((first as any).exports.value as any).func(), 'v1')
|
|
113
|
-
|
|
114
|
-
await writeFile(file, `export const value = { func: async () => 'v2' }`)
|
|
115
|
-
const second = await runner.run(file)
|
|
116
|
-
assert.equal(second.ok, true)
|
|
117
|
-
assert.equal(await ((second as any).exports.value as any).func(), 'v2')
|
|
118
|
-
|
|
119
|
-
// Stable key: many reloads of one path never grow the registry.
|
|
120
|
-
for (let i = 0; i < 20; i++) await runner.run(file)
|
|
121
|
-
assert.equal(runner.size, 1)
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
test('reports a bad edit with its reason so the caller can say why', async () => {
|
|
125
|
-
const runner = createModuleRunner()
|
|
126
|
-
const file = join(tmpDir, 'broken.ts')
|
|
127
|
-
await writeFile(
|
|
128
|
-
file,
|
|
129
|
-
`export const oops = { func: async () => ( } ] syntax`
|
|
130
|
-
)
|
|
131
|
-
const result = await runner.run(file)
|
|
132
|
-
assert.equal(result.ok, false)
|
|
133
|
-
// The caller keeps serving the old code, so this error is the only thing
|
|
134
|
-
// standing between the developer and an unexplained stale response.
|
|
135
|
-
const { error } = result as { error: Error }
|
|
136
|
-
assert.ok(error instanceof Error)
|
|
137
|
-
assert.match(error.message, /broken\.ts/)
|
|
138
|
-
assert.equal(isTopLevelAwaitLimitation(error), false)
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
test('names the top-level await limitation as such', async () => {
|
|
142
|
-
const runner = createModuleRunner()
|
|
143
|
-
const file = join(tmpDir, 'tla.ts')
|
|
144
|
-
await writeFile(
|
|
145
|
-
file,
|
|
146
|
-
`const config = await Promise.resolve({ ok: true })
|
|
147
|
-
export const load = { func: async () => config }`
|
|
148
|
-
)
|
|
149
|
-
const result = await runner.run(file)
|
|
150
|
-
assert.equal(result.ok, false)
|
|
151
|
-
// Nothing is wrong with this file — the `cjs` emit is what cannot take it,
|
|
152
|
-
// and the caller has to be able to tell the developer that.
|
|
153
|
-
assert.equal(
|
|
154
|
-
isTopLevelAwaitLimitation((result as { error: Error }).error),
|
|
155
|
-
true
|
|
156
|
-
)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
test('a thrown non-Error still arrives as an Error carrying its value', async () => {
|
|
160
|
-
const runner = createModuleRunner()
|
|
161
|
-
const file = join(tmpDir, 'throws-a-string.ts')
|
|
162
|
-
await writeFile(file, `throw 'boom'`)
|
|
163
|
-
const result = await runner.run(file)
|
|
164
|
-
assert.equal(result.ok, false)
|
|
165
|
-
const { error } = result as { error: Error }
|
|
166
|
-
assert.ok(error instanceof Error)
|
|
167
|
-
assert.equal(error.message, 'boom')
|
|
168
|
-
assert.equal((error as { cause?: unknown }).cause, 'boom')
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
test('editing and reimporting a module 200x does not leak memory', async () => {
|
|
172
|
-
const gc = getGc()
|
|
173
|
-
const runner = createModuleRunner()
|
|
174
|
-
const file = join(tmpDir, 'big.ts')
|
|
175
|
-
// A sizeable module edited on every reload (the real dev pattern). The old
|
|
176
|
-
// fresh-URL reimport left one of these in the native ESM loader map per
|
|
177
|
-
// edit (~0.3-1.3 MB each) — ~84 MB (Node) / ~222 MB (Bun) over 200 edits —
|
|
178
|
-
// and OOMed. The evictable runner overwrites a single stable slot, so the
|
|
179
|
-
// previous module is collected and heap stays bounded.
|
|
180
|
-
const payload = JSON.stringify(
|
|
181
|
-
Array.from({ length: 2000 }, (_, i) => ({ i, s: 'field_' + i }))
|
|
182
|
-
)
|
|
183
|
-
const write = (marker: number) =>
|
|
184
|
-
writeFile(
|
|
185
|
-
file,
|
|
186
|
-
`export const data = ${payload}
|
|
187
|
-
export const handler = { func: async () => data.length }
|
|
188
|
-
// edit ${marker}`
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
// Warm up (first compile allocates esbuild + shared caches), then baseline.
|
|
192
|
-
await write(0)
|
|
193
|
-
await runner.run(file)
|
|
194
|
-
gc()
|
|
195
|
-
const baseline = heapUsedMb()
|
|
196
|
-
|
|
197
|
-
for (let i = 1; i <= 200; i++) {
|
|
198
|
-
await write(i)
|
|
199
|
-
const result = await runner.run(file)
|
|
200
|
-
assert.equal(result.ok, true)
|
|
201
|
-
}
|
|
202
|
-
gc()
|
|
203
|
-
const growth = heapUsedMb() - baseline
|
|
204
|
-
|
|
205
|
-
assert.equal(runner.size, 1)
|
|
206
|
-
if (UNDER_COVERAGE) return
|
|
207
|
-
assert.ok(
|
|
208
|
-
growth < 15,
|
|
209
|
-
`heap grew ${growth.toFixed(1)} MB over 200 edits (expected < 15 MB)`
|
|
210
|
-
)
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
test('a .js specifier resolves to the .ts file that actually exists', async () => {
|
|
214
|
-
// How every TypeScript source in a pikku app refers to a sibling: the
|
|
215
|
-
// import is written `.js` and only the `.ts` is on disk. Nothing else here
|
|
216
|
-
// covers it — the delegated-import test writes a real `.js` — and it is the
|
|
217
|
-
// shape that breaks under Bun once `pikku dev` has been running, where the
|
|
218
|
-
// reload fails and the process quietly keeps serving the previous code.
|
|
219
|
-
await writeFile(join(tmpDir, 'dep.ts'), `export const value = 'from-dep'`)
|
|
220
|
-
|
|
221
|
-
const runner = createModuleRunner()
|
|
222
|
-
const userFile = join(tmpDir, 'importer.ts')
|
|
223
|
-
await writeFile(
|
|
224
|
-
userFile,
|
|
225
|
-
`import { value } from './dep.js'
|
|
226
|
-
export const fn = { func: async () => value }`
|
|
227
|
-
)
|
|
228
|
-
|
|
229
|
-
const result = await runner.run(userFile)
|
|
230
|
-
assert.equal(result.ok, true)
|
|
231
|
-
const mod = (result as { exports: Record<string, unknown> }).exports
|
|
232
|
-
assert.equal(await (mod.fn as { func: () => Promise<string> }).func(), 'from-dep')
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
})
|
package/src/dev/module-runner.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import { readFile } from 'node:fs/promises'
|
|
2
|
-
import { createRequire } from 'node:module'
|
|
3
|
-
import { dirname, resolve } from 'node:path'
|
|
4
|
-
import { pathToFileURL } from 'node:url'
|
|
5
|
-
import { compileFunction } from 'node:vm'
|
|
6
|
-
import type { transformSync as EsbuildTransformSync } from 'esbuild'
|
|
7
|
-
|
|
8
|
-
type EsbuildTransform = typeof EsbuildTransformSync
|
|
9
|
-
|
|
10
|
-
let transformSync: EsbuildTransform | undefined
|
|
11
|
-
|
|
12
|
-
const loadTransform = async (): Promise<EsbuildTransform> => {
|
|
13
|
-
if (transformSync) return transformSync
|
|
14
|
-
// esbuild is a dev-only dependency hoisted from @pikku/cli at runtime; the
|
|
15
|
-
// `./dev` export is dev-only so it is never loaded in production runtimes.
|
|
16
|
-
const esbuild = await import('esbuild')
|
|
17
|
-
transformSync = esbuild.transformSync
|
|
18
|
-
return transformSync
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** The outcome of one run. A failure carries its error rather than collapsing
|
|
22
|
-
* to `null`: the caller keeps serving the previously-loaded code, so unless the
|
|
23
|
-
* reason travels with the failure the running process silently disagrees with
|
|
24
|
-
* the file on disk and nothing anywhere says why. */
|
|
25
|
-
export type PikkuModuleRunResult =
|
|
26
|
-
{ ok: true; exports: Record<string, unknown> } | { ok: false; error: Error }
|
|
27
|
-
|
|
28
|
-
export interface PikkuModuleRunner {
|
|
29
|
-
/** Run a user module by absolute path. Repeated runs of one path overwrite a
|
|
30
|
-
* single registry slot. Failure is returned, not thrown, so the caller can
|
|
31
|
-
* keep the previously-loaded code — and the discriminant makes that case
|
|
32
|
-
* impossible to read past by accident. */
|
|
33
|
-
run: (absPath: string) => Promise<PikkuModuleRunResult>
|
|
34
|
-
evict: (absPath: string) => void
|
|
35
|
-
clear: () => void
|
|
36
|
-
readonly size: number
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** esbuild states pikku's one documented reload limitation only in the text of
|
|
40
|
-
* its transform error. Matching it is worth the fragility: the developer's file
|
|
41
|
-
* is correct, and no amount of re-reading it will reveal that the reloader —
|
|
42
|
-
* not the file — is what cannot cope. */
|
|
43
|
-
export const isTopLevelAwaitLimitation = (error: Error): boolean =>
|
|
44
|
-
/top-level await/i.test(error.message)
|
|
45
|
-
|
|
46
|
-
interface BunResolver {
|
|
47
|
-
resolveSync: (specifier: string, parent: string) => string
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/** The `require` a reloaded module is run with.
|
|
51
|
-
*
|
|
52
|
-
* On Bun, `createRequire`'s referrer stops being honoured somewhere in a
|
|
53
|
-
* long-running process: the same relative specifier that resolves in a fresh
|
|
54
|
-
* script fails inside a `pikku dev` that has been up for a while, so a file
|
|
55
|
-
* importing `./sibling.js` reloads as `Cannot find module` and the developer
|
|
56
|
-
* is left serving the previous code from an edit that looked applied. Bun's
|
|
57
|
-
* own resolver still answers correctly when handed the importer's directory
|
|
58
|
-
* outright, so the specifier is resolved to an absolute path first and the
|
|
59
|
-
* referrer never has to survive the trip. Anything Bun's resolver declines —
|
|
60
|
-
* builtins among them — falls through to `require` unchanged.
|
|
61
|
-
*/
|
|
62
|
-
const createRequireForFile = (absPath: string): NodeRequire => {
|
|
63
|
-
const base = createRequire(pathToFileURL(absPath))
|
|
64
|
-
const bun = (globalThis as { Bun?: BunResolver }).Bun
|
|
65
|
-
if (!bun) return base
|
|
66
|
-
|
|
67
|
-
const importerDir = dirname(absPath)
|
|
68
|
-
const resolveThroughBun = (specifier: string): string => {
|
|
69
|
-
try {
|
|
70
|
-
return bun.resolveSync(specifier, importerDir)
|
|
71
|
-
} catch {
|
|
72
|
-
return specifier
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Only resolution is delegated; the require itself stays outside the guard so
|
|
77
|
-
// a module that throws while evaluating reports its own error rather than
|
|
78
|
-
// being retried under a second specifier.
|
|
79
|
-
const bunRequire = ((specifier: string) =>
|
|
80
|
-
base(resolveThroughBun(specifier))) as NodeRequire
|
|
81
|
-
return Object.assign(bunRequire, base)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export const createModuleRunner = (): PikkuModuleRunner => {
|
|
85
|
-
const registry = new Map<string, Record<string, unknown>>()
|
|
86
|
-
|
|
87
|
-
const run = async (filePath: string): Promise<PikkuModuleRunResult> => {
|
|
88
|
-
const absPath = resolve(filePath)
|
|
89
|
-
try {
|
|
90
|
-
const transform = await loadTransform()
|
|
91
|
-
const source = await readFile(absPath, 'utf-8')
|
|
92
|
-
const { code } = transform(source, {
|
|
93
|
-
loader: absPath.endsWith('.ts') ? 'ts' : 'js',
|
|
94
|
-
format: 'cjs',
|
|
95
|
-
sourcefile: absPath,
|
|
96
|
-
})
|
|
97
|
-
|
|
98
|
-
const fn = compileFunction(
|
|
99
|
-
code,
|
|
100
|
-
['require', 'exports', 'module', '__filename', '__dirname'],
|
|
101
|
-
{ filename: absPath }
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
const require = createRequireForFile(absPath)
|
|
105
|
-
const moduleObj: { exports: Record<string, unknown> } = { exports: {} }
|
|
106
|
-
fn(require, moduleObj.exports, moduleObj, absPath, dirname(absPath))
|
|
107
|
-
|
|
108
|
-
registry.set(absPath, moduleObj.exports)
|
|
109
|
-
return { ok: true, exports: moduleObj.exports }
|
|
110
|
-
} catch (thrown) {
|
|
111
|
-
// A bad edit, or the one known limitation: a file using top-level
|
|
112
|
-
// `await`, which cannot be emitted in `cjs` form. Normalised to an
|
|
113
|
-
// `Error` so the caller always has a message and a stack to print
|
|
114
|
-
// without re-deriving them; a non-`Error` throw keeps its original value
|
|
115
|
-
// as the `cause`.
|
|
116
|
-
return {
|
|
117
|
-
ok: false,
|
|
118
|
-
error:
|
|
119
|
-
thrown instanceof Error
|
|
120
|
-
? thrown
|
|
121
|
-
: new Error(String(thrown), { cause: thrown }),
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return {
|
|
127
|
-
run,
|
|
128
|
-
evict: (filePath: string) => {
|
|
129
|
-
registry.delete(resolve(filePath))
|
|
130
|
-
},
|
|
131
|
-
clear: () => {
|
|
132
|
-
registry.clear()
|
|
133
|
-
},
|
|
134
|
-
get size() {
|
|
135
|
-
return registry.size
|
|
136
|
-
},
|
|
137
|
-
}
|
|
138
|
-
}
|