gina 0.6.1 → 0.6.2
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 +11 -0
- package/README.md +15 -25
- package/ROADMAP.md +8 -6
- package/framework/v0.6.2/VERSION +1 -0
- package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/js/gina.js +12 -3
- package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +160 -160
- package/framework/v0.6.2/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.2/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- package/framework/{v0.6.1 → v0.6.2}/core/config.js +63 -2
- package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.js +279 -10
- package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-nunjucks.js +5 -1
- package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-swig.js +13 -1
- package/framework/{v0.6.1 → v0.6.2}/core/gna.js +31 -0
- package/framework/{v0.6.1 → v0.6.2}/core/template/conf/env.json +12 -0
- package/framework/{v0.6.1 → v0.6.2}/lib/nunjucks-filters/src/main.js +7 -1
- package/framework/{v0.6.1 → v0.6.2}/lib/proc.js +15 -1
- package/framework/{v0.6.1 → v0.6.2}/lib/swig-filters/src/main.js +12 -1
- package/framework/{v0.6.1 → v0.6.2}/lib/uuid/src/main.js +12 -3
- package/framework/{v0.6.1 → v0.6.2}/package.json +1 -1
- package/gna.js +4 -4
- package/llms.txt +5 -3
- package/package.json +3 -3
- package/schema/settings.json +22 -0
- package/script/perf/analyze-cpuprofile.js +187 -0
- package/script/perf/profile-baseline.js +811 -0
- package/script/perf/ws-codec-server.js +44 -0
- package/utils/prototypes.json_clone.js +5 -2
- package/framework/v0.6.1/VERSION +0 -1
- package/framework/v0.6.1/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
- package/framework/v0.6.1/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/AUTHORS +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/LICENSE +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/html/nolayout.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/html/static.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/android-chrome-192x192.png +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/android-chrome-512x512.png +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/apple-touch-icon.png +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/favicon-16x16.png +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/favicon-32x32.png +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/img/favicon.ico +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/ai/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/ai/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/connector.v3.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/connector.v4.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/n1ql.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/duckdb/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/duckdb/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mongodb/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mongodb/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mongodb/lib/job-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mongodb/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mysql/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/mysql/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/postgresql/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/postgresql/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/redis/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/redis/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/redis/lib/job-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/redis/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/redis/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/scylladb/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/scylladb/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/scylladb/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/sql-parser.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/sqlite/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/sqlite/lib/connector.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/sqlite/lib/job-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/connectors/sqlite/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/content.encoding +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.framework.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-json.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-nunjucks-async.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-stream.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-swig-async.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/controller.render-v1.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/inspector-window-emit.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/controller/release-banner.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/dev/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/dev/lib/class.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/dev/lib/factory.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/dev/lib/tools.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/currency.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/dist/language/en.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/dist/language/fr.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/dist/region/en.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/dist/region/fr.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/locales/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/mime.types +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/model/entity.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/model/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/model/template/entityFactory.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/model/template/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/csrf/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/csrf/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/csrf/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coep/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coep/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coop/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coop/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/corp/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/corp/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/csp/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/csp/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hsts/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hsts/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/session/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/session/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/session/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/storage/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/storage/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/storage/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/storage/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/validator/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/validator/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/validator/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/validator/src/form-validator.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/plugins/lib/validator/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/router.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/server.express.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/server.isaac.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/server.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/status.codes +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/_gitignore +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/app.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/connectors.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/routing.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/settings.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/templates.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/config/watchers.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle/locales/en.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/css/default.css +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/css/home.css +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/readme.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_public/sw.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/command/gina.bat.tpl +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/command/gina.tpl +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/conf/manifest.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/conf/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/conf/settings.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/conf/statics.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/conf/templates.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/client/json/401.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/client/json/403.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/client/json/404.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/server/html/50x.html +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/server/json/500.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/error/server/json/503.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/core/template/extensions/logger/config.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/console.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/context.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/data/LICENSE +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/data/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/data/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/data/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/dateFormat.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/json/LICENSE +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/json/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/json/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/json/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/path.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/plugins/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/plugins/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/plugins/src/api-error.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/plugins/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/prototypes.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/task.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/helpers/text.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/admin/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/admin/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/archiver/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/archiver/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/archiver/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/archiver/src/dep/jszip.min.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/archiver/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/async/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/async/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/audit/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/audit/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/audit-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authn/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authn/src/lockout.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authn/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authn/src/totp.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authz-gate/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/authz-gate/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cache/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cache/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cache/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cache/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/aliases.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/audit/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/audit/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/audit/verify.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/build.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/copy.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/cp.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/mcp-start.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/mcp.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/oas.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/openapi.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/rename.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/restart.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/start.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/status.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/stop.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/bundle/types.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/cache/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/cache/clear.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/cache/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/cache/stats.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/infer.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/migrate.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/models.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/connector/test.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/ps.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/container/stop.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/inc/args.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/inc/namespace.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/inc/reference-scan.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/inc/scaffold.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/rename.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/controller/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/get.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/link-dev.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/set.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/unset.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/env/use.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/build.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/dot.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/get.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/init.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/link-node-modules.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/link.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/msg.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/open.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/reset.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/restart.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/set.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/start.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/status.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/stop.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/tail.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/update.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/framework/version.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/gina-dev.1.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/gina-framework.1.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/gina.1.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/helper.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/export.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/import.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/i18n/scan.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/_host.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/build.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/image/run.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/inspector/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/inspector/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/inspector/open.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/man-render.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/minion/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/minion/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/minion/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/minion/kill.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/minion/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/msg.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/inc/scan.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/reset.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/port/set.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/backup.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/build.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/import.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/move.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/rename.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/restart.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/restore.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/start.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/status.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/project/stop.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/protocol/set.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/link-local.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/link-production.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/remove.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/rm.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/scope/use.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/secrets/arguments.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/secrets/check.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/secrets/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/secrets/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/secrets/scan.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/service/help.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/service/help.txt +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/service/list.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/service/man.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/service/start.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd/view/add.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd-status-format/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cmd-status-format/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/collection/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/collection/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/collection/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/collection/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/config.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-config/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-config/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-error/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-error/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-registry/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/connector-registry/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cron/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cron/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/cron/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/domain/LICENSE +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/domain/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/domain/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/domain/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto-pipe/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto-pipe/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto-types/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/dto-types/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/generator/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/i18n/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/i18n/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/image-build/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/image-build/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inherits/LICENSE +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inherits/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inherits/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inherits/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inspector-events/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inspector-events/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inspector-redact/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/inspector-redact/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/instrument/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/instrument/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/job/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/job/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/job-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/json-config-header/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/json-config-header/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/default/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/file/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/mq/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/mq/listener.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/containers/mq/speaker.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/helper.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/logger/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/math/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-dispatch/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-dispatch/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-http/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-http/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-server/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/mcp-server/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/merge/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/merge/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/merge/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/metrics/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/metrics/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/model.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/net-locality/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/net-locality/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/nunjucks-filters/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/nunjucks-filters/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/nunjucks-resolver/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/nunjucks-resolver/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/release-watch/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/release-watch/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/render-cache/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/render-cache/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/render-cache-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing/build.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing/src/radix.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing-introspect/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/routing-introspect/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/secrets/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/secrets/src/backends/env.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/secrets/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/session-store.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/shell.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/sqlite-driver.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/state.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/swig-filters/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/swig-filters/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/swig-resolver/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/swig-resolver/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/template-loaders/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/template-loaders/src/loaders/http.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/template-loaders/src/loaders/memory.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/template-loaders/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/url/README.md +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/url/index.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/url/routing.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/uuid/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/validator.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/watcher/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/watcher/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-framing/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-framing/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-query/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-query/src/main.js +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-session/package.json +0 -0
- /package/framework/{v0.6.1 → v0.6.2}/lib/ws-session/src/main.js +0 -0
|
@@ -0,0 +1,811 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* profile-baseline.js — #P34: runtime CPU profiling baseline for the
|
|
4
|
+
* native-acceleration arc (#P34-#P38).
|
|
5
|
+
*
|
|
6
|
+
* Boots a throwaway bundle in FULL ISOLATION (self-bootstrapping gina home
|
|
7
|
+
* under os.tmpdir(), HOME override — the real ~/.gina is never touched),
|
|
8
|
+
* builds it for the prod env (so the profile is not dominated by dev-mode
|
|
9
|
+
* hot-reload work), then per arm: boots it under `node --cpu-prof` (via
|
|
10
|
+
* NODE_OPTIONS, measured to reach the bundle child and to flush the profile
|
|
11
|
+
* on the SIGTERM drain path), drives load, tears down, and aggregates the
|
|
12
|
+
* bundle child's `.cpuprofile` by acceleration-candidate bucket via
|
|
13
|
+
* analyze-cpuprofile.js.
|
|
14
|
+
*
|
|
15
|
+
* The three arms mirror the 2026-07-28 assessment's prescription:
|
|
16
|
+
* render — HTTP/2 HTML renders, deliberately UNCACHED (getAssets + swig +
|
|
17
|
+
* the whole-document replace passes — a warm-cache replay would
|
|
18
|
+
* bypass exactly the #P37 candidates);
|
|
19
|
+
* upload — concurrent multipart POSTs (the streamsearch boundary-scan
|
|
20
|
+
* byte loop, #P35's target);
|
|
21
|
+
* ws — WebSocket echo over HTTP/2 extended CONNECT (the RFC 6455
|
|
22
|
+
* unmask/encode codec in lib/ws-framing, #P36's target). Runs
|
|
23
|
+
* CODEC-ISOLATED against ws-codec-server.js rather than in-bundle:
|
|
24
|
+
* every ws-handler registration shape killed the isolated boot
|
|
25
|
+
* silently (staked bug candidates; see fixture()).
|
|
26
|
+
*
|
|
27
|
+
* The bundle serves h2 over https with a run-local self-signed cert triple
|
|
28
|
+
* (private.key / certificate.crt / ca_bundle.crt) — h2c is NOT used because
|
|
29
|
+
* the port allocator carries no `http/2.0 -> http` slot (measured).
|
|
30
|
+
*
|
|
31
|
+
* Operator-invoked ONLY — never wired into the test suite or CI. Expected
|
|
32
|
+
* runtime: 2-5 minutes for all three arms. Results land in
|
|
33
|
+
* ./tmp/perf-baseline-<stamp>/ (gitignored): per-arm .cpuprofile copies,
|
|
34
|
+
* report.txt, report.json.
|
|
35
|
+
*
|
|
36
|
+
* Usage:
|
|
37
|
+
* node script/perf/profile-baseline.js # all arms
|
|
38
|
+
* node script/perf/profile-baseline.js --arm=render,ws # subset
|
|
39
|
+
* node script/perf/profile-baseline.js --keep # keep the temp home
|
|
40
|
+
* Options (defaults): --requests=3000 --concurrency=8 --upload-count=200
|
|
41
|
+
* --upload-kb=1500 --ws-sessions=8 --ws-frames=1500 --ws-payload=4096
|
|
42
|
+
* --start-port-from=9860
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
var fs = require('fs');
|
|
46
|
+
var os = require('os');
|
|
47
|
+
var path = require('path');
|
|
48
|
+
var net = require('net');
|
|
49
|
+
var http2 = require('http2');
|
|
50
|
+
var crypto = require('crypto');
|
|
51
|
+
var { spawn, spawnSync } = require('child_process');
|
|
52
|
+
|
|
53
|
+
var analyzer = require('./analyze-cpuprofile');
|
|
54
|
+
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
// Options & constants
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} name
|
|
61
|
+
* @param {*} dflt
|
|
62
|
+
* @returns {string|*} the `--name=value` argv value, or the default
|
|
63
|
+
* @inner
|
|
64
|
+
*/
|
|
65
|
+
function opt(name, dflt) {
|
|
66
|
+
var hit = process.argv.slice(2).filter(function (a) { return a.indexOf('--' + name + '=') === 0; })[0];
|
|
67
|
+
return hit ? hit.split('=').slice(1).join('=') : dflt;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var ARMS = String(opt('arm', 'render,upload,ws')).split(',').filter(Boolean);
|
|
71
|
+
var REQUESTS = parseInt(opt('requests', 3000), 10);
|
|
72
|
+
var CONCURRENCY = parseInt(opt('concurrency', 8), 10);
|
|
73
|
+
var UPLOAD_COUNT = parseInt(opt('upload-count', 200), 10);
|
|
74
|
+
var UPLOAD_KB = parseInt(opt('upload-kb', 1500), 10);
|
|
75
|
+
var WS_SESSIONS = parseInt(opt('ws-sessions', 8), 10);
|
|
76
|
+
var WS_FRAMES = parseInt(opt('ws-frames', 1500), 10);
|
|
77
|
+
var WS_PAYLOAD = parseInt(opt('ws-payload', 4096), 10);
|
|
78
|
+
var PORT_START = parseInt(opt('start-port-from', 9860), 10);
|
|
79
|
+
var KEEP = process.argv.indexOf('--keep') > -1;
|
|
80
|
+
|
|
81
|
+
var STAMP = Date.now();
|
|
82
|
+
var PROJ = 'perf' + STAMP;
|
|
83
|
+
var BUNDLE = 'demo';
|
|
84
|
+
var GINA_ROOT = path.resolve(__dirname, '..', '..');
|
|
85
|
+
var FW = require(path.join(GINA_ROOT, 'test', 'fw'));
|
|
86
|
+
var CLI = path.join(GINA_ROOT, 'bin', 'cli');
|
|
87
|
+
var CONTAINER = path.join(GINA_ROOT, 'bin', 'gina-container');
|
|
88
|
+
|
|
89
|
+
// GINA_PERF_HOME_BASE overrides where the throwaway home lives (kept real-path:
|
|
90
|
+
// a symlink-prefixed base records alias paths into every state file).
|
|
91
|
+
var HOME_BASE = process.env.GINA_PERF_HOME_BASE
|
|
92
|
+
? fs.realpathSync(process.env.GINA_PERF_HOME_BASE)
|
|
93
|
+
: fs.realpathSync(os.tmpdir());
|
|
94
|
+
var FAKE_HOME = path.join(HOME_BASE, 'gina-perf-' + STAMP);
|
|
95
|
+
// Neutral cwd for CLI + boot children: NOT the repo (the CLI auto-link drops a
|
|
96
|
+
// stray `gina` symlink at a repo cwd) and NOT the fake home (scaffolding with
|
|
97
|
+
// the cwd AT a dir containing .gina/ produced silently-dead prod scenes during
|
|
98
|
+
// bring-up; a sibling dir sidesteps both).
|
|
99
|
+
var CWD_DIR = FAKE_HOME + '-cwd';
|
|
100
|
+
var GINA_HOME = path.join(FAKE_HOME, '.gina');
|
|
101
|
+
var PROJ_DIR = path.join(FAKE_HOME, 'proj');
|
|
102
|
+
var SRC = path.join(PROJ_DIR, 'src', BUNDLE);
|
|
103
|
+
var OUT = path.join(GINA_ROOT, 'tmp', 'perf-baseline-' + STAMP);
|
|
104
|
+
|
|
105
|
+
// CLI + boot env: isolate via HOME (both bin/cli and bin/gina-container derive
|
|
106
|
+
// ~/.gina from it), silence the MQ transport, and never inherit the operator's
|
|
107
|
+
// GINA_HOMEDIR or NODE_OPTIONS (the CLI must not be profiled).
|
|
108
|
+
var CHILD_ENV = Object.assign({}, process.env, {
|
|
109
|
+
HOME : FAKE_HOME,
|
|
110
|
+
GINA_LOG_STDOUT : 'true'
|
|
111
|
+
});
|
|
112
|
+
delete CHILD_ENV.GINA_HOMEDIR;
|
|
113
|
+
delete CHILD_ENV.NODE_OPTIONS;
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Small helpers
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
/** @param {string} msg */
|
|
120
|
+
function log(msg) { process.stdout.write('[perf-baseline] ' + msg + '\n'); }
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Runs an offline gina CLI command against the isolated home. Exit status is
|
|
124
|
+
* NOT trusted (the first-run home bootstrap exits non-zero on a benign MQ
|
|
125
|
+
* teardown) — callers verify via on-disk state instead. cwd is the fake home
|
|
126
|
+
* so the CLI's auto-link step can never drop a stray `gina` symlink in the
|
|
127
|
+
* repo (it is still checked at teardown).
|
|
128
|
+
*
|
|
129
|
+
* @param {string[]} args
|
|
130
|
+
* @returns {{status: (number|null), stdout: string, stderr: string}}
|
|
131
|
+
*/
|
|
132
|
+
function runCli(args) {
|
|
133
|
+
var r = spawnSync(process.execPath, [CLI].concat(args), {
|
|
134
|
+
env: CHILD_ENV, cwd: CWD_DIR, encoding: 'utf8', timeout: 120000
|
|
135
|
+
});
|
|
136
|
+
return { status: r.status, stdout: r.stdout || '', stderr: r.stderr || '' };
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** @param {string} file @returns {object} */
|
|
140
|
+
function readJSON(file) { return JSON.parse(fs.readFileSync(file, 'utf8')); }
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Parses a gina config JSON (tolerates full-line `//` comments).
|
|
144
|
+
* @param {string} file
|
|
145
|
+
* @returns {object}
|
|
146
|
+
*/
|
|
147
|
+
function parseConfigJSON(file) {
|
|
148
|
+
var stripped = fs.readFileSync(file, 'utf8').split('\n')
|
|
149
|
+
.filter(function (l) { return !/^\s*\/\//.test(l); }).join('\n');
|
|
150
|
+
return JSON.parse(stripped);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** @param {number} ms @returns {Promise} */
|
|
154
|
+
function sleep(ms) { return new Promise(function (r) { setTimeout(r, ms); }); }
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* @param {number} port
|
|
158
|
+
* @param {number} timeoutMs
|
|
159
|
+
* @returns {Promise<boolean>} true once something listens on 127.0.0.1:port
|
|
160
|
+
*/
|
|
161
|
+
function waitForPort(port, timeoutMs) {
|
|
162
|
+
var deadline = Date.now() + timeoutMs;
|
|
163
|
+
return new Promise(function (resolve) {
|
|
164
|
+
(function poll() {
|
|
165
|
+
var sock = new net.Socket();
|
|
166
|
+
sock.setTimeout(800);
|
|
167
|
+
sock.on('connect', function () { sock.destroy(); resolve(true); });
|
|
168
|
+
sock.on('error', function () { retry(); });
|
|
169
|
+
sock.on('timeout', function () { sock.destroy(); retry(); });
|
|
170
|
+
function retry() {
|
|
171
|
+
if (Date.now() >= deadline) { return resolve(false); }
|
|
172
|
+
setTimeout(poll, 300);
|
|
173
|
+
}
|
|
174
|
+
sock.connect(port, '127.0.0.1');
|
|
175
|
+
})();
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// Phase 1 — scaffold + fixture + build
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Scaffolds project + bundle + view into the isolated home, verified through
|
|
185
|
+
* the state files (never exit codes).
|
|
186
|
+
* @returns {void} throws on failure
|
|
187
|
+
*/
|
|
188
|
+
function scaffold() {
|
|
189
|
+
fs.mkdirSync(PROJ_DIR, { recursive: true });
|
|
190
|
+
fs.mkdirSync(CWD_DIR, { recursive: true });
|
|
191
|
+
runCli(['project:add', '@' + PROJ, '--path=' + PROJ_DIR]);
|
|
192
|
+
if (!fs.existsSync(path.join(GINA_HOME, 'projects.json')) ||
|
|
193
|
+
!readJSON(path.join(GINA_HOME, 'projects.json'))[PROJ]) {
|
|
194
|
+
throw new Error('project:add did not register @' + PROJ);
|
|
195
|
+
}
|
|
196
|
+
// The CLI's auto-link of <proj>/node_modules/gina is unreliable under an
|
|
197
|
+
// isolated home; without it the release's require('gina') dies
|
|
198
|
+
// MODULE_NOT_FOUND before the bundle child logs a byte. Link explicitly.
|
|
199
|
+
var nmDir = path.join(PROJ_DIR, 'node_modules');
|
|
200
|
+
fs.mkdirSync(nmDir, { recursive: true });
|
|
201
|
+
if (!fs.existsSync(path.join(nmDir, 'gina'))) {
|
|
202
|
+
fs.symlinkSync(GINA_ROOT, path.join(nmDir, 'gina'));
|
|
203
|
+
}
|
|
204
|
+
runCli(['bundle:add', BUNDLE, '@' + PROJ, '--start-port-from=' + PORT_START]);
|
|
205
|
+
var key = BUNDLE + '@' + PROJ;
|
|
206
|
+
if (!readJSON(path.join(GINA_HOME, 'ports.reverse.json'))[key]) {
|
|
207
|
+
throw new Error('bundle:add did not register ' + key);
|
|
208
|
+
}
|
|
209
|
+
runCli(['view:add', BUNDLE, '@' + PROJ]);
|
|
210
|
+
if (!fs.existsSync(path.join(SRC, 'templates', 'html', 'content', 'homepage.html'))) {
|
|
211
|
+
throw new Error('view:add did not scaffold the homepage template');
|
|
212
|
+
}
|
|
213
|
+
log('scaffolded ' + key + ' in ' + FAKE_HOME);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Applies the arm fixtures to the bundle SRC (settings, routes, controller,
|
|
218
|
+
* ws handler, prod render-cache) and drops a self-signed cert triple for the
|
|
219
|
+
* h2-over-https boot. All served content is rebuilt from src by build().
|
|
220
|
+
* @returns {void}
|
|
221
|
+
*/
|
|
222
|
+
function fixture() {
|
|
223
|
+
// h2 + extended CONNECT + memory render-cache type
|
|
224
|
+
var settingsPath = path.join(SRC, 'config', 'settings.json');
|
|
225
|
+
var settings = parseConfigJSON(settingsPath);
|
|
226
|
+
settings.server = Object.assign({}, settings.server, {
|
|
227
|
+
protocol : 'http/2.0',
|
|
228
|
+
scheme : 'https',
|
|
229
|
+
http2Options : Object.assign({}, (settings.server || {}).http2Options, { enableConnectProtocol: true })
|
|
230
|
+
});
|
|
231
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 4));
|
|
232
|
+
|
|
233
|
+
// routes: uncached render, route-cached render, upload sink.
|
|
234
|
+
// `file: homepage` is explicit because a rule with no `file` defaults to
|
|
235
|
+
// the RULE name and only the default rule's template is scaffolded.
|
|
236
|
+
fs.writeFileSync(path.join(SRC, 'config', 'routing.json'), JSON.stringify({
|
|
237
|
+
'$schema' : 'https://gina.io/schema/routing.json',
|
|
238
|
+
'homepage' : { namespace: 'content', url: '/', method: 'GET', param: { control: 'home' } },
|
|
239
|
+
'perf-render' : {
|
|
240
|
+
namespace: 'content', url: '/render', method: 'GET',
|
|
241
|
+
param: { control: 'perfRender', file: 'homepage' }
|
|
242
|
+
},
|
|
243
|
+
'perf-upload' : { namespace: 'content', url: '/upload', method: 'POST', param: { control: 'perfUpload' } }
|
|
244
|
+
}, null, 2));
|
|
245
|
+
|
|
246
|
+
// content controller: HTML render + upload echo (mirrors the scaffold's shape)
|
|
247
|
+
fs.writeFileSync(path.join(SRC, 'controllers', 'controller.content.js'), [
|
|
248
|
+
'function DemoContentController() {',
|
|
249
|
+
' var self = this;',
|
|
250
|
+
' var appConf = this.getConfig(\'app\');',
|
|
251
|
+
'',
|
|
252
|
+
' this.home = function(req, res) {',
|
|
253
|
+
' self.renderJSON({ msg: appConf.greeting });',
|
|
254
|
+
' };',
|
|
255
|
+
'',
|
|
256
|
+
' this.perfRender = function(req, res) {',
|
|
257
|
+
' var items = [];',
|
|
258
|
+
' for (var i = 0; i < 50; i++) { items.push({ n: i, label: \'item-\' + i }); }',
|
|
259
|
+
' self.render({ msg: appConf.greeting, items: items });',
|
|
260
|
+
' };',
|
|
261
|
+
'',
|
|
262
|
+
' this.perfUpload = function(req, res) {',
|
|
263
|
+
' var files = req.files || [];',
|
|
264
|
+
' var total = 0;',
|
|
265
|
+
' for (var i = 0; i < files.length; i++) { total += files[i].size || 0; }',
|
|
266
|
+
' self.renderJSON({ count: files.length, bytes: total });',
|
|
267
|
+
' };',
|
|
268
|
+
'}',
|
|
269
|
+
'module.exports = DemoContentController',
|
|
270
|
+
''
|
|
271
|
+
].join('\n'));
|
|
272
|
+
|
|
273
|
+
// NOTE — the scaffold's index.js is left UNTOUCHED and the ws arm profiles
|
|
274
|
+
// the codec standalone via ws-codec-server.js.
|
|
275
|
+
//
|
|
276
|
+
// ⚠️ The bring-up reason for this was REFUTED on 2026-07-31 (#B182). The
|
|
277
|
+
// bring-up recorded that every WebSocket-handler registration shape — and
|
|
278
|
+
// even a pure onInitialize passthrough — made the isolated boot exit 0
|
|
279
|
+
// silently. A verbatim re-run of the documented shapes on fresh, uncontam-
|
|
280
|
+
// inated scenes booted ALIVE in 11/11 arms (seeded AND self-bootstrapping
|
|
281
|
+
// homes; dev/h1, prod/h1, prod/h2; stock, pure passthrough, the documented
|
|
282
|
+
// express-session wire-in, programmatic app.onWebSocket, and the declarative
|
|
283
|
+
// `method: "ws"` + channels/<name>.js route), each with a firing control.
|
|
284
|
+
// The bring-up's readings were almost certainly confounded by cumulative
|
|
285
|
+
// scene state — a project env.json left in place from an earlier arm, i.e.
|
|
286
|
+
// #B181, which IS real (unguarded envConf[bundle][env] at config.js:355).
|
|
287
|
+
//
|
|
288
|
+
// So an IN-BUNDLE ws arm is available whenever one is wanted (it is what
|
|
289
|
+
// #P36's re-arm measurement needs); the standalone codec server remains the
|
|
290
|
+
// right instrument for isolating codec self-time, which is why it stays.
|
|
291
|
+
|
|
292
|
+
// NOTE — deliberately NO render-cache config and NO env.json: a warm-cache
|
|
293
|
+
// replay BYPASSES the #P37 candidates (getAssets + the replace passes), so
|
|
294
|
+
// profiling the uncached render is what can convict them; and a project
|
|
295
|
+
// env.json carrying only a partial server block broke the prod boot in
|
|
296
|
+
// three measured ways during harness bring-up (host clobber -> unresolved
|
|
297
|
+
// ${host} cert path; unguarded [bundle][env] read on an empty file; the
|
|
298
|
+
// crash persisting after the file's deletion) — staked as bug candidates.
|
|
299
|
+
|
|
300
|
+
// self-signed cert triple (isaac eagerly reads all three for https)
|
|
301
|
+
var certDir = path.join(GINA_HOME, 'certificates', 'scopes', 'local', 'localhost');
|
|
302
|
+
fs.mkdirSync(certDir, { recursive: true });
|
|
303
|
+
var ssl = spawnSync('openssl', [
|
|
304
|
+
'req', '-x509', '-newkey', 'rsa:2048', '-nodes',
|
|
305
|
+
'-keyout', path.join(certDir, 'private.key'),
|
|
306
|
+
'-out', path.join(certDir, 'certificate.crt'),
|
|
307
|
+
'-days', '2', '-subj', '/CN=localhost'
|
|
308
|
+
], { encoding: 'utf8' });
|
|
309
|
+
if (ssl.status !== 0 || !fs.existsSync(path.join(certDir, 'private.key'))) {
|
|
310
|
+
throw new Error('openssl self-signed cert generation failed: ' + (ssl.stderr || ssl.status));
|
|
311
|
+
}
|
|
312
|
+
fs.copyFileSync(path.join(certDir, 'certificate.crt'), path.join(certDir, 'ca_bundle.crt'));
|
|
313
|
+
log('fixture applied (h2/https + render/upload routes)');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Builds the prod release (fixture config is BAKED into the release tree, so
|
|
318
|
+
* this must run after every fixture change).
|
|
319
|
+
* @returns {void} throws when no prod entry point was produced
|
|
320
|
+
*/
|
|
321
|
+
function build() {
|
|
322
|
+
runCli(['bundle:build', BUNDLE, '@' + PROJ, '--env=prod', '--scope=local']);
|
|
323
|
+
var relRoot = path.join(PROJ_DIR, 'releases', BUNDLE, 'local', 'prod');
|
|
324
|
+
var built = fs.existsSync(relRoot) && fs.readdirSync(relRoot).some(function (v) {
|
|
325
|
+
return fs.existsSync(path.join(relRoot, v, 'index.js'));
|
|
326
|
+
});
|
|
327
|
+
if (!built) { throw new Error('bundle:build produced no prod release under ' + relRoot); }
|
|
328
|
+
log('prod release built');
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @returns {number} the prod h2/https port from ports.reverse.json
|
|
333
|
+
*/
|
|
334
|
+
function resolvePort() {
|
|
335
|
+
var key = BUNDLE + '@' + PROJ;
|
|
336
|
+
var port = null;
|
|
337
|
+
try { port = readJSON(path.join(GINA_HOME, 'ports.reverse.json'))[key].prod['http/2.0'].https; } catch (e) { /* fall through */ }
|
|
338
|
+
if (!port) { throw new Error('could not resolve the prod http/2.0 https port for ' + key); }
|
|
339
|
+
return port;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// ---------------------------------------------------------------------------
|
|
343
|
+
// Phase 2 — per-arm boot / drive / profile collection
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Boots the bundle under --cpu-prof for one arm.
|
|
348
|
+
*
|
|
349
|
+
* @param {string} arm
|
|
350
|
+
* @param {number} port
|
|
351
|
+
* @returns {Promise<{proc: object, profDir: string, logRef: {txt: string}, exit: object}>}
|
|
352
|
+
*/
|
|
353
|
+
async function bootArm(arm, port) {
|
|
354
|
+
var profDir = path.join(OUT, 'profiles', arm);
|
|
355
|
+
fs.mkdirSync(profDir, { recursive: true });
|
|
356
|
+
var env = Object.assign({}, CHILD_ENV, {
|
|
357
|
+
NODE_ENV : 'prod',
|
|
358
|
+
NODE_OPTIONS : '--cpu-prof --cpu-prof-dir=' + profDir
|
|
359
|
+
});
|
|
360
|
+
var handle = { profDir: profDir, logRef: { txt: '' }, exit: { code: null, signal: null, done: false } };
|
|
361
|
+
handle.proc = spawn(process.execPath, [CONTAINER, BUNDLE, '@' + PROJ], {
|
|
362
|
+
env: env, cwd: CWD_DIR, stdio: ['ignore', 'pipe', 'pipe']
|
|
363
|
+
});
|
|
364
|
+
handle.proc.stdout.on('data', function (d) { handle.logRef.txt += d; });
|
|
365
|
+
handle.proc.stderr.on('data', function (d) { handle.logRef.txt += d; });
|
|
366
|
+
handle.proc.on('exit', function (code, signal) {
|
|
367
|
+
handle.exit = { code: code, signal: signal, done: true };
|
|
368
|
+
});
|
|
369
|
+
var opened = await waitForPort(port, 25000);
|
|
370
|
+
if (!opened) {
|
|
371
|
+
var exitNote = handle.exit.done
|
|
372
|
+
? 'launcher EXITED (code ' + handle.exit.code + ', signal ' + handle.exit.signal + ') before binding'
|
|
373
|
+
: 'launcher still running at deadline — a stalled boot';
|
|
374
|
+
throw new Error('[' + arm + '] port ' + port + ' never opened. ' + exitNote + '\n--- boot log:\n' + handle.logRef.txt.slice(-3000));
|
|
375
|
+
}
|
|
376
|
+
return handle;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* SIGTERM-drains the arm's boot and returns the BUNDLE child's .cpuprofile
|
|
381
|
+
* (matched by the mounted pid from the boot log; largest-file fallback). The
|
|
382
|
+
* profile is flushed by V8 on the drain-exit path — asserted non-empty here.
|
|
383
|
+
*
|
|
384
|
+
* @param {string} arm
|
|
385
|
+
* @param {object} handle - bootArm() result
|
|
386
|
+
* @returns {Promise<string>} profile path
|
|
387
|
+
*/
|
|
388
|
+
async function stopArm(arm, handle) {
|
|
389
|
+
try { handle.proc.kill('SIGTERM'); } catch (e) { /* already gone */ }
|
|
390
|
+
var until = Date.now() + 10000;
|
|
391
|
+
while (Date.now() < until && !handle.exit.done) { await sleep(150); }
|
|
392
|
+
if (!handle.exit.done) {
|
|
393
|
+
try { handle.proc.kill('SIGKILL'); } catch (e) { /* ignore */ }
|
|
394
|
+
await sleep(400);
|
|
395
|
+
}
|
|
396
|
+
await sleep(600); // let V8 finish writing the profiles
|
|
397
|
+
|
|
398
|
+
var files = fs.readdirSync(handle.profDir).filter(function (f) { return /\.cpuprofile$/.test(f); });
|
|
399
|
+
if (!files.length) { throw new Error('[' + arm + '] no .cpuprofile written — SIGKILL used, or the profiler never attached'); }
|
|
400
|
+
|
|
401
|
+
var m = handle.logRef.txt.match(/\[ FRAMEWORK \]\[ (\d+) \]/);
|
|
402
|
+
var bundlePid = m ? m[1] : null;
|
|
403
|
+
var pick = null;
|
|
404
|
+
if (bundlePid) {
|
|
405
|
+
pick = files.filter(function (f) { return f.indexOf('.' + bundlePid + '.') > -1; })[0] || null;
|
|
406
|
+
}
|
|
407
|
+
if (!pick) { // fallback: the bundle profile is the largest one
|
|
408
|
+
pick = files.sort(function (a, b) {
|
|
409
|
+
return fs.statSync(path.join(handle.profDir, b)).size - fs.statSync(path.join(handle.profDir, a)).size;
|
|
410
|
+
})[0];
|
|
411
|
+
}
|
|
412
|
+
var full = path.join(handle.profDir, pick);
|
|
413
|
+
if (fs.statSync(full).size < 1000) { throw new Error('[' + arm + '] bundle profile is empty: ' + full); }
|
|
414
|
+
log('[' + arm + '] bundle profile: ' + pick + ' (' + fs.statSync(full).size + ' bytes, pid-matched: ' + (bundlePid ? 'yes' : 'no') + ')');
|
|
415
|
+
return full;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* @param {number} port
|
|
420
|
+
* @returns {object} an h2 client session to the bundle (self-signed tolerated)
|
|
421
|
+
* @inner
|
|
422
|
+
*/
|
|
423
|
+
function h2Session(port) {
|
|
424
|
+
return http2.connect('https://127.0.0.1:' + port, { rejectUnauthorized: false });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Sequentially GETs `reqPath` n times on one session, discarding bodies.
|
|
429
|
+
*
|
|
430
|
+
* @param {object} client
|
|
431
|
+
* @param {string} reqPath
|
|
432
|
+
* @param {number} n
|
|
433
|
+
* @param {object} stats - {codes: object} accumulator
|
|
434
|
+
* @returns {Promise<void>}
|
|
435
|
+
* @inner
|
|
436
|
+
*/
|
|
437
|
+
function seqGet(client, reqPath, n, stats) {
|
|
438
|
+
return new Promise(function (resolve, reject) {
|
|
439
|
+
(function one(left) {
|
|
440
|
+
if (left <= 0) { return resolve(); }
|
|
441
|
+
var req = client.request({ ':path': reqPath });
|
|
442
|
+
req.on('response', function (h) {
|
|
443
|
+
var s = h[':status'];
|
|
444
|
+
stats.codes[s] = (stats.codes[s] || 0) + 1;
|
|
445
|
+
});
|
|
446
|
+
req.on('data', function () { /* discard */ });
|
|
447
|
+
req.on('end', function () { one(left - 1); });
|
|
448
|
+
req.on('error', reject);
|
|
449
|
+
})(n);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Render arm: N uncached renders then N route-cached renders, C sessions.
|
|
455
|
+
*
|
|
456
|
+
* @param {number} port
|
|
457
|
+
* @returns {Promise<object>} driver stats
|
|
458
|
+
*/
|
|
459
|
+
async function driveRender(port) {
|
|
460
|
+
var webroot = '/' + BUNDLE;
|
|
461
|
+
var stats = { arm: 'render', codes: {}, requests: REQUESTS, startMs: Date.now() };
|
|
462
|
+
var clients = [];
|
|
463
|
+
for (var c = 0; c < CONCURRENCY; c++) { clients.push(h2Session(port)); }
|
|
464
|
+
var per = Math.ceil(REQUESTS / CONCURRENCY);
|
|
465
|
+
try {
|
|
466
|
+
await Promise.all(clients.map(function (cl) { return seqGet(cl, webroot + '/render', per, stats); }));
|
|
467
|
+
} finally {
|
|
468
|
+
clients.forEach(function (cl) { try { cl.close(); } catch (e) { /* ignore */ } });
|
|
469
|
+
}
|
|
470
|
+
stats.wallMs = Date.now() - stats.startMs;
|
|
471
|
+
return stats;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Upload arm: concurrent multipart POSTs of a random binary payload.
|
|
476
|
+
*
|
|
477
|
+
* @param {number} port
|
|
478
|
+
* @returns {Promise<object>} driver stats
|
|
479
|
+
*/
|
|
480
|
+
async function driveUpload(port) {
|
|
481
|
+
var boundary = '----ginaPerf' + STAMP;
|
|
482
|
+
var head = Buffer.from(
|
|
483
|
+
'--' + boundary + '\r\n' +
|
|
484
|
+
'Content-Disposition: form-data; name="file"; filename="blob.bin"\r\n' +
|
|
485
|
+
'Content-Type: application/octet-stream\r\n\r\n');
|
|
486
|
+
var tail = Buffer.from('\r\n--' + boundary + '--\r\n');
|
|
487
|
+
var body = Buffer.concat([head, crypto.randomBytes(UPLOAD_KB * 1024), tail]);
|
|
488
|
+
|
|
489
|
+
var stats = { arm: 'upload', codes: {}, requests: UPLOAD_COUNT, bodyBytes: body.length, startMs: Date.now() };
|
|
490
|
+
var conc = Math.min(CONCURRENCY, 4);
|
|
491
|
+
var clients = [];
|
|
492
|
+
for (var c = 0; c < conc; c++) { clients.push(h2Session(port)); }
|
|
493
|
+
|
|
494
|
+
function postOne(client) {
|
|
495
|
+
return new Promise(function (resolve, reject) {
|
|
496
|
+
var req = client.request({
|
|
497
|
+
':method' : 'POST',
|
|
498
|
+
':path' : '/' + BUNDLE + '/upload',
|
|
499
|
+
'content-type' : 'multipart/form-data; boundary=' + boundary,
|
|
500
|
+
'content-length' : body.length
|
|
501
|
+
});
|
|
502
|
+
req.on('response', function (h) {
|
|
503
|
+
var s = h[':status'];
|
|
504
|
+
stats.codes[s] = (stats.codes[s] || 0) + 1;
|
|
505
|
+
});
|
|
506
|
+
req.on('data', function () { /* discard */ });
|
|
507
|
+
req.on('end', resolve);
|
|
508
|
+
req.on('error', reject);
|
|
509
|
+
req.end(body);
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
var per = Math.ceil(UPLOAD_COUNT / conc);
|
|
513
|
+
try {
|
|
514
|
+
await Promise.all(clients.map(function (cl) {
|
|
515
|
+
return (function loop(left) {
|
|
516
|
+
if (left <= 0) { return Promise.resolve(); }
|
|
517
|
+
return postOne(cl).then(function () { return loop(left - 1); });
|
|
518
|
+
})(per);
|
|
519
|
+
}));
|
|
520
|
+
} finally {
|
|
521
|
+
clients.forEach(function (cl) { try { cl.close(); } catch (e) { /* ignore */ } });
|
|
522
|
+
}
|
|
523
|
+
stats.wallMs = Date.now() - stats.startMs;
|
|
524
|
+
return stats;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* WS arm: S extended-CONNECT sessions, each ping-ponging N masked TEXT frames
|
|
529
|
+
* against the echo handler (client masks per RFC 6455 §5.1, so every inbound
|
|
530
|
+
* payload byte exercises the server's unmask loop; every echo exercises the
|
|
531
|
+
* encode side). The client codec is the framework's own lib/ws-framing.
|
|
532
|
+
*
|
|
533
|
+
* @param {number} port
|
|
534
|
+
* @returns {Promise<object>} driver stats
|
|
535
|
+
*/
|
|
536
|
+
async function driveWs(port) {
|
|
537
|
+
var wsf = require(path.join(FW, 'lib', 'ws-framing', 'src', 'main.js'));
|
|
538
|
+
var payload = 'x'.repeat(WS_PAYLOAD);
|
|
539
|
+
var stats = { arm: 'ws', sessions: WS_SESSIONS, framesPerSession: WS_FRAMES, payloadBytes: WS_PAYLOAD, echoes: 0, startMs: Date.now() };
|
|
540
|
+
|
|
541
|
+
function oneSession() {
|
|
542
|
+
return new Promise(function (resolve, reject) {
|
|
543
|
+
var client = http2.connect('http://127.0.0.1:' + port);
|
|
544
|
+
var guard = setTimeout(function () {
|
|
545
|
+
try { client.close(); } catch (e) { /* ignore */ }
|
|
546
|
+
reject(new Error('ws session timed out (' + stats.echoes + ' echoes so far)'));
|
|
547
|
+
}, 120000);
|
|
548
|
+
client.on('error', reject);
|
|
549
|
+
client.on('remoteSettings', function () {
|
|
550
|
+
var req = client.request({
|
|
551
|
+
':method': 'CONNECT', ':protocol': 'websocket', ':scheme': 'http',
|
|
552
|
+
':path': '/live', ':authority': '127.0.0.1:' + port
|
|
553
|
+
});
|
|
554
|
+
var sent = 0;
|
|
555
|
+
var parser = wsf.createParser({
|
|
556
|
+
isServer : false,
|
|
557
|
+
onMessage : function () {
|
|
558
|
+
stats.echoes++;
|
|
559
|
+
if (sent < WS_FRAMES) { pump(); }
|
|
560
|
+
else {
|
|
561
|
+
// Close: code 1000 + reason, masked like every client frame
|
|
562
|
+
req.write(wsf.encodeFrame({
|
|
563
|
+
opcode : wsf.OPCODES.CLOSE,
|
|
564
|
+
payload : Buffer.concat([Buffer.from([0x03, 0xe8]), Buffer.from('done')]),
|
|
565
|
+
mask : true
|
|
566
|
+
}));
|
|
567
|
+
req.end();
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
onClose : function () { /* server echoes the close */ },
|
|
571
|
+
onError : function (e) { reject(e); }
|
|
572
|
+
});
|
|
573
|
+
function pump() {
|
|
574
|
+
sent++;
|
|
575
|
+
req.write(wsf.encodeFrame({ opcode: wsf.OPCODES.TEXT, payload: payload, mask: true }));
|
|
576
|
+
}
|
|
577
|
+
req.on('error', reject);
|
|
578
|
+
req.on('response', function (h) {
|
|
579
|
+
if (h[':status'] !== 200) { return reject(new Error('ws handshake refused: ' + h[':status'])); }
|
|
580
|
+
req.on('data', function (chunk) { parser.feed(chunk); });
|
|
581
|
+
pump();
|
|
582
|
+
});
|
|
583
|
+
req.on('close', function () {
|
|
584
|
+
clearTimeout(guard);
|
|
585
|
+
try { client.close(); } catch (e) { /* ignore */ }
|
|
586
|
+
resolve();
|
|
587
|
+
});
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
var sessions = [];
|
|
593
|
+
for (var s = 0; s < WS_SESSIONS; s++) { sessions.push(oneSession()); }
|
|
594
|
+
await Promise.all(sessions);
|
|
595
|
+
stats.wallMs = Date.now() - stats.startMs;
|
|
596
|
+
return stats;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* The whole ws arm: spawns ws-codec-server.js under `node --cpu-prof` (direct
|
|
601
|
+
* argv — no bundle boot involved; see the fixture() note), drives the echo
|
|
602
|
+
* load, SIGTERM-collects the server's profile.
|
|
603
|
+
*
|
|
604
|
+
* @returns {Promise<{stats: object, profile: string}>}
|
|
605
|
+
*/
|
|
606
|
+
async function runWsArm() {
|
|
607
|
+
var profDir = path.join(OUT, 'profiles', 'ws');
|
|
608
|
+
fs.mkdirSync(profDir, { recursive: true });
|
|
609
|
+
var srv = spawn(process.execPath,
|
|
610
|
+
['--cpu-prof', '--cpu-prof-dir=' + profDir, path.join(__dirname, 'ws-codec-server.js')],
|
|
611
|
+
{ env: CHILD_ENV, cwd: CWD_DIR, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
612
|
+
var out = { txt: '' };
|
|
613
|
+
var exited = { done: false };
|
|
614
|
+
srv.stdout.on('data', function (d) { out.txt += d; });
|
|
615
|
+
srv.stderr.on('data', function (d) { out.txt += d; });
|
|
616
|
+
srv.on('exit', function () { exited.done = true; });
|
|
617
|
+
|
|
618
|
+
var deadline = Date.now() + 10000;
|
|
619
|
+
var port = null;
|
|
620
|
+
while (Date.now() < deadline && !port) {
|
|
621
|
+
var m = out.txt.match(/PORT (\d+)/);
|
|
622
|
+
if (m) { port = parseInt(m[1], 10); break; }
|
|
623
|
+
if (exited.done) { break; }
|
|
624
|
+
await sleep(150);
|
|
625
|
+
}
|
|
626
|
+
if (!port) {
|
|
627
|
+
try { srv.kill('SIGKILL'); } catch (e) { /* ignore */ }
|
|
628
|
+
throw new Error('[ws] codec server never reported a port.\n' + out.txt.slice(-1500));
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
var stats;
|
|
632
|
+
try {
|
|
633
|
+
stats = await driveWs(port);
|
|
634
|
+
} finally {
|
|
635
|
+
try { srv.kill('SIGTERM'); } catch (e) { /* ignore */ }
|
|
636
|
+
}
|
|
637
|
+
var until = Date.now() + 6000;
|
|
638
|
+
while (Date.now() < until && !exited.done) { await sleep(150); }
|
|
639
|
+
await sleep(600); // profile flush
|
|
640
|
+
|
|
641
|
+
var files = fs.readdirSync(profDir).filter(function (f) { return /\.cpuprofile$/.test(f); });
|
|
642
|
+
if (!files.length) { throw new Error('[ws] no .cpuprofile written by the codec server'); }
|
|
643
|
+
var pick = files.sort(function (a, b) {
|
|
644
|
+
return fs.statSync(path.join(profDir, b)).size - fs.statSync(path.join(profDir, a)).size;
|
|
645
|
+
})[0];
|
|
646
|
+
var full = path.join(profDir, pick);
|
|
647
|
+
log('[ws] codec-server profile: ' + pick + ' (' + fs.statSync(full).size + ' bytes)');
|
|
648
|
+
return { stats: stats, profile: full };
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Fires a few webroot GETs so the JIT is warm before the measured load.
|
|
653
|
+
* @param {number} port
|
|
654
|
+
* @returns {Promise<void>}
|
|
655
|
+
*/
|
|
656
|
+
async function warmup(port) {
|
|
657
|
+
var client = h2Session(port);
|
|
658
|
+
var stats = { codes: {} };
|
|
659
|
+
try { await seqGet(client, '/' + BUNDLE + '/', 25, stats); }
|
|
660
|
+
finally { try { client.close(); } catch (e) { /* ignore */ } }
|
|
661
|
+
if (!stats.codes[200]) { throw new Error('warmup never saw a 200: ' + JSON.stringify(stats.codes)); }
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// ---------------------------------------------------------------------------
|
|
665
|
+
// Phase 3 — teardown & safety checks
|
|
666
|
+
// ---------------------------------------------------------------------------
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Best-effort teardown: remove the throwaway project + home, hunt surviving
|
|
670
|
+
* processes of THIS run by project name (never other gina processes), verify
|
|
671
|
+
* the real ~/.gina was untouched, and check for the stray repo-root `gina`
|
|
672
|
+
* self-symlink the CLI auto-link step can drop.
|
|
673
|
+
* @returns {string[]} human-readable warnings (empty = clean)
|
|
674
|
+
*/
|
|
675
|
+
function teardown() {
|
|
676
|
+
var warnings = [];
|
|
677
|
+
if (!KEEP) { // --keep preserves the WHOLE scene (incl. the registration) for forensics
|
|
678
|
+
try { runCli(['project:rm', '@' + PROJ, '--force']); } catch (e) { /* best effort */ }
|
|
679
|
+
try { fs.rmSync(FAKE_HOME, { recursive: true, force: true }); } catch (e) { warnings.push('could not remove ' + FAKE_HOME + ': ' + e.message); }
|
|
680
|
+
try { fs.rmSync(CWD_DIR, { recursive: true, force: true }); } catch (e) { /* ignore */ }
|
|
681
|
+
} else {
|
|
682
|
+
warnings.push('--keep: left ' + FAKE_HOME + ' and the @' + PROJ + ' registration in place');
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// survivors of THIS run only (bundle title is 'gina: demo@perf<stamp>')
|
|
686
|
+
try {
|
|
687
|
+
var ps = spawnSync('ps', ['-eo', 'pid,command'], { encoding: 'utf8' }).stdout || '';
|
|
688
|
+
ps.split('\n').forEach(function (line) {
|
|
689
|
+
if (line.indexOf('@' + PROJ) === -1) { return; }
|
|
690
|
+
var pid = parseInt(line.trim().split(/\s+/)[0], 10);
|
|
691
|
+
if (pid && pid !== process.pid) {
|
|
692
|
+
try { process.kill(pid, 'SIGTERM'); warnings.push('killed surviving process ' + pid + ' (' + line.trim().slice(0, 90) + ')'); } catch (e) { /* gone */ }
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
if (/gina: inspector@gina/.test(ps)) {
|
|
696
|
+
warnings.push('an inspector@gina process is running — NOT killed (may belong to another session); ps-hunt it manually if it is this run\'s leak');
|
|
697
|
+
}
|
|
698
|
+
} catch (e) { /* ps unavailable — skip */ }
|
|
699
|
+
|
|
700
|
+
// the real home must be untouched
|
|
701
|
+
try {
|
|
702
|
+
var realProjects = path.join(os.homedir(), '.gina', 'projects.json');
|
|
703
|
+
if (fs.existsSync(realProjects) && readJSON(realProjects)[PROJ]) {
|
|
704
|
+
warnings.push('LEAK: @' + PROJ + ' registered in the REAL ~/.gina/projects.json — remove it');
|
|
705
|
+
}
|
|
706
|
+
} catch (e) { /* unreadable — ignore */ }
|
|
707
|
+
try {
|
|
708
|
+
var realDot = path.join(os.homedir(), '.' + PROJ);
|
|
709
|
+
if (fs.existsSync(realDot)) {
|
|
710
|
+
if (!fs.readdirSync(realDot).length) { fs.rmdirSync(realDot); }
|
|
711
|
+
else { warnings.push('LEAK: non-empty ' + realDot + ' on the real home'); }
|
|
712
|
+
}
|
|
713
|
+
} catch (e) { /* ignore */ }
|
|
714
|
+
|
|
715
|
+
// stray self-symlink at the repo root
|
|
716
|
+
try {
|
|
717
|
+
var stray = path.join(GINA_ROOT, 'gina');
|
|
718
|
+
if (fs.existsSync(stray) && fs.lstatSync(stray).isSymbolicLink()) {
|
|
719
|
+
fs.unlinkSync(stray);
|
|
720
|
+
warnings.push('removed a stray `gina` self-symlink at the repo root');
|
|
721
|
+
}
|
|
722
|
+
} catch (e) { /* ignore */ }
|
|
723
|
+
return warnings;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// ---------------------------------------------------------------------------
|
|
727
|
+
// Main
|
|
728
|
+
// ---------------------------------------------------------------------------
|
|
729
|
+
|
|
730
|
+
var DRIVERS = { render: driveRender, upload: driveUpload, ws: driveWs };
|
|
731
|
+
|
|
732
|
+
async function main() {
|
|
733
|
+
var bad = ARMS.filter(function (a) { return !DRIVERS[a]; });
|
|
734
|
+
if (bad.length) {
|
|
735
|
+
process.stderr.write('unknown arm(s): ' + bad.join(',') + ' — valid: render,upload,ws\n');
|
|
736
|
+
process.exit(2);
|
|
737
|
+
}
|
|
738
|
+
fs.mkdirSync(OUT, { recursive: true });
|
|
739
|
+
log('output dir: ' + OUT);
|
|
740
|
+
|
|
741
|
+
var report = { stamp: STAMP, node: process.version, arms: {} };
|
|
742
|
+
var failures = 0;
|
|
743
|
+
|
|
744
|
+
try {
|
|
745
|
+
scaffold();
|
|
746
|
+
fixture();
|
|
747
|
+
build();
|
|
748
|
+
var port = resolvePort();
|
|
749
|
+
log('prod h2 port: ' + port);
|
|
750
|
+
|
|
751
|
+
for (var i = 0; i < ARMS.length; i++) {
|
|
752
|
+
var arm = ARMS[i];
|
|
753
|
+
log('── arm: ' + arm);
|
|
754
|
+
var handle = null;
|
|
755
|
+
try {
|
|
756
|
+
var stats, profile;
|
|
757
|
+
if (arm === 'ws') {
|
|
758
|
+
var wsRun = await runWsArm(); // standalone codec server, no bundle boot
|
|
759
|
+
stats = wsRun.stats;
|
|
760
|
+
profile = wsRun.profile;
|
|
761
|
+
} else {
|
|
762
|
+
handle = await bootArm(arm, port);
|
|
763
|
+
await warmup(port);
|
|
764
|
+
stats = await DRIVERS[arm](port);
|
|
765
|
+
profile = await stopArm(arm, handle);
|
|
766
|
+
handle = null;
|
|
767
|
+
}
|
|
768
|
+
var analysis = analyzer.analyze(JSON.parse(fs.readFileSync(profile, 'utf8')));
|
|
769
|
+
var label = (arm === 'ws') ? 'ws (codec-isolated standalone server)' : arm + ' (bundle child)';
|
|
770
|
+
report.arms[arm] = {
|
|
771
|
+
driver : stats,
|
|
772
|
+
mode : (arm === 'ws') ? 'codec-isolated standalone' : 'bundle child (prod, h2/https)',
|
|
773
|
+
profile : path.relative(GINA_ROOT, profile),
|
|
774
|
+
totalUs : analysis.totalUs,
|
|
775
|
+
buckets : analysis.buckets,
|
|
776
|
+
top : analysis.frames.slice(0, 20)
|
|
777
|
+
};
|
|
778
|
+
log(analyzer.format(label, analysis));
|
|
779
|
+
log('[' + arm + '] driver: ' + JSON.stringify(stats));
|
|
780
|
+
} catch (e) {
|
|
781
|
+
failures++;
|
|
782
|
+
report.arms[arm] = { error: String(e && e.message || e) };
|
|
783
|
+
log('[' + arm + '] FAILED: ' + (e && e.message || e));
|
|
784
|
+
if (handle && handle.proc) {
|
|
785
|
+
try { handle.proc.kill('SIGKILL'); } catch (k) { /* ignore */ }
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
} catch (e) {
|
|
790
|
+
failures++;
|
|
791
|
+
log('SETUP FAILED: ' + (e && e.stack || e));
|
|
792
|
+
} finally {
|
|
793
|
+
var warnings = teardown();
|
|
794
|
+
report.teardownWarnings = warnings;
|
|
795
|
+
warnings.forEach(function (w) { log('teardown: ' + w); });
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
fs.writeFileSync(path.join(OUT, 'report.json'), JSON.stringify(report, null, 2));
|
|
799
|
+
var lines = ['# perf-baseline ' + STAMP + ' — node ' + process.version, ''];
|
|
800
|
+
Object.keys(report.arms).forEach(function (arm) {
|
|
801
|
+
var a = report.arms[arm];
|
|
802
|
+
if (a.error) { lines.push('## ' + arm + ': FAILED — ' + a.error, ''); return; }
|
|
803
|
+
lines.push('## ' + arm, 'driver: ' + JSON.stringify(a.driver), '');
|
|
804
|
+
lines.push(analyzer.format(arm, { totalUs: a.totalUs, buckets: a.buckets, frames: a.top }), '');
|
|
805
|
+
});
|
|
806
|
+
fs.writeFileSync(path.join(OUT, 'report.txt'), lines.join('\n'));
|
|
807
|
+
log('report: ' + path.join(OUT, 'report.txt'));
|
|
808
|
+
process.exit(failures ? 1 : 0);
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
main();
|