@greenpandastudios/aug-cli 0.19.0
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/LICENSE +21 -0
- package/README.md +13 -0
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/bin/aug.mjs +3 -0
- package/docs/api/crypto.md +351 -0
- package/docs/api/io.md +207 -0
- package/docs/api/json.md +21 -0
- package/docs/api/memory.md +109 -0
- package/docs/api/time.md +54 -0
- package/docs/api/web.md +184 -0
- package/docs/assets/benchmarks/execution.svg +2978 -0
- package/docs/assets/benchmarks/http.svg +1674 -0
- package/docs/assets/benchmarks/improvements.svg +2315 -0
- package/docs/assets/benchmarks/memory.svg +1891 -0
- package/docs/benchmark-baseline.json +1087 -0
- package/docs/benchmark-results.json +91123 -0
- package/docs/benchmarks.json +38 -0
- package/docs/compatibility.md +42 -0
- package/docs/concurrency-implementation.md +18 -0
- package/docs/diagnostics.md +97 -0
- package/docs/docker.md +35 -0
- package/docs/example-projects.json +26 -0
- package/docs/examples/approved-design/counters.md +253 -0
- package/docs/examples/approved-design/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/approved-design/domain/app.md +165 -0
- package/docs/examples/approved-design/domain/export.md +83 -0
- package/docs/examples/approved-design/domain/models.md +80 -0
- package/docs/examples/approved-design/domain/numbers.md +248 -0
- package/docs/examples/approved-design/index.md +39 -0
- package/docs/examples/approved-design/main-yaml.md +24 -0
- package/docs/examples/approved-design/main.md +215 -0
- package/docs/examples/benchmark/index.md +33 -0
- package/docs/examples/benchmark/main-yaml.md +17 -0
- package/docs/examples/benchmark/main.md +117 -0
- package/docs/examples/cli-args/index.md +32 -0
- package/docs/examples/cli-args/main.md +107 -0
- package/docs/examples/collections/index.md +32 -0
- package/docs/examples/collections/main.md +118 -0
- package/docs/examples/collections-benchmark/index.md +34 -0
- package/docs/examples/collections-benchmark/main.md +115 -0
- package/docs/examples/cpu-benchmark/index.md +34 -0
- package/docs/examples/cpu-benchmark/main.md +90 -0
- package/docs/examples/developer-workflow/calculator.md +357 -0
- package/docs/examples/developer-workflow/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/developer-workflow/index.md +37 -0
- package/docs/examples/developer-workflow/logging/console.md +124 -0
- package/docs/examples/developer-workflow/logging/export.md +70 -0
- package/docs/examples/developer-workflow/logging/logger.md +111 -0
- package/docs/examples/developer-workflow/main.md +172 -0
- package/docs/examples/drop/index.md +33 -0
- package/docs/examples/drop/main.md +85 -0
- package/docs/examples/drop/resource.md +95 -0
- package/docs/examples/errors/errors.md +85 -0
- package/docs/examples/errors/index.md +33 -0
- package/docs/examples/errors/main.md +92 -0
- package/docs/examples/ffi/index.md +33 -0
- package/docs/examples/ffi/main.md +75 -0
- package/docs/examples/ffi/native.md +93 -0
- package/docs/examples/generic-di/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/generic-di/index.md +33 -0
- package/docs/examples/generic-di/main.md +111 -0
- package/docs/examples/generic-di/types.md +180 -0
- package/docs/examples/generics/index.md +33 -0
- package/docs/examples/generics/main.md +120 -0
- package/docs/examples/generics/types.md +189 -0
- package/docs/examples/hello/app/export.md +67 -0
- package/docs/examples/hello/app/greeter.md +190 -0
- package/docs/examples/hello/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/hello/index.md +37 -0
- package/docs/examples/hello/logging/console.md +121 -0
- package/docs/examples/hello/logging/export.md +71 -0
- package/docs/examples/hello/logging/logger.md +120 -0
- package/docs/examples/hello/main.md +115 -0
- package/docs/examples/http-benchmark/index.md +35 -0
- package/docs/examples/http-benchmark/main.md +79 -0
- package/docs/examples/http-benchmark/routes.md +88 -0
- package/docs/examples/index.md +60 -0
- package/docs/examples/interceptors/app.md +250 -0
- package/docs/examples/interceptors/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/interceptors/index.md +35 -0
- package/docs/examples/interceptors/interceptors.md +284 -0
- package/docs/examples/interceptors/logging.md +155 -0
- package/docs/examples/interceptors/main.md +162 -0
- package/docs/examples/json-benchmark/data.md +71 -0
- package/docs/examples/json-benchmark/dependencies/august/0.19.0/json/contracts.md +103 -0
- package/docs/examples/json-benchmark/index.md +35 -0
- package/docs/examples/json-benchmark/main.md +131 -0
- package/docs/examples/new-syntax/console.md +118 -0
- package/docs/examples/new-syntax/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/new-syntax/greeter.md +145 -0
- package/docs/examples/new-syntax/index.md +36 -0
- package/docs/examples/new-syntax/logger.md +111 -0
- package/docs/examples/new-syntax/main.md +135 -0
- package/docs/examples/new-syntax/math.md +79 -0
- package/docs/examples/oidc-login/client/contracts.md +151 -0
- package/docs/examples/oidc-login/client/endpoints.md +263 -0
- package/docs/examples/oidc-login/client/export.md +107 -0
- package/docs/examples/oidc-login/client/login.md +515 -0
- package/docs/examples/oidc-login/client/logout.md +249 -0
- package/docs/examples/oidc-login/client/protocol.md +595 -0
- package/docs/examples/oidc-login/client/session.md +297 -0
- package/docs/examples/oidc-login/client/views.md +144 -0
- package/docs/examples/oidc-login/common/export.md +115 -0
- package/docs/examples/oidc-login/common/headers.md +162 -0
- package/docs/examples/oidc-login/common/keys.md +336 -0
- package/docs/examples/oidc-login/common/settings.md +116 -0
- package/docs/examples/oidc-login/common/views.md +103 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/contracts.md +925 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/crypto/jose.md +434 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/json/contracts.md +103 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/memory/store.md +374 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/time/contracts.md +150 -0
- package/docs/examples/oidc-login/dependencies/august/0.19.0/web/contracts.md +532 -0
- package/docs/examples/oidc-login/index.md +57 -0
- package/docs/examples/oidc-login/main-yaml.md +28 -0
- package/docs/examples/oidc-login/main.md +283 -0
- package/docs/examples/oidc-login/provider/authorization.md +457 -0
- package/docs/examples/oidc-login/provider/contracts.md +267 -0
- package/docs/examples/oidc-login/provider/credentials.md +148 -0
- package/docs/examples/oidc-login/provider/discovery.md +215 -0
- package/docs/examples/oidc-login/provider/export.md +131 -0
- package/docs/examples/oidc-login/provider/token.md +364 -0
- package/docs/examples/oidc-login/provider/userinfo.md +228 -0
- package/docs/examples/oidc-login/provider/views.md +137 -0
- package/docs/examples/ownership/counter.md +140 -0
- package/docs/examples/ownership/index.md +33 -0
- package/docs/examples/ownership/main.md +90 -0
- package/docs/examples/ownership-transfer/dependencies/august/0.19.0/io/contracts.md +395 -0
- package/docs/examples/ownership-transfer/index.md +33 -0
- package/docs/examples/ownership-transfer/main.md +125 -0
- package/docs/examples/ownership-transfer/resource.md +150 -0
- package/docs/examples/packages-app/dependencies/packages/@example/aug-math/0.1.0/arithmetic.md +117 -0
- package/docs/examples/packages-app/index.md +34 -0
- package/docs/examples/packages-app/main-yaml.md +18 -0
- package/docs/examples/packages-app/main.md +80 -0
- package/docs/examples/packages-math/aug-package-json.md +24 -0
- package/docs/examples/packages-math/index.md +36 -0
- package/docs/examples/packages-math/package-json.md +25 -0
- package/docs/examples/packages-math/src/arithmetic.md +121 -0
- package/docs/examples/packages-math/src/export.md +63 -0
- package/docs/examples/startup-benchmark/index.md +34 -0
- package/docs/examples/startup-benchmark/main.md +68 -0
- package/docs/examples/visibility/counter.md +142 -0
- package/docs/examples/visibility/index.md +33 -0
- package/docs/examples/visibility/main.md +96 -0
- package/docs/examples.json +47 -0
- package/docs/getting-started.md +5 -0
- package/docs/grammar.md +136 -0
- package/docs/implementation-map.md +106 -0
- package/docs/index.md +46 -0
- package/docs/language-conformance.md +30 -0
- package/docs/language-constructs.md +1461 -0
- package/docs/language-design-audit.md +147 -0
- package/docs/maintaining-docs.md +43 -0
- package/docs/packages.md +184 -0
- package/docs/performance.md +535 -0
- package/docs/production-readiness.md +39 -0
- package/docs/reference.md +361 -0
- package/docs/release-review.md +23 -0
- package/docs/releasing.md +79 -0
- package/docs/roadmap.md +13 -0
- package/docs/specifications.md +86 -0
- package/docs/testing.md +120 -0
- package/docs/tooling.md +197 -0
- package/docs/web-implementation-plan.md +39 -0
- package/docs/web-library-gaps.md +27 -0
- package/docs/web.md +197 -0
- package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/approved-design/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/approved-design/.aug-spec/manifest.json +14 -0
- package/examples/approved-design/counters.aug +22 -0
- package/examples/approved-design/counters.aug.md +177 -0
- package/examples/approved-design/domain/app.aug +12 -0
- package/examples/approved-design/domain/app.aug.md +97 -0
- package/examples/approved-design/domain/export.aug +5 -0
- package/examples/approved-design/domain/export.aug.md +25 -0
- package/examples/approved-design/domain/models.aug +2 -0
- package/examples/approved-design/domain/models.aug.md +30 -0
- package/examples/approved-design/domain/numbers.aug +29 -0
- package/examples/approved-design/domain/numbers.aug.md +141 -0
- package/examples/approved-design/main.aug +26 -0
- package/examples/approved-design/main.aug.md +108 -0
- package/examples/approved-design/main.yaml +8 -0
- package/examples/benchmark/.aug-spec/manifest.json +7 -0
- package/examples/benchmark/main.aug +17 -0
- package/examples/benchmark/main.aug.md +43 -0
- package/examples/benchmark/main.yaml +1 -0
- package/examples/cli-args/.aug-spec/manifest.json +7 -0
- package/examples/cli-args/main.aug +15 -0
- package/examples/cli-args/main.aug.md +38 -0
- package/examples/collections/.aug-spec/manifest.json +7 -0
- package/examples/collections/main.aug +18 -0
- package/examples/collections/main.aug.md +43 -0
- package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/developer-workflow/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/developer-workflow/.aug-spec/manifest.json +13 -0
- package/examples/developer-workflow/calculator.aug +55 -0
- package/examples/developer-workflow/calculator.aug.md +228 -0
- package/examples/developer-workflow/logging/console.aug +8 -0
- package/examples/developer-workflow/logging/console.aug.md +67 -0
- package/examples/developer-workflow/logging/export.aug +2 -0
- package/examples/developer-workflow/logging/export.aug.md +19 -0
- package/examples/developer-workflow/logging/logger.aug +6 -0
- package/examples/developer-workflow/logging/logger.aug.md +57 -0
- package/examples/developer-workflow/main.aug +25 -0
- package/examples/developer-workflow/main.aug.md +79 -0
- package/examples/drop/.aug-spec/manifest.json +8 -0
- package/examples/drop/main.aug +3 -0
- package/examples/drop/main.aug.md +35 -0
- package/examples/drop/resource.aug +8 -0
- package/examples/drop/resource.aug.md +44 -0
- package/examples/errors/.aug-spec/manifest.json +8 -0
- package/examples/errors/errors.aug +6 -0
- package/examples/errors/errors.aug.md +33 -0
- package/examples/errors/main.aug +7 -0
- package/examples/errors/main.aug.md +36 -0
- package/examples/ffi/.aug-spec/manifest.json +8 -0
- package/examples/ffi/main.aug +2 -0
- package/examples/ffi/main.aug.md +27 -0
- package/examples/ffi/native.aug +6 -0
- package/examples/ffi/native.aug.md +43 -0
- package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/generic-di/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/generic-di/.aug-spec/manifest.json +10 -0
- package/examples/generic-di/main.aug +9 -0
- package/examples/generic-di/main.aug.md +49 -0
- package/examples/generic-di/types.aug +17 -0
- package/examples/generic-di/types.aug.md +124 -0
- package/examples/generics/.aug-spec/manifest.json +8 -0
- package/examples/generics/main.aug +9 -0
- package/examples/generics/main.aug.md +58 -0
- package/examples/generics/types.aug +19 -0
- package/examples/generics/types.aug.md +132 -0
- package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/hello/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/hello/.aug-spec/manifest.json +14 -0
- package/examples/hello/app/export.aug +1 -0
- package/examples/hello/app/export.aug.md +17 -0
- package/examples/hello/app/greeter.aug +22 -0
- package/examples/hello/app/greeter.aug.md +109 -0
- package/examples/hello/logging/console.aug +7 -0
- package/examples/hello/logging/console.aug.md +65 -0
- package/examples/hello/logging/export.aug +2 -0
- package/examples/hello/logging/export.aug.md +19 -0
- package/examples/hello/logging/logger.aug +9 -0
- package/examples/hello/logging/logger.aug.md +59 -0
- package/examples/hello/main.aug +9 -0
- package/examples/hello/main.aug.md +49 -0
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/interceptors/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/interceptors/.aug-spec/manifest.json +12 -0
- package/examples/interceptors/app.aug +28 -0
- package/examples/interceptors/app.aug.md +162 -0
- package/examples/interceptors/interceptors.aug +40 -0
- package/examples/interceptors/interceptors.aug.md +180 -0
- package/examples/interceptors/logging.aug +12 -0
- package/examples/interceptors/logging.aug.md +96 -0
- package/examples/interceptors/main.aug +22 -0
- package/examples/interceptors/main.aug.md +76 -0
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/new-syntax/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/new-syntax/.aug-spec/manifest.json +13 -0
- package/examples/new-syntax/console.aug +7 -0
- package/examples/new-syntax/console.aug.md +63 -0
- package/examples/new-syntax/greeter.aug +10 -0
- package/examples/new-syntax/greeter.aug.md +89 -0
- package/examples/new-syntax/logger.aug +6 -0
- package/examples/new-syntax/logger.aug.md +57 -0
- package/examples/new-syntax/main.aug +12 -0
- package/examples/new-syntax/main.aug.md +64 -0
- package/examples/new-syntax/math.aug +3 -0
- package/examples/new-syntax/math.aug.md +29 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug +73 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/contracts.aug.md +791 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug +68 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/crypto/jose.aug.md +266 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug +6 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/json/contracts.aug.md +55 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug +45 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/memory/store.aug.md +250 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug +11 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/time/contracts.aug.md +96 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug +58 -0
- package/examples/oidc-login/.aug-spec/august/0.19.0/web/contracts.aug.md +420 -0
- package/examples/oidc-login/.aug-spec/manifest.json +40 -0
- package/examples/oidc-login/README.md +29 -0
- package/examples/oidc-login/client/contracts.aug +7 -0
- package/examples/oidc-login/client/contracts.aug.md +80 -0
- package/examples/oidc-login/client/endpoints.aug +21 -0
- package/examples/oidc-login/client/endpoints.aug.md +161 -0
- package/examples/oidc-login/client/export.aug +7 -0
- package/examples/oidc-login/client/export.aug.md +29 -0
- package/examples/oidc-login/client/login.aug +58 -0
- package/examples/oidc-login/client/login.aug.md +331 -0
- package/examples/oidc-login/client/logout.aug +18 -0
- package/examples/oidc-login/client/logout.aug.md +150 -0
- package/examples/oidc-login/client/protocol.aug +106 -0
- package/examples/oidc-login/client/protocol.aug.md +326 -0
- package/examples/oidc-login/client/session.aug +34 -0
- package/examples/oidc-login/client/session.aug.md +155 -0
- package/examples/oidc-login/client/views.aug +21 -0
- package/examples/oidc-login/client/views.aug.md +68 -0
- package/examples/oidc-login/common/export.aug +9 -0
- package/examples/oidc-login/common/export.aug.md +33 -0
- package/examples/oidc-login/common/headers.aug +11 -0
- package/examples/oidc-login/common/headers.aug.md +79 -0
- package/examples/oidc-login/common/keys.aug +37 -0
- package/examples/oidc-login/common/keys.aug.md +207 -0
- package/examples/oidc-login/common/settings.aug +4 -0
- package/examples/oidc-login/common/settings.aug.md +47 -0
- package/examples/oidc-login/common/views.aug +16 -0
- package/examples/oidc-login/common/views.aug.md +34 -0
- package/examples/oidc-login/main.aug +39 -0
- package/examples/oidc-login/main.aug.md +166 -0
- package/examples/oidc-login/main.yaml +12 -0
- package/examples/oidc-login/provider/authorization.aug +59 -0
- package/examples/oidc-login/provider/authorization.aug.md +264 -0
- package/examples/oidc-login/provider/contracts.aug +15 -0
- package/examples/oidc-login/provider/contracts.aug.md +193 -0
- package/examples/oidc-login/provider/credentials.aug +10 -0
- package/examples/oidc-login/provider/credentials.aug.md +64 -0
- package/examples/oidc-login/provider/discovery.aug +13 -0
- package/examples/oidc-login/provider/discovery.aug.md +133 -0
- package/examples/oidc-login/provider/export.aug +13 -0
- package/examples/oidc-login/provider/export.aug.md +41 -0
- package/examples/oidc-login/provider/token.aug +37 -0
- package/examples/oidc-login/provider/token.aug.md +223 -0
- package/examples/oidc-login/provider/userinfo.aug +26 -0
- package/examples/oidc-login/provider/userinfo.aug.md +104 -0
- package/examples/oidc-login/provider/views.aug +18 -0
- package/examples/oidc-login/provider/views.aug.md +63 -0
- package/examples/ownership/.aug-spec/manifest.json +8 -0
- package/examples/ownership/counter.aug +14 -0
- package/examples/ownership/counter.aug.md +85 -0
- package/examples/ownership/main.aug +4 -0
- package/examples/ownership/main.aug.md +38 -0
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug +36 -0
- package/examples/ownership-transfer/.aug-spec/august/0.19.0/io/contracts.aug.md +316 -0
- package/examples/ownership-transfer/.aug-spec/manifest.json +10 -0
- package/examples/ownership-transfer/main.aug +9 -0
- package/examples/ownership-transfer/main.aug.md +63 -0
- package/examples/ownership-transfer/resource.aug +16 -0
- package/examples/ownership-transfer/resource.aug.md +89 -0
- package/examples/packages/README.md +15 -0
- package/examples/packages/app/.aug-spec/manifest.json +9 -0
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug +9 -0
- package/examples/packages/app/.aug-spec/packages/@example/aug-math/0.1.0/arithmetic.aug.md +63 -0
- package/examples/packages/app/main.aug +2 -0
- package/examples/packages/app/main.aug.md +33 -0
- package/examples/packages/app/main.yaml +2 -0
- package/examples/packages/math/.aug-spec/manifest.json +8 -0
- package/examples/packages/math/README.md +3 -0
- package/examples/packages/math/aug-package.json +8 -0
- package/examples/packages/math/package.json +9 -0
- package/examples/packages/math/src/arithmetic.aug +8 -0
- package/examples/packages/math/src/arithmetic.aug.md +63 -0
- package/examples/packages/math/src/export.aug +1 -0
- package/examples/packages/math/src/export.aug.md +17 -0
- package/examples/visibility/.aug-spec/manifest.json +8 -0
- package/examples/visibility/counter.aug +14 -0
- package/examples/visibility/counter.aug.md +87 -0
- package/examples/visibility/main.aug +7 -0
- package/examples/visibility/main.aug.md +39 -0
- package/package.json +50 -0
- package/runtime/aug_crypto.c +121 -0
- package/runtime/aug_html.c +93 -0
- package/runtime/aug_http.c +829 -0
- package/runtime/aug_json.c +165 -0
- package/runtime/aug_runtime.c +792 -0
- package/runtime/aug_runtime.h +245 -0
- package/runtime/aug_tasks.c +172 -0
- package/runtime/aug_time.c +5 -0
- package/runtime/aug_values.c +80 -0
- package/scripts/bootstrap-native.mjs +121 -0
- package/scripts/native-dependencies.lock.json +65 -0
- package/scripts/native-home.mjs +11 -0
- package/src/actions.js +109 -0
- package/src/ast.js +19 -0
- package/src/builtins.js +93 -0
- package/src/checker.js +2896 -0
- package/src/cli.js +344 -0
- package/src/codegen.js +1159 -0
- package/src/config.js +149 -0
- package/src/continuation.js +110 -0
- package/src/di.js +24 -0
- package/src/documentation.js +27 -0
- package/src/editor.js +782 -0
- package/src/effects.js +29 -0
- package/src/fixes.js +222 -0
- package/src/formatter.js +296 -0
- package/src/freshness.js +154 -0
- package/src/help.js +212 -0
- package/src/html.js +27 -0
- package/src/http-policies.js +90 -0
- package/src/inference.js +16 -0
- package/src/interceptors.js +70 -0
- package/src/javadoc.js +67 -0
- package/src/lexer.js +199 -0
- package/src/libraries.js +31 -0
- package/src/lsp.js +180 -0
- package/src/native.js +144 -0
- package/src/navigation.js +162 -0
- package/src/openapi.js +220 -0
- package/src/ownership.js +232 -0
- package/src/package-manager.js +299 -0
- package/src/parser.js +1155 -0
- package/src/policies.js +130 -0
- package/src/project-init.js +19 -0
- package/src/project.js +292 -0
- package/src/schemas.js +62 -0
- package/src/semantic.js +255 -0
- package/src/spec.js +738 -0
- package/src/testing.js +186 -0
- package/src/types.js +10 -0
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
# Performance and benchmarks
|
|
2
|
+
|
|
3
|
+
Use this page to measure an August application, read the comparison graphs, and inspect the exact August programs behind each result. The recorded results used August 0.18.0, which compiles to native code through C. The current compiler is 0.19.0; rerun the suite before comparing a new release. Always measure work that resembles your application.
|
|
4
|
+
|
|
5
|
+
## Read the graphs
|
|
6
|
+
|
|
7
|
+
Execution and memory bars use **lower is better**. HTTP throughput uses **higher is better**. Read the workload name and units before comparing: a 20,000-entry map and a two-million-step CPU loop do different amounts of work. The execution panels have separate linear scales; compare implementations within a panel. Tables provide exact values and remain readable on a phone.
|
|
8
|
+
|
|
9
|
+
All results below were recorded on September 29, 2026: Apple M5, macOS Darwin 25.6.0, ARM64, Apple Clang 21, Node 24.18.0, CPython 3.12.14. August and C use `-O2` without LTO. [Raw samples, checksums, build timings and environment](benchmark-results.json) are committed with this page.
|
|
10
|
+
|
|
11
|
+
## Execution time
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
[benchmark-execution-start]: #
|
|
16
|
+
|
|
17
|
+
| Workload | August | C | Node | Python |
|
|
18
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
19
|
+
| Startup | 1.46 ms | 1.29 ms | 19.07 ms | 8.42 ms |
|
|
20
|
+
| CPU · 2 million iterations | 7.24 ms | 8.17 ms | 30.22 ms | 194.98 ms |
|
|
21
|
+
| Map + Set · 20,000 entries | 2.54 ms | 1.65 ms | 22.31 ms | 10.36 ms |
|
|
22
|
+
| Map + Set · 200,000 entries | 15.10 ms | 6.38 ms | 38.33 ms | 26.44 ms |
|
|
23
|
+
| JSON · 5,000 round trips | 6.92 ms | 2.01 ms | 20.84 ms | 19.20 ms |
|
|
24
|
+
|
|
25
|
+
[benchmark-execution-end]: #
|
|
26
|
+
|
|
27
|
+
Times include a fresh process's startup and exclude compilation: 3 warmups and 15 measured runs for each implementation, with the execution order rotated. Every run must produce the expected checksum. Node and Python start a new interpreter each time; these are batch timings, not warmed server-loop or steady-state JIT timings. The startup row helps make that cost visible; subtracting medians would not establish a new measured result.
|
|
28
|
+
|
|
29
|
+
The programs below are the actual benchmark sources. The suite checks their printed results against the C, Node and Python references on every run.
|
|
30
|
+
|
|
31
|
+
The C reference is tailored to these inputs: it preallocates integer tables and checks JSON field types. August uses its normal Map, Set and typed JSON APIs. The programs produce the same checked results, but perform different amounts of validation and memory management. Read the complete sources below when comparing them.
|
|
32
|
+
|
|
33
|
+
[benchmark-summary-start]: #
|
|
34
|
+
|
|
35
|
+
The CPU program takes **7.24 ms** in August and **8.17 ms** in C on this host. The large-collection program takes **15.10 ms** in August. These are measurements of the shown programs, not guarantees for other applications. JSON batch time includes interpreter startup for Node and Python; it does not establish a universal JSON-throughput advantage.
|
|
36
|
+
|
|
37
|
+
[benchmark-summary-end]: #
|
|
38
|
+
|
|
39
|
+
### Startup program
|
|
40
|
+
|
|
41
|
+
Save this as `main.aug`. Its result is `7`; the measurement includes starting and stopping the executable.
|
|
42
|
+
|
|
43
|
+
[benchmark-source-startup-start]: #
|
|
44
|
+
|
|
45
|
+
**main.aug**
|
|
46
|
+
|
|
47
|
+
```aug project=benchmark-startup file=main.aug
|
|
48
|
+
print(value=7)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
[benchmark-source-startup-end]: #
|
|
53
|
+
|
|
54
|
+
### CPU program
|
|
55
|
+
|
|
56
|
+
This loop performs two million dependent integer steps. Its result must be `819677333`. Change the iteration count to measure a different workload; keep it the same across comparisons.
|
|
57
|
+
|
|
58
|
+
[benchmark-source-cpu-start]: #
|
|
59
|
+
|
|
60
|
+
**main.aug**
|
|
61
|
+
|
|
62
|
+
```aug project=benchmark-cpu file=main.aug
|
|
63
|
+
// A loop-carried dependency prevents removal of the computation.
|
|
64
|
+
int state = 123
|
|
65
|
+
int index = 0
|
|
66
|
+
while index < 2000000:
|
|
67
|
+
int product = state * 48271
|
|
68
|
+
state = product - (product / 2147483647) * 2147483647
|
|
69
|
+
index = index + 1
|
|
70
|
+
print(value=state)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
[benchmark-source-cpu-end]: #
|
|
75
|
+
|
|
76
|
+
### Map and Set program
|
|
77
|
+
|
|
78
|
+
This creates a Map and Set, inserts 20,000 values, checks membership, and sums values while iterating. Its results are `599970000` and `true`. The larger graph uses the same program with `20000` changed to `200000`, producing `59999700000` and `true`.
|
|
79
|
+
|
|
80
|
+
[benchmark-source-collections-start]: #
|
|
81
|
+
|
|
82
|
+
**main.aug**
|
|
83
|
+
|
|
84
|
+
```aug project=benchmark-collections file=main.aug
|
|
85
|
+
own Map<int, int> values = {}
|
|
86
|
+
own Set<int> unique = {}
|
|
87
|
+
int index = 0
|
|
88
|
+
while index < 20000:
|
|
89
|
+
values.set(key=index, value=index * 3)
|
|
90
|
+
unique.add(value=index)
|
|
91
|
+
index = index + 1
|
|
92
|
+
int checksum = 0
|
|
93
|
+
for (key, value) in values:
|
|
94
|
+
if unique.contains(value=key):
|
|
95
|
+
checksum = checksum + value
|
|
96
|
+
print(value=checksum)
|
|
97
|
+
print(value=values.length() == unique.length())
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
[benchmark-source-collections-end]: #
|
|
102
|
+
|
|
103
|
+
### JSON program
|
|
104
|
+
|
|
105
|
+
These two files belong in one folder. The program parses JSON, reads a typed record, writes JSON, and checks the result 5,000 times. Its result is `250000`.
|
|
106
|
+
|
|
107
|
+
[benchmark-source-json-start]: #
|
|
108
|
+
|
|
109
|
+
**data.aug**
|
|
110
|
+
|
|
111
|
+
```aug project=benchmark-json file=data.aug
|
|
112
|
+
record Payload(int id, string message, List<int> values)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**main.aug**
|
|
116
|
+
|
|
117
|
+
```aug project=benchmark-json file=main.aug
|
|
118
|
+
import parse from august.json
|
|
119
|
+
import Payload from data
|
|
120
|
+
int checksum = 0
|
|
121
|
+
int index = 0
|
|
122
|
+
try:
|
|
123
|
+
while index < 5000:
|
|
124
|
+
document = parse(input="{\"id\":7,\"message\":\"hello\",\"values\":[1,2,3]}")
|
|
125
|
+
payload = document.decode<Payload>()
|
|
126
|
+
encoded = Json(value=payload).stringify()
|
|
127
|
+
checksum = checksum + payload.id + encoded.length()
|
|
128
|
+
index = index + 1
|
|
129
|
+
print(value=checksum)
|
|
130
|
+
catch JsonError error:
|
|
131
|
+
exit(status=1)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
[benchmark-source-json-end]: #
|
|
136
|
+
|
|
137
|
+
## HTTP throughput
|
|
138
|
+
|
|
139
|
+

|
|
140
|
+
|
|
141
|
+
[benchmark-http-start]: #
|
|
142
|
+
|
|
143
|
+
| Clients | August req/sec | Node req/sec | August p95 latency | Node p95 latency |
|
|
144
|
+
| ---: | ---: | ---: | ---: | ---: |
|
|
145
|
+
| 1 | 23,526 | 25,580 | 0.05 ms | 0.04 ms |
|
|
146
|
+
| 16 | 73,370 | 69,166 | 0.37 ms | 0.40 ms |
|
|
147
|
+
| 64 | 65,365 | 69,260 | 1.74 ms | 1.32 ms |
|
|
148
|
+
|
|
149
|
+
[benchmark-http-end]: #
|
|
150
|
+
|
|
151
|
+
A real August `GET /bench` endpoint returns a newly constructed typed JSON record. The Node reference constructs and serializes the same response. Both run on loopback with HTTP/1.1 keep-alive, 1,000 warmup requests and three fresh-server rounds of 5,000 measured requests per concurrency level. Every response must have status 200, JSON content type, and the exact expected data. The measured runs had zero errors. p95 is the median of the three per-round p95 latencies; graph error bars show observed throughput min/max, not confidence intervals.
|
|
152
|
+
|
|
153
|
+
The Node load generator runs on the same machine and consumes CPU. This closed-loop test has no TLS, authentication, logging, database, outbound network calls or slow clients. Its numbers are endpoint microbenchmark throughput, not a supported production capacity or service-level guarantee. HTTP/2, HTTP/3 and streaming are not benchmarked here.
|
|
154
|
+
|
|
155
|
+
Use the table to compare throughput and latency at the concurrency you expect. These results measure one process on one OS thread; they do not establish multicore scaling.
|
|
156
|
+
|
|
157
|
+
### HTTP program
|
|
158
|
+
|
|
159
|
+
Place these files in one folder. Every request constructs a `Reply` and returns it as JSON. Port `0` selects a free port; the server prints the chosen port when it starts.
|
|
160
|
+
|
|
161
|
+
[benchmark-source-http-start]: #
|
|
162
|
+
|
|
163
|
+
**routes.aug**
|
|
164
|
+
|
|
165
|
+
```aug project=benchmark-http file=routes.aug
|
|
166
|
+
record Reply(int id, string message)
|
|
167
|
+
endpoint GET "/bench" as reply() returns Reply:
|
|
168
|
+
return Reply(id=7, message="hello")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**main.aug**
|
|
172
|
+
|
|
173
|
+
```aug project=benchmark-http file=main.aug
|
|
174
|
+
import reply from routes
|
|
175
|
+
serve reply on port 0
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
[benchmark-source-http-end]: #
|
|
180
|
+
|
|
181
|
+
Start the app in one terminal:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
aug run path/to/http-example
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Save the load generator below as `http-load.mjs`, or use `scripts/http-load.mjs` from a repository checkout. In another terminal, replace `PORT` with the printed port. This is the **same load generator** the comparison suite uses:
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
node http-load.mjs --url http://127.0.0.1:PORT/bench \
|
|
191
|
+
--concurrency 64 --requests 5000 --warmup 1000 --rounds 3
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The output includes requests/sec, p95 latency and validated request counts. An incorrect status, content type, JSON result, or timeout fails the run. The default expected result is `{"id":7,"message":"hello"}`. For your own JSON endpoint, pass `--expected '{"your":"result"}'`. This tool measures HTTP/1.1 without TLS. Its CLI rounds reuse your running server; the comparison suite starts a fresh server for each round.
|
|
195
|
+
|
|
196
|
+
The measurement uses a fixed number of keep-alive clients. Each client waits for its response before sending another request. Inspect the complete code below when reproducing a result.
|
|
197
|
+
|
|
198
|
+
::: details HTTP load generator source
|
|
199
|
+
|
|
200
|
+
[benchmark-source-load-start]: #
|
|
201
|
+
|
|
202
|
+
```js
|
|
203
|
+
#!/usr/bin/env node
|
|
204
|
+
import assert from 'node:assert/strict';
|
|
205
|
+
import http from 'node:http';
|
|
206
|
+
import {resolve} from 'node:path';
|
|
207
|
+
import {fileURLToPath} from 'node:url';
|
|
208
|
+
|
|
209
|
+
export const statistics = samples => {
|
|
210
|
+
const sorted = [...samples].sort((a, b) => a - b), middle = Math.floor(sorted.length / 2);
|
|
211
|
+
return {samples, minimum:sorted[0], median:sorted.length % 2 ? sorted[middle] : (sorted[middle - 1] + sorted[middle]) / 2,
|
|
212
|
+
p95:sorted[Math.ceil(sorted.length * .95) - 1]};
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
/** Closed-loop HTTP/1.1 load with a fixed number of keep-alive clients.
|
|
216
|
+
* Every response is checked; failed requests fail the measurement.
|
|
217
|
+
*/
|
|
218
|
+
export async function httpLoad(target, concurrency, count, expected = {id:7, message:'hello'}) {
|
|
219
|
+
assert.ok(Number.isInteger(concurrency) && concurrency > 0);
|
|
220
|
+
assert.ok(Number.isInteger(count) && count > 0);
|
|
221
|
+
const url = new URL(typeof target === 'number' ? `http://127.0.0.1:${target}/bench` : target);
|
|
222
|
+
assert.equal(url.protocol, 'http:', 'This benchmark measures HTTP/1.1 without TLS');
|
|
223
|
+
const agent = new http.Agent({keepAlive:true, maxSockets:concurrency}), latencies = [];
|
|
224
|
+
let next = 0;
|
|
225
|
+
const started = performance.now();
|
|
226
|
+
try {
|
|
227
|
+
await Promise.all(Array.from({length:concurrency}, async () => {
|
|
228
|
+
while (next++ < count) {
|
|
229
|
+
const begin = performance.now();
|
|
230
|
+
await new Promise((resolve, reject) => {
|
|
231
|
+
const req = http.get(url, {agent}, response => {
|
|
232
|
+
let body = ''; response.on('data', chunk => {body += chunk;});
|
|
233
|
+
response.on('error', reject); response.on('end', () => {
|
|
234
|
+
try {
|
|
235
|
+
assert.equal(response.statusCode, 200);
|
|
236
|
+
assert.match(response.headers['content-type'], /application\/json/);
|
|
237
|
+
assert.deepEqual(JSON.parse(body), expected);
|
|
238
|
+
latencies.push(performance.now() - begin); resolve();
|
|
239
|
+
} catch (error) { reject(error); }
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
req.setTimeout(10000, () => req.destroy(new Error('HTTP request timed out'))); req.on('error', reject);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}));
|
|
246
|
+
assert.equal(latencies.length, count);
|
|
247
|
+
const elapsedMs = performance.now() - started;
|
|
248
|
+
return {requests:count, errors:0, elapsedMs, requestsPerSecond:count * 1000 / elapsedMs, latencyMs:statistics(latencies)};
|
|
249
|
+
} finally { agent.destroy(); }
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
|
|
253
|
+
const option = (name, fallback) => {
|
|
254
|
+
const index = process.argv.indexOf('--' + name);
|
|
255
|
+
return index < 0 ? fallback : process.argv[index + 1];
|
|
256
|
+
};
|
|
257
|
+
try {
|
|
258
|
+
const url = option('url');
|
|
259
|
+
assert.ok(url, 'Use --url http://127.0.0.1:PORT/bench [--concurrency 64 --requests 5000 --warmup 1000 --rounds 3]');
|
|
260
|
+
const concurrency = Number(option('concurrency', 16)), requests = Number(option('requests', 5000));
|
|
261
|
+
const warmup = Number(option('warmup', 1000)), rounds = Number(option('rounds', 3));
|
|
262
|
+
assert.ok(Number.isInteger(rounds) && rounds > 0);
|
|
263
|
+
const expected = JSON.parse(option('expected', '{"id":7,"message":"hello"}'));
|
|
264
|
+
const results = [];
|
|
265
|
+
for (let i = 0; i < rounds; i++) {
|
|
266
|
+
await httpLoad(url, concurrency, warmup, expected);
|
|
267
|
+
const result = await httpLoad(url, concurrency, requests, expected);
|
|
268
|
+
delete result.latencyMs.samples; results.push(result);
|
|
269
|
+
}
|
|
270
|
+
const measured = statistics(results.map(result => result.requestsPerSecond));
|
|
271
|
+
console.log(JSON.stringify({url, concurrency, warmup, rounds:results, requestsPerSecond:measured}, null, 2));
|
|
272
|
+
} catch (error) { console.error(error.message); process.exitCode = 1; }
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
[benchmark-source-load-end]: #
|
|
277
|
+
|
|
278
|
+
:::
|
|
279
|
+
|
|
280
|
+
## Memory
|
|
281
|
+
|
|
282
|
+

|
|
283
|
+
|
|
284
|
+
[benchmark-memory-start]: #
|
|
285
|
+
|
|
286
|
+
| Workload | August | C | Node | Python |
|
|
287
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
288
|
+
| Startup | 1.3 MiB | 1.4 MiB | 46.0 MiB | 15.1 MiB |
|
|
289
|
+
| CPU · 2 million iterations | 1.3 MiB | 1.4 MiB | 52.2 MiB | 15.1 MiB |
|
|
290
|
+
| Map + Set · 20,000 entries | 4.5 MiB | 4.4 MiB | 57.0 MiB | 20.2 MiB |
|
|
291
|
+
| Map + Set · 200,000 entries | 34.2 MiB | 25.4 MiB | 91.1 MiB | 62.1 MiB |
|
|
292
|
+
| JSON · 5,000 round trips | 1.8 MiB | 1.5 MiB | 47.4 MiB | 16.2 MiB |
|
|
293
|
+
|
|
294
|
+
[benchmark-memory-end]: #
|
|
295
|
+
|
|
296
|
+
These are medians of three separate peak-RSS measurements through `/usr/bin/time`, in MiB, including the process runtime/interpreter. They are not allocation counts or retained heap after a GC. Long-running heap stability and leak behavior need separate soak tests.
|
|
297
|
+
|
|
298
|
+
## Before and after
|
|
299
|
+
|
|
300
|
+
The same August programs and measurement settings were run on this machine before and after the performance work. Shorter bars are faster for execution time; taller points are faster for HTTP. This compares observed application performance. [Earlier measurement summaries](benchmark-baseline.json) preserve the baseline.
|
|
301
|
+
|
|
302
|
+

|
|
303
|
+
|
|
304
|
+
[benchmark-improvements-start]: #
|
|
305
|
+
|
|
306
|
+
| August workload | Before | Current | Current relative to before |
|
|
307
|
+
| --- | ---: | ---: | ---: |
|
|
308
|
+
| CPU · 2 million iterations | 36.65 ms | 7.24 ms | 5.06× faster |
|
|
309
|
+
| Map + Set · 20,000 entries | 4.68 ms | 2.54 ms | 1.84× faster |
|
|
310
|
+
| Map + Set · 200,000 entries | 47.90 ms | 15.10 ms | 3.17× faster |
|
|
311
|
+
| HTTP · 1 clients | 25,273 req/sec | 23,526 req/sec | 0.93× throughput |
|
|
312
|
+
| HTTP · 16 clients | 62,719 req/sec | 73,370 req/sec | 1.17× throughput |
|
|
313
|
+
| HTTP · 64 clients | 30,693 req/sec | 65,365 req/sec | 2.13× throughput |
|
|
314
|
+
| Map + Set · 200k peak memory | 61.9 MiB | 34.2 MiB | 45% less |
|
|
315
|
+
|
|
316
|
+
[benchmark-improvements-end]: #
|
|
317
|
+
|
|
318
|
+
## Benchmark your own project
|
|
319
|
+
|
|
320
|
+
1. Choose a representative finite workload in `main.aug`. Give it a deterministic result so you can check correctness.
|
|
321
|
+
2. Run it once and verify the output. Keep input size, dependencies, native compiler, machine and background load recorded.
|
|
322
|
+
3. Measure a release executable repeatedly. Compilation is excluded; process startup is included.
|
|
323
|
+
|
|
324
|
+
```sh
|
|
325
|
+
aug check path/to/project
|
|
326
|
+
aug run path/to/project
|
|
327
|
+
aug bench path/to/project --iterations 20 --warmup 3 --json > benchmark.json
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`aug bench` compiles with release optimization even when the project's normal setting is debug. Do not benchmark `aug run`: that command includes compiler work. Server programs run indefinitely, so use an HTTP load generator against a built server instead of `aug bench`. Record errors and latency as well as throughput. The comparison suite validates checksums; `aug bench` itself checks exit status, so verify your program's result first.
|
|
331
|
+
|
|
332
|
+
## Reproduce the comparison graphs
|
|
333
|
+
|
|
334
|
+
From a checkout, with Node 24+, Python and a C11 compiler:
|
|
335
|
+
|
|
336
|
+
```sh
|
|
337
|
+
npm ci
|
|
338
|
+
node scripts/bootstrap-native.mjs
|
|
339
|
+
npm run bench:compare
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Set `AUG_BENCH_PYTHON=/path/to/python3` or `CC=/path/to/clang` to select the reference interpreter/compiler. `AUG_NATIVE_HOME` selects the native dependency cache. The raw result file records versions and a source fingerprint. Compilation timings are included separately from executable run time.
|
|
343
|
+
|
|
344
|
+
For core/JSON only, extract the smaller native source dependencies and omit HTTP:
|
|
345
|
+
|
|
346
|
+
```sh
|
|
347
|
+
node scripts/bootstrap-native.mjs --extract-only --only minicoro,yyjson
|
|
348
|
+
npm run bench:compare -- --skip-http
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
The full suite writes `docs/benchmark-results.json`; a core-only run writes `.aug-build/benchmarks/results-core.json` and preserves the complete wiki measurements. Focus on selected workloads while trying your own changes:
|
|
352
|
+
|
|
353
|
+
```sh
|
|
354
|
+
npm run bench:compare -- --only cpu,collections-200k
|
|
355
|
+
npm run bench:compare -- --only http --http-requests 10000
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Focused runs write `.aug-build/benchmarks/results-focused.json`. Use `--output PATH` to keep separate reports. Render graphs, tables and the exact source examples from the full result file using Python 3.12+:
|
|
359
|
+
|
|
360
|
+
```sh
|
|
361
|
+
python3 -m venv .aug-build/benchmark-plotting
|
|
362
|
+
.aug-build/benchmark-plotting/bin/python -m pip install -r benchmarks/plot-requirements.txt
|
|
363
|
+
.aug-build/benchmark-plotting/bin/python scripts/render-benchmarks.py
|
|
364
|
+
.aug-build/benchmark-plotting/bin/python scripts/render-benchmarks.py --check
|
|
365
|
+
npm run docs:build
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
The plot environment is isolated and ignored; published documentation includes the rendered graphs and needs no Python installation. Review this page's environment, interpretations and limitations when replacing measurements. Short exploratory runs can use `--iterations 3 --warmup 1 --http-rounds 1 --http-requests 1000`; they have less statistical coverage.
|
|
369
|
+
|
|
370
|
+
### Comparison implementation sources
|
|
371
|
+
|
|
372
|
+
These are the complete reference programs used for the graphs. The C collection case preallocates integer tables, while August, Node and Python use their normal growing collections. Expected inputs and printed checksums match.
|
|
373
|
+
|
|
374
|
+
::: details C reference
|
|
375
|
+
|
|
376
|
+
[benchmark-source-c-start]: #
|
|
377
|
+
|
|
378
|
+
```c
|
|
379
|
+
#include <stdint.h>
|
|
380
|
+
#include <stdio.h>
|
|
381
|
+
#include <stdlib.h>
|
|
382
|
+
#include <string.h>
|
|
383
|
+
#include "yyjson.h"
|
|
384
|
+
|
|
385
|
+
// A specialized integer table is a useful C baseline, not August's generic value representation.
|
|
386
|
+
typedef struct { int64_t key, value; unsigned char occupied; } Entry;
|
|
387
|
+
static size_t slot(Entry *table, size_t mask, int64_t key) {
|
|
388
|
+
uint64_t hash = (uint64_t)key;
|
|
389
|
+
hash ^= hash >> 30; hash *= UINT64_C(0xbf58476d1ce4e5b9);
|
|
390
|
+
hash ^= hash >> 27; hash *= UINT64_C(0x94d049bb133111eb); hash ^= hash >> 31;
|
|
391
|
+
size_t index = (size_t)hash & mask;
|
|
392
|
+
while (table[index].occupied && table[index].key != key) index = (index + 1) & mask;
|
|
393
|
+
return index;
|
|
394
|
+
}
|
|
395
|
+
int main(int argc, char **argv) {
|
|
396
|
+
if (argc != 3) return 2;
|
|
397
|
+
int64_t count = strtoll(argv[2], NULL, 10);
|
|
398
|
+
if (!strcmp(argv[1], "startup")) puts("7");
|
|
399
|
+
else if (!strcmp(argv[1], "cpu")) {
|
|
400
|
+
int64_t state = 123;
|
|
401
|
+
for (int64_t i = 0; i < count; i++) {
|
|
402
|
+
int64_t product = state * 48271;
|
|
403
|
+
state = product - (product / 2147483647) * 2147483647;
|
|
404
|
+
}
|
|
405
|
+
printf("%lld\n", (long long)state);
|
|
406
|
+
} else if (!strcmp(argv[1], "collections")) {
|
|
407
|
+
size_t capacity = 8; while (capacity < (size_t)count * 2) capacity *= 2;
|
|
408
|
+
Entry *values = calloc(capacity, sizeof(Entry)), *unique = calloc(capacity, sizeof(Entry));
|
|
409
|
+
if (!values || !unique) return 3;
|
|
410
|
+
for (int64_t i = 0; i < count; i++) {
|
|
411
|
+
values[slot(values, capacity - 1, i)] = (Entry){i, i * 3, 1};
|
|
412
|
+
unique[slot(unique, capacity - 1, i)] = (Entry){i, 0, 1};
|
|
413
|
+
}
|
|
414
|
+
int64_t checksum = 0;
|
|
415
|
+
for (size_t i = 0; i < capacity; i++) if (values[i].occupied && unique[slot(unique, capacity - 1, values[i].key)].occupied) checksum += values[i].value;
|
|
416
|
+
printf("%lld\ntrue\n", (long long)checksum);
|
|
417
|
+
free(values); free(unique);
|
|
418
|
+
} else if (!strcmp(argv[1], "json")) {
|
|
419
|
+
const char *input = "{\"id\":7,\"message\":\"hello\",\"values\":[1,2,3]}";
|
|
420
|
+
int64_t checksum = 0;
|
|
421
|
+
for (int64_t i = 0; i < count; i++) {
|
|
422
|
+
yyjson_doc *doc = yyjson_read(input, strlen(input), 0); if (!doc) return 4;
|
|
423
|
+
yyjson_val *root = yyjson_doc_get_root(doc);
|
|
424
|
+
yyjson_val *id = yyjson_obj_get(root, "id");
|
|
425
|
+
if (!yyjson_is_int(id) || !yyjson_is_str(yyjson_obj_get(root, "message")) || !yyjson_is_arr(yyjson_obj_get(root, "values"))) return 5;
|
|
426
|
+
size_t length = 0; char *encoded = yyjson_write(doc, 0, &length); if (!encoded) return 6;
|
|
427
|
+
checksum += yyjson_get_sint(id) + (int64_t)length;
|
|
428
|
+
free(encoded); yyjson_doc_free(doc);
|
|
429
|
+
}
|
|
430
|
+
printf("%lld\n", (long long)checksum);
|
|
431
|
+
} else return 2;
|
|
432
|
+
return 0;
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
[benchmark-source-c-end]: #
|
|
437
|
+
|
|
438
|
+
:::
|
|
439
|
+
|
|
440
|
+
::: details Node reference
|
|
441
|
+
|
|
442
|
+
[benchmark-source-node-start]: #
|
|
443
|
+
|
|
444
|
+
```js
|
|
445
|
+
const [workload, countText] = process.argv.slice(2), count = Number(countText);
|
|
446
|
+
if (workload === 'startup') console.log(7);
|
|
447
|
+
else if (workload === 'cpu') {
|
|
448
|
+
let state = 123;
|
|
449
|
+
for (let i = 0; i < count; i++) {
|
|
450
|
+
const product = state * 48271;
|
|
451
|
+
state = product - Math.trunc(product / 2147483647) * 2147483647;
|
|
452
|
+
}
|
|
453
|
+
console.log(state);
|
|
454
|
+
} else if (workload === 'collections') {
|
|
455
|
+
const values = new Map(), unique = new Set();
|
|
456
|
+
for (let i = 0; i < count; i++) { values.set(i, i * 3); unique.add(i); }
|
|
457
|
+
let checksum = 0;
|
|
458
|
+
for (const [key, value] of values) if (unique.has(key)) checksum += value;
|
|
459
|
+
console.log(checksum); console.log(values.size === unique.size);
|
|
460
|
+
} else if (workload === 'json') {
|
|
461
|
+
let checksum = 0;
|
|
462
|
+
for (let i = 0; i < count; i++) {
|
|
463
|
+
const value = JSON.parse('{"id":7,"message":"hello","values":[1,2,3]}');
|
|
464
|
+
checksum += value.id + JSON.stringify(value).length;
|
|
465
|
+
}
|
|
466
|
+
console.log(checksum);
|
|
467
|
+
} else if (workload === 'http') {
|
|
468
|
+
const { default: http } = await import('node:http');
|
|
469
|
+
http.createServer((req, res) => {
|
|
470
|
+
if (req.method !== 'GET' || req.url !== '/bench') { res.writeHead(404); res.end(); return; }
|
|
471
|
+
const body = JSON.stringify({ id: 7, message: 'hello' });
|
|
472
|
+
res.writeHead(200, { 'content-type': 'application/json', 'content-length': Buffer.byteLength(body) }); res.end(body);
|
|
473
|
+
}).listen(0, '127.0.0.1', function () { console.log('PORT ' + this.address().port); });
|
|
474
|
+
} else throw new Error('Unknown workload');
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
[benchmark-source-node-end]: #
|
|
478
|
+
|
|
479
|
+
:::
|
|
480
|
+
|
|
481
|
+
::: details Python reference
|
|
482
|
+
|
|
483
|
+
[benchmark-source-python-start]: #
|
|
484
|
+
|
|
485
|
+
```python
|
|
486
|
+
import sys
|
|
487
|
+
|
|
488
|
+
workload, count = sys.argv[1], int(sys.argv[2])
|
|
489
|
+
if workload == 'startup':
|
|
490
|
+
print(7)
|
|
491
|
+
elif workload == 'cpu':
|
|
492
|
+
state = 123
|
|
493
|
+
for index in range(count):
|
|
494
|
+
product = state * 48271
|
|
495
|
+
state = product - (product // 2147483647) * 2147483647
|
|
496
|
+
print(state)
|
|
497
|
+
elif workload == 'collections':
|
|
498
|
+
values, unique = {}, set()
|
|
499
|
+
for index in range(count):
|
|
500
|
+
values[index] = index * 3
|
|
501
|
+
unique.add(index)
|
|
502
|
+
checksum = sum(value for key, value in values.items() if key in unique)
|
|
503
|
+
print(checksum)
|
|
504
|
+
print(str(len(values) == len(unique)).lower())
|
|
505
|
+
elif workload == 'json':
|
|
506
|
+
import json
|
|
507
|
+
checksum = 0
|
|
508
|
+
for index in range(count):
|
|
509
|
+
value = json.loads('{"id":7,"message":"hello","values":[1,2,3]}')
|
|
510
|
+
checksum += value['id'] + len(json.dumps(value, separators=(',', ':')))
|
|
511
|
+
print(checksum)
|
|
512
|
+
else:
|
|
513
|
+
raise ValueError('Unknown workload')
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
[benchmark-source-python-end]: #
|
|
517
|
+
|
|
518
|
+
:::
|
|
519
|
+
|
|
520
|
+
## Production assessment
|
|
521
|
+
|
|
522
|
+
**Experimental; appropriate for prototypes and controlled pilots. General production readiness is not established.** The measured native path is viable enough to continue developing and profiling. These microbenchmarks do not cover the correctness, operational behavior and portability needed for a production language/runtime.
|
|
523
|
+
|
|
524
|
+
| Remaining evidence or feature | Why it matters |
|
|
525
|
+
| --- | --- |
|
|
526
|
+
| Application-specific profiling | These small workloads do not predict a complete application's performance. |
|
|
527
|
+
| Long-running memory/lifecycle tests | Peak RSS of a short process does not prove a stable server heap. |
|
|
528
|
+
| Tasks that capture injected mutable state; cleanup of owned shared values | These ownership and resource-lifetime cases still have gaps. Check the gap ledger before relying on them. |
|
|
529
|
+
| Multicore workers, bounded channels and broadcasts | Tasks currently run on one OS thread; these features are not available yet. |
|
|
530
|
+
| Independent HTTP conformance and adverse-client tests | Existing socket regressions do not cover the entire HTTP specification. |
|
|
531
|
+
| Other native platform builds | The native bootstrap and full suite are verified on macOS ARM and Linux ARM. Linux x86-64 runs in CI; Windows and other platforms remain unverified. |
|
|
532
|
+
| Identity-provider hardening and durable storage | The OIDC demo is a development proof; persistence, key rotation, federation and certification remain. |
|
|
533
|
+
| Stable package/native ABI and operational tooling | Source packages work, but compiler compatibility is exact and rich debugging remains limited. |
|
|
534
|
+
|
|
535
|
+
See [the library/runtime gap ledger](web-library-gaps.md) for current support and limitations.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Production readiness and dependencies
|
|
2
|
+
|
|
3
|
+
August 0.19 is experimental. The compiler, CLI, packages, standard declarations, and editor can be tried today; the project does not claim general production readiness. Use the [getting-started guide](getting-started.md) for a first application, [the roadmap](roadmap.md) for release gates, and [the compatibility page](compatibility.md) for the proposed 1.0 support contract.
|
|
4
|
+
|
|
5
|
+
## What is measured and verified
|
|
6
|
+
|
|
7
|
+
The repository checks compiler types, native execution, language examples, generated specs, package installation outside the checkout, and the VS Code extension in CI. [Performance measurements](performance.md) compare specific programs and HTTP loads on named hardware. A benchmark is evidence for that program and environment, not a general speed guarantee.
|
|
8
|
+
|
|
9
|
+
The [robustness tests](../tests/robustness.test.mjs) mutate 5,000 source files through the parser and 1,000 through project checking, then compare generated native integer, Map, and Set programs in debug and release modes with independent JavaScript oracles. CI also runs [core native stress programs](../scripts/sanitize-core.mjs) for collections, task joining, and owned `Shared<T>` transfer with AddressSanitizer and UBSan on macOS and Linux. Run them locally with `npm run test:sanitizers`. This catches specific crashes, wrong results, and memory errors in the exercised paths; it does not prove the compiler, HTTP/crypto libraries, or all programs safe. Leak detection is disabled for this gate because the macOS AddressSanitizer runtime does not support it.
|
|
10
|
+
|
|
11
|
+
The same-app [OpenID Connect example](examples/oidc-login/index.md) proves integration paths; it stores accounts, signing keys, and sessions in memory. It is a development demonstration, not a production identity service.
|
|
12
|
+
|
|
13
|
+
## Dependencies and licenses
|
|
14
|
+
|
|
15
|
+
The npm CLI and three August library packages have **no npm production dependencies outside their matching August packages**. The VS Code extension's npm audit currently reports zero advisories. The wiki build uses VitePress and a pinned Vite override; run `npm audit` before each release. npm audit only covers npm packages and cannot certify native code or deployment configuration.
|
|
16
|
+
|
|
17
|
+
| Dependency | Role | License from upstream | Distribution consideration |
|
|
18
|
+
| --- | --- | --- | --- |
|
|
19
|
+
| minicoro | Portable task runtime source | Public domain or MIT No Attribution | Source is fetched with a checked SHA-256. |
|
|
20
|
+
| yyjson | JSON source | MIT | Source is fetched with a checked SHA-256. |
|
|
21
|
+
| libwebsockets | Native HTTP library | MIT core; bundled portions have their own notices | Static link in a full native build; preserve applicable notices. |
|
|
22
|
+
| GnuTLS | TLS and cryptography | LGPL 2.1 or later core | Shared library; preserve notices and satisfy LGPL distribution terms. |
|
|
23
|
+
| Bundled libtasn1 and libunistring | GnuTLS's configured included dependencies | LGPL 2.1 or later for libtasn1; LGPL 3 or later or GPL 2 or later for libunistring | Inspect the exact GnuTLS source bundle and preserve applicable terms. |
|
|
24
|
+
| Nettle | Cryptographic primitives | LGPL 3 or later or GPL 2 or later | Shared library; choose and comply with a permitted license route. |
|
|
25
|
+
| GMP | Big integer arithmetic | LGPL 3 or later or GPL 2 or later | Shared library; choose and comply with a permitted license route. |
|
|
26
|
+
| zlib | Host compression library | zlib | Include applicable notice when redistributing it. |
|
|
27
|
+
| CMake, pkgconf | Native build tools | See upstream license files | Build tools are not included in the current source/npm/VSIX release artifacts. |
|
|
28
|
+
|
|
29
|
+
The exact versions, archive URLs, and SHA-256 values are in [`native-dependencies.lock.json`](../scripts/native-dependencies.lock.json). See [native dependency notices](../THIRD_PARTY_NOTICES.md) and the upstream [GMP copying terms](https://gmplib.org/manual/Copying), [GnuTLS security advisories](https://gnutls.org/security-new.html), [libwebsockets security policy](https://github.com/warmcat/libwebsockets/security), [libtasn1 terms](https://www.gnu.org/software/libtasn1/), and [libunistring terms](https://www.gnu.org/software/libunistring/manual/html_node/Licenses.html). A redistributor of a compiled app must review its actual linked libraries, notices, source obligations, and target environment. The repository's audit is a starting inventory, not legal advice or a vulnerability certification. The pinned libwebsockets commit is not automatically updated when upstream fixes arrive; review upstream's security notes before shipping it.
|
|
30
|
+
|
|
31
|
+
## Release gates still open
|
|
32
|
+
|
|
33
|
+
- **Platform support:** the full pinned web/crypto bootstrap passes on macOS ARM and Linux ARM. [Docker build/run bases](docker.md) run core, web, and crypto programs on Linux. Linux x86-64 runs in CI; other platforms remain unverified.
|
|
34
|
+
- **Concurrency and ownership:** tasks use one OS thread. The [conformance suite](language-conformance.md) exercises injected captures, mutation after a child starts inside `borrow`, owned `Shared<T>` cleanup, branch joins, cancellation, and the public `Task<T>` error contract. A 1.0 support claim still depends on the platform, distribution, and compatibility gates.
|
|
35
|
+
- **Security and reliability:** HTTP and OIDC need broad protocol conformance, durable credentials and keys, rotation, long-running load tests, and deployment guidance. The [gap ledger](web-library-gaps.md) records the precise work.
|
|
36
|
+
- **Package and ABI stability:** published npm identities, reproducible releases, compatibility policy, and native adapter ABI need stable release gates.
|
|
37
|
+
- **Operational behavior:** failure handling, cancellation, instrumentation, platform builds, and resource ceilings need repeated CI and field testing.
|
|
38
|
+
|
|
39
|
+
For a trial deployment, pin the compiler and native lock, run the project's tests and `aug spec --check`, review the generated C/native linker inputs, and validate the executable under your own load and failure conditions. Track the [gap ledger](web-library-gaps.md) before promising production service levels.
|