hecks 0.2.0 → 1.0.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.
- checksums.yaml +5 -5
- data/lib/hecks/adapters/driven/claude_code.adapter +3 -0
- data/lib/hecks/adapters/driven/claude_code.rb +127 -0
- data/lib/hecks/adapters/driven/d1.adapter +12 -0
- data/lib/hecks/adapters/driven/d1.rb +427 -0
- data/lib/hecks/adapters/driven/folder.adapter +3 -0
- data/lib/hecks/adapters/driven/folder.rb +199 -0
- data/lib/hecks/adapters/driven/google_authentication.adapter +3 -0
- data/lib/hecks/adapters/driven/google_authentication.rb +100 -0
- data/lib/hecks/adapters/driven/governance_authorization.adapter +3 -0
- data/lib/hecks/adapters/driven/governance_authorization.rb +101 -0
- data/lib/hecks/adapters/driven/heki/journal.rb +56 -0
- data/lib/hecks/adapters/driven/heki/saga_store.rb +99 -0
- data/lib/hecks/adapters/driven/heki/snapshot.rb +65 -0
- data/lib/hecks/adapters/driven/heki.adapter +4 -0
- data/lib/hecks/adapters/driven/heki.rb +179 -0
- data/lib/hecks/adapters/driven/identity_registry.adapter +3 -0
- data/lib/hecks/adapters/driven/identity_registry.rb +26 -0
- data/lib/hecks/adapters/driven/in_memory_ordering.rb +51 -0
- data/lib/hecks/adapters/driven/lambda/client.rb +63 -0
- data/lib/hecks/adapters/driven/lambda.adapter +4 -0
- data/lib/hecks/adapters/driven/lambda.rb +145 -0
- data/lib/hecks/adapters/driven/memory.adapter +3 -0
- data/lib/hecks/adapters/driven/memory.rb +103 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.adapter +3 -0
- data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +28 -0
- data/lib/hecks/adapters/driven/postgres/codec.rb +88 -0
- data/lib/hecks/adapters/driven/postgres/schema_builder.rb +207 -0
- data/lib/hecks/adapters/driven/postgres.adapter +5 -0
- data/lib/hecks/adapters/driven/postgres.rb +438 -0
- data/lib/hecks/adapters/driven/postgres_era.adapter +17 -0
- data/lib/hecks/adapters/driven/prism.adapter +3 -0
- data/lib/hecks/adapters/driven/prism.rb +80 -0
- data/lib/hecks/adapters/driven/secure_random_identity.adapter +3 -0
- data/lib/hecks/adapters/driven/secure_random_identity.rb +14 -0
- data/lib/hecks/adapters/driven/sql_query_builder.rb +221 -0
- data/lib/hecks/adapters/driven/sqlite/codec.rb +80 -0
- data/lib/hecks/adapters/driven/sqlite/projection.rb +172 -0
- data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +192 -0
- data/lib/hecks/adapters/driven/sqlite.adapter +9 -0
- data/lib/hecks/adapters/driven/sqlite.rb +306 -0
- data/lib/hecks/adapters/driven/system_clock.adapter +3 -0
- data/lib/hecks/adapters/driven/system_clock.rb +14 -0
- data/lib/hecks/adapters/driven.rb +54 -0
- data/lib/hecks/adapters.rb +6 -0
- data/lib/hecks/behaviors/dsl.rb +125 -0
- data/lib/hecks/behaviors/expectations.rb +340 -0
- data/lib/hecks/behaviors/ir.rb +31 -0
- data/lib/hecks/behaviors/rspec.rb +42 -0
- data/lib/hecks/behaviors/runner.rb +96 -0
- data/lib/hecks/behaviors.rb +25 -0
- data/lib/hecks/bluebook/aggregate.rb +108 -0
- data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +134 -0
- data/lib/hecks/bluebook/assembly/build.rb +48 -0
- data/lib/hecks/bluebook/assembly/contract.rb +112 -0
- data/lib/hecks/bluebook/assembly/contracts.rb +438 -0
- data/lib/hecks/bluebook/assembly/marks.rb +228 -0
- data/lib/hecks/bluebook/assembly/specializer.rb +70 -0
- data/lib/hecks/bluebook/assembly.rb +91 -0
- data/lib/hecks/bluebook/attribute.rb +96 -0
- data/lib/hecks/bluebook/behaviour/aggregate.rb +83 -0
- data/lib/hecks/bluebook/behaviour/attribute.rb +27 -0
- data/lib/hecks/bluebook/behaviour/chapter.rb +72 -0
- data/lib/hecks/bluebook/behaviour/command.rb +116 -0
- data/lib/hecks/bluebook/behaviour/domain_port.rb +25 -0
- data/lib/hecks/bluebook/behaviour/entity.rb +59 -0
- data/lib/hecks/bluebook/behaviour/hexagon.rb +50 -0
- data/lib/hecks/bluebook/behaviour/lifecycle.rb +68 -0
- data/lib/hecks/bluebook/behaviour/policy.rb +52 -0
- data/lib/hecks/bluebook/behaviour/process_manager.rb +51 -0
- data/lib/hecks/bluebook/behaviour/query.rb +10 -0
- data/lib/hecks/bluebook/behaviour/read_model.rb +29 -0
- data/lib/hecks/bluebook/behaviour/traits.rb +81 -0
- data/lib/hecks/bluebook/behaviour/value_object.rb +33 -0
- data/lib/hecks/bluebook/chapter.rb +78 -0
- data/lib/hecks/bluebook/command.rb +124 -0
- data/lib/hecks/bluebook/domain_port.rb +102 -0
- data/lib/hecks/bluebook/dsl/adapter_builder.rb +34 -0
- data/lib/hecks/bluebook/dsl/aggregate_builder.rb +1018 -0
- data/lib/hecks/bluebook/dsl/attribute_collector.rb +348 -0
- data/lib/hecks/bluebook/dsl/binding_proxy.rb +71 -0
- data/lib/hecks/bluebook/dsl/bluebook_builder.rb +1087 -0
- data/lib/hecks/bluebook/dsl/command_builder.rb +714 -0
- data/lib/hecks/bluebook/dsl/const_shim.rb +81 -0
- data/lib/hecks/bluebook/dsl/domain_port_builder.rb +79 -0
- data/lib/hecks/bluebook/dsl/entity_builder.rb +430 -0
- data/lib/hecks/bluebook/dsl/generic_dispatch.rb +366 -0
- data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +163 -0
- data/lib/hecks/bluebook/dsl/identity_declaration.rb +191 -0
- data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +44 -0
- data/lib/hecks/bluebook/dsl/malformed.rb +7 -0
- data/lib/hecks/bluebook/dsl/policy_builder.rb +135 -0
- data/lib/hecks/bluebook/dsl/port_builder.rb +39 -0
- data/lib/hecks/bluebook/dsl/port_operation_builder.rb +142 -0
- data/lib/hecks/bluebook/dsl/process_manager_builder.rb +306 -0
- data/lib/hecks/bluebook/dsl/query_builder.rb +113 -0
- data/lib/hecks/bluebook/dsl/read_model_builder.rb +233 -0
- data/lib/hecks/bluebook/dsl/rule_reference.rb +173 -0
- data/lib/hecks/bluebook/dsl/translation_builder.rb +243 -0
- data/lib/hecks/bluebook/dsl/value_object_builder.rb +178 -0
- data/lib/hecks/bluebook/dsl/word_gate.rb +228 -0
- data/lib/hecks/bluebook/dsl/world_builder.rb +117 -0
- data/lib/hecks/bluebook/dsl.rb +45 -0
- data/lib/hecks/bluebook/entity.rb +103 -0
- data/lib/hecks/bluebook/expression/canonical_form.rb +123 -0
- data/lib/hecks/bluebook/expression/evaluator.rb +304 -0
- data/lib/hecks/bluebook/expression/projection.json +218 -0
- data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +233 -0
- data/lib/hecks/bluebook/expression/resolver.rb +781 -0
- data/lib/hecks/bluebook/expression.rb +13 -0
- data/lib/hecks/bluebook/hexagon.rb +60 -0
- data/lib/hecks/bluebook/lifecycle.rb +42 -0
- data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +54 -0
- data/lib/hecks/bluebook/meta_validator/judge.rb +621 -0
- data/lib/hecks/bluebook/meta_validator/plan.rb +332 -0
- data/lib/hecks/bluebook/meta_validator/port_judge.rb +51 -0
- data/lib/hecks/bluebook/meta_validator/readings.rb +360 -0
- data/lib/hecks/bluebook/meta_validator/reconstruction.rb +351 -0
- data/lib/hecks/bluebook/meta_validator/shapes.rb +266 -0
- data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +255 -0
- data/lib/hecks/bluebook/meta_validator/translation_judge.rb +138 -0
- data/lib/hecks/bluebook/meta_validator/world_judge.rb +78 -0
- data/lib/hecks/bluebook/meta_validator.rb +542 -0
- data/lib/hecks/bluebook/model_check.rb +445 -0
- data/lib/hecks/bluebook/pattern_subset.rb +184 -0
- data/lib/hecks/bluebook/policy.rb +41 -0
- data/lib/hecks/bluebook/process_manager.rb +128 -0
- data/lib/hecks/bluebook/project_discovery.rb +30 -0
- data/lib/hecks/bluebook/project_loader.rb +40 -0
- data/lib/hecks/bluebook/project_register.rb +82 -0
- data/lib/hecks/bluebook/query.rb +61 -0
- data/lib/hecks/bluebook/read_model.rb +109 -0
- data/lib/hecks/bluebook/reference.rb +74 -0
- data/lib/hecks/bluebook/smoke_test.rb +166 -0
- data/lib/hecks/bluebook/synthesizer.rb +95 -0
- data/lib/hecks/bluebook/translation.rb +92 -0
- data/lib/hecks/bluebook/value_object.rb +66 -0
- data/lib/hecks/bluebook.rb +74 -0
- data/lib/hecks/codemod.rb +342 -0
- data/lib/hecks/construct.rb +71 -0
- data/lib/hecks/deploy/bluebook/deploy.bluebook +219 -0
- data/lib/hecks/deploy/bluebook/deploy.hecksagon +4 -0
- data/lib/hecks/deploy/oidc.json +18 -0
- data/lib/hecks/doc/reference.rb +410 -0
- data/lib/hecks/embryonaut_bluebook.rb +75 -0
- data/lib/hecks/facade/cli_door.rb +119 -0
- data/lib/hecks/facade/cli_runner.rb +190 -0
- data/lib/hecks/facade/command_request.rb +105 -0
- data/lib/hecks/facade/handle.rb +173 -0
- data/lib/hecks/facade/json_door.rb +166 -0
- data/lib/hecks/facade/surface/aggregate_door.rb +185 -0
- data/lib/hecks/facade/surface/chapter.rb +107 -0
- data/lib/hecks/facade/surface.rb +48 -0
- data/lib/hecks/facade.rb +44 -0
- data/lib/hecks/forms/app.rb +341 -0
- data/lib/hecks/forms/command_form_renderer.rb +113 -0
- data/lib/hecks/forms/examples/banking_console.bluebook +3 -0
- data/lib/hecks/forms/field_renderer.rb +177 -0
- data/lib/hecks/forms/field_shape.rb +232 -0
- data/lib/hecks/forms/html.rb +84 -0
- data/lib/hecks/forms/index_renderer.rb +35 -0
- data/lib/hecks/forms/page.rb +157 -0
- data/lib/hecks/forms/params.rb +161 -0
- data/lib/hecks/forms/port_argument.rb +46 -0
- data/lib/hecks/forms/query_form_renderer.rb +114 -0
- data/lib/hecks/forms/record_renderer.rb +119 -0
- data/lib/hecks/forms/record_table.rb +68 -0
- data/lib/hecks/forms/reference_options.rb +30 -0
- data/lib/hecks/forms/value_object_shape.rb +46 -0
- data/lib/hecks/forms.rb +54 -0
- data/lib/hecks/fqn.rb +94 -0
- data/lib/hecks/framework/bluebook/compliance.bluebook +1 -0
- data/lib/hecks/framework/bluebook/console_settings.bluebook +489 -0
- data/lib/hecks/framework/bluebook/framework.hecksagon +32 -0
- data/lib/hecks/framework/bluebook/governance.bluebook +145 -0
- data/lib/hecks/framework/bluebook/identity.bluebook +90 -0
- data/lib/hecks/framework/oidc.json +39 -0
- data/lib/hecks/framework.rb +90 -0
- data/lib/hecks/freezer.rb +67 -0
- data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +527 -0
- data/lib/hecks/fuzzing/invalid_value_generator.rb +86 -0
- data/lib/hecks/fuzzing/isolated_boot.rb +286 -0
- data/lib/hecks/fuzzing/properties.rb +1192 -0
- data/lib/hecks/fuzzing/replay.rb +668 -0
- data/lib/hecks/fuzzing/sequence_generator/catalog.rb +93 -0
- data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +80 -0
- data/lib/hecks/fuzzing/sequence_generator/picker.rb +96 -0
- data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +250 -0
- data/lib/hecks/fuzzing/sequence_generator.rb +131 -0
- data/lib/hecks/fuzzing/value_generator.rb +200 -0
- data/lib/hecks/fuzzing.rb +12 -0
- data/lib/hecks/grammar/evolve.rb +324 -0
- data/lib/hecks/grammar/expression.bluebook +420 -0
- data/lib/hecks/grammar/expression_operators.json +1648 -0
- data/lib/hecks/grammar/grammar.hecksagon +20 -0
- data/lib/hecks/grammar/oidc.json +69 -0
- data/lib/hecks/grammar/translation.bluebook +203 -0
- data/lib/hecks/grammar.rb +178 -0
- data/lib/hecks/ir.rb +126 -0
- data/lib/hecks/language/adapter.bluebook +116 -0
- data/lib/hecks/language/bluebook/aggregate.bluebook +581 -0
- data/lib/hecks/language/bluebook/attaches/paging.bluebook +76 -0
- data/lib/hecks/language/bluebook/bluebook.bluebook +256 -0
- data/lib/hecks/language/bluebook/bluebook.hecksagon +24 -0
- data/lib/hecks/language/bluebook/command.bluebook +471 -0
- data/lib/hecks/language/bluebook/entity.bluebook +392 -0
- data/lib/hecks/language/bluebook/policy.bluebook +189 -0
- data/lib/hecks/language/bluebook/process_manager.bluebook +381 -0
- data/lib/hecks/language/bluebook/projection.bluebook +267 -0
- data/lib/hecks/language/bluebook/query.bluebook +245 -0
- data/lib/hecks/language/bluebook/shape.bluebook +292 -0
- data/lib/hecks/language/bluebook/syntax.bluebook +448 -0
- data/lib/hecks/language/bluebook/vocabulary.bluebook +379 -0
- data/lib/hecks/language/hecksagon/adapter_binding.bluebook +51 -0
- data/lib/hecks/language/hecksagon/domain_port.bluebook +76 -0
- data/lib/hecks/language/hecksagon/hecksagon.bluebook +131 -0
- data/lib/hecks/language/hecksagon/port_operation.bluebook +102 -0
- data/lib/hecks/language/oidc.json +333 -0
- data/lib/hecks/language/port.bluebook +120 -0
- data/lib/hecks/language/translation/translation.bluebook +110 -0
- data/lib/hecks/language/translation/translation_aggregate.bluebook +267 -0
- data/lib/hecks/language/world/wiring.bluebook +62 -0
- data/lib/hecks/language/world/world.bluebook +84 -0
- data/lib/hecks/literal.rb +125 -0
- data/lib/hecks/naming.rb +174 -0
- data/lib/hecks/ports/access_control.port +9 -0
- data/lib/hecks/ports/access_control.rb +62 -0
- data/lib/hecks/ports/agent/answers.rb +104 -0
- data/lib/hecks/ports/agent.port +8 -0
- data/lib/hecks/ports/agent.rb +167 -0
- data/lib/hecks/ports/authentication.port +6 -0
- data/lib/hecks/ports/authentication.rb +50 -0
- data/lib/hecks/ports/authorization.port +7 -0
- data/lib/hecks/ports/authorization.rb +62 -0
- data/lib/hecks/ports/clock.port +5 -0
- data/lib/hecks/ports/clock.rb +62 -0
- data/lib/hecks/ports/extraction.port +5 -0
- data/lib/hecks/ports/extraction.rb +37 -0
- data/lib/hecks/ports/identity_assignment.port +5 -0
- data/lib/hecks/ports/identity_assignment.rb +45 -0
- data/lib/hecks/ports/identity_generation.port +5 -0
- data/lib/hecks/ports/identity_generation.rb +49 -0
- data/lib/hecks/ports/identity_resolution.port +5 -0
- data/lib/hecks/ports/identity_resolution.rb +40 -0
- data/lib/hecks/ports/loading.port +4 -0
- data/lib/hecks/ports/loading.rb +13 -0
- data/lib/hecks/ports/persistence/append_only.rb +138 -0
- data/lib/hecks/ports/persistence/binding_policy.rb +56 -0
- data/lib/hecks/ports/persistence/execution.rb +23 -0
- data/lib/hecks/ports/persistence/null_saga_store.rb +25 -0
- data/lib/hecks/ports/persistence/plugin.rb +54 -0
- data/lib/hecks/ports/persistence/plugins/era/era_check.rb +169 -0
- data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +128 -0
- data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +161 -0
- data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +61 -0
- data/lib/hecks/ports/persistence/plugins/era/lineage.rb +304 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +171 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +190 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +478 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +166 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +314 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +168 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +170 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +134 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +137 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +89 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +85 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +43 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +132 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +74 -0
- data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +758 -0
- data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +31 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +46 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +102 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +46 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +70 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +72 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +120 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +183 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +41 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +28 -0
- data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +30 -0
- data/lib/hecks/ports/persistence/plugins/era/translation.rb +11 -0
- data/lib/hecks/ports/persistence/plugins/era.rb +48 -0
- data/lib/hecks/ports/persistence/remote_runtime.rb +42 -0
- data/lib/hecks/ports/persistence/repository_factory.rb +30 -0
- data/lib/hecks/ports/persistence.port +4 -0
- data/lib/hecks/ports/persistence.rb +39 -0
- data/lib/hecks/ports/projection.port +4 -0
- data/lib/hecks/ports/projection.rb +96 -0
- data/lib/hecks/ports/query/in_memory.rb +60 -0
- data/lib/hecks/ports/query/ordering.rb +41 -0
- data/lib/hecks/ports/query.rb +36 -0
- data/lib/hecks/ports.rb +27 -0
- data/lib/hecks/projections/diagrams.rb +642 -0
- data/lib/hecks/projections/ir.rb +18 -0
- data/lib/hecks/projections/model/deviations.rb +98 -0
- data/lib/hecks/projections/model.rb +145 -0
- data/lib/hecks/projections/oidc.rb +110 -0
- data/lib/hecks/projections/parser_table.rb +159 -0
- data/lib/hecks/projections/reference.rb +38 -0
- data/lib/hecks/projections/shape.rb +44 -0
- data/lib/hecks/projections/statements.rb +110 -0
- data/lib/hecks/projections/vocabulary.rb +100 -0
- data/lib/hecks/projections.rb +32 -0
- data/lib/hecks/projector/cli_projector.rb +446 -0
- data/lib/hecks/projector/docs_projector.rb +321 -0
- data/lib/hecks/projector/exporter.rb +158 -0
- data/lib/hecks/projector/ir_projector.rb +18 -0
- data/lib/hecks/projector/narrate_projector.rb +243 -0
- data/lib/hecks/projector/target.rb +97 -0
- data/lib/hecks/projector.rb +186 -0
- data/lib/hecks/query_ir.rb +411 -0
- data/lib/hecks/query_specification/common/authorization_spec.rb +9 -0
- data/lib/hecks/query_specification/common/comparators.rb +25 -0
- data/lib/hecks/query_specification/common/comparison.rb +174 -0
- data/lib/hecks/query_specification/common/cursor_spec.rb +9 -0
- data/lib/hecks/query_specification/common/dsl.rb +58 -0
- data/lib/hecks/query_specification/common/inspection_spec.rb +9 -0
- data/lib/hecks/query_specification/common/limit_spec.rb +9 -0
- data/lib/hecks/query_specification/common/null_policy.rb +92 -0
- data/lib/hecks/query_specification/common/null_semantics.rb +11 -0
- data/lib/hecks/query_specification/common/offset_spec.rb +9 -0
- data/lib/hecks/query_specification/common/options.rb +32 -0
- data/lib/hecks/query_specification/common/order_by.rb +9 -0
- data/lib/hecks/query_specification/common/specification.rb +10 -0
- data/lib/hecks/query_specification/common/where_clause.rb +9 -0
- data/lib/hecks/query_specification/field_path.rb +107 -0
- data/lib/hecks/query_specification/hop_path.rb +132 -0
- data/lib/hecks/query_specification/read_model/specification.rb +18 -0
- data/lib/hecks/query_specification.rb +14 -0
- data/lib/hecks/rendering.rb +48 -0
- data/lib/hecks/router/namespace_installer.rb +157 -0
- data/lib/hecks/router.rb +70 -0
- data/lib/hecks/runtime/aggregate_lock.rb +45 -0
- data/lib/hecks/runtime/boot_gates.rb +41 -0
- data/lib/hecks/runtime/caller.rb +66 -0
- data/lib/hecks/runtime/capability_graph.rb +44 -0
- data/lib/hecks/runtime/command_interpreter/argument_gate.rb +135 -0
- data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +260 -0
- data/lib/hecks/runtime/command_interpreter.rb +497 -0
- data/lib/hecks/runtime/command_rules/admissibility.rb +357 -0
- data/lib/hecks/runtime/command_rules/arithmetic.rb +260 -0
- data/lib/hecks/runtime/command_rules/authorization.rb +65 -0
- data/lib/hecks/runtime/command_rules/emission.rb +34 -0
- data/lib/hecks/runtime/command_rules/references.rb +189 -0
- data/lib/hecks/runtime/command_rules.rb +28 -0
- data/lib/hecks/runtime/dependency_planning.rb +245 -0
- data/lib/hecks/runtime/dispatcher.rb +301 -0
- data/lib/hecks/runtime/entity_element.rb +253 -0
- data/lib/hecks/runtime/entity_interpreter.rb +299 -0
- data/lib/hecks/runtime/errors.rb +122 -0
- data/lib/hecks/runtime/event.rb +51 -0
- data/lib/hecks/runtime/identity.rb +156 -0
- data/lib/hecks/runtime/instance.rb +175 -0
- data/lib/hecks/runtime/interpreting.rb +90 -0
- data/lib/hecks/runtime/loader.rb +184 -0
- data/lib/hecks/runtime/policy_interpreter.rb +366 -0
- data/lib/hecks/runtime/port_operation_interpreter.rb +210 -0
- data/lib/hecks/runtime/query_interpreter.rb +286 -0
- data/lib/hecks/runtime/reaction_invocation.rb +253 -0
- data/lib/hecks/runtime/read_model_interpreter.rb +341 -0
- data/lib/hecks/runtime/rebuild_sweep.rb +74 -0
- data/lib/hecks/runtime/reference_hop.rb +99 -0
- data/lib/hecks/runtime/refusal_wording.rb +126 -0
- data/lib/hecks/runtime/registry/saga_persistence.rb +142 -0
- data/lib/hecks/runtime/registry/verification.rb +246 -0
- data/lib/hecks/runtime/registry.rb +279 -0
- data/lib/hecks/runtime/remote_dispatcher.rb +143 -0
- data/lib/hecks/runtime/routing.rb +96 -0
- data/lib/hecks/runtime/saga_interpreter/correlation.rb +97 -0
- data/lib/hecks/runtime/saga_interpreter.rb +503 -0
- data/lib/hecks/runtime/saga_pending_dispatch.rb +45 -0
- data/lib/hecks/runtime/tenant_check.rb +84 -0
- data/lib/hecks/runtime/tenant_scope.rb +55 -0
- data/lib/hecks/runtime/value/admission.rb +130 -0
- data/lib/hecks/runtime/value/coercion.rb +565 -0
- data/lib/hecks/runtime/value/invariant_violation.rb +5 -0
- data/lib/hecks/runtime/value.rb +125 -0
- data/lib/hecks/runtime.rb +107 -0
- data/lib/hecks/storehouse.rb +632 -0
- data/lib/hecks/version.rb +16 -0
- data/lib/hecks/vocabulary.rb +218 -0
- data/lib/hecks.rb +123 -6
- data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +90 -0
- data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +128 -0
- data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +160 -0
- metadata +412 -222
- data/bin/hecks +0 -7
- data/bin/hecks-package +0 -65
- data/bin/hecks_console +0 -12
- data/bin/hecks_serverless +0 -6
- data/lib/cli/build.rb +0 -14
- data/lib/cli/command_runner.rb +0 -28
- data/lib/cli/console.rb +0 -10
- data/lib/cli/generate.rb +0 -37
- data/lib/cli/hecks-cli.rb +0 -27
- data/lib/cli/test.rb +0 -57
- data/lib/console/commands.rb +0 -8
- data/lib/console/hecks-console.rb +0 -1
- data/lib/packager/README.md +0 -0
- data/lib/packager/app_runner.rb +0 -21
- data/lib/packager/args.rb +0 -26
- data/lib/packager/compatibility/fixnum.rb +0 -6
- data/lib/packager/hecks.rb +0 -39
- data/lib/packager/query_runner.rb +0 -21
- data/lib/packager/resources/Dockerfile +0 -11
- data/lib/packager/resources/app_binary +0 -7
- data/lib/packager/resources/bundle_config +0 -3
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-linux-x86_64.tar.gz +0 -0
- data/lib/packager/resources/traveling-ruby-20150715-2.2.2-osx.tar.gz +0 -0
- data/lib/serverless/Domain +0 -32
- data/lib/serverless/cli.rb +0 -75
- data/lib/serverless/resources/command_name.js +0 -5
- data/lib/serverless/resources/environment.js +0 -7
- data/lib/serverless/resources/handler.js.tt +0 -28
- data/lib/serverless/resources/run_binary.js +0 -22
- data/lib/serverless/resources/serverless.yml +0 -20
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
module Hecks
|
|
2
|
+
module Bluebook
|
|
3
|
+
module MetaValidator
|
|
4
|
+
# The parts of a bluebook the walk cannot read by name alone.
|
|
5
|
+
#
|
|
6
|
+
# The language now spells its fields exactly as the IR spells them, so the
|
|
7
|
+
# judge reads almost everything straight through: `command.givens`,
|
|
8
|
+
# `value_object.invariants`, `read_model.aggregate_heads`. What remains here
|
|
9
|
+
# is not naming drift — it is places where the IR's SHAPE differs from the
|
|
10
|
+
# language's, and no amount of renaming would close that:
|
|
11
|
+
#
|
|
12
|
+
# transitions one declaration expands to SEVERAL rows, because `from`
|
|
13
|
+
# may be a list of states
|
|
14
|
+
# value_objects the IR holds objects ; the language holds their names
|
|
15
|
+
# normalisations not on the bluebook at all — they come from the canonical
|
|
16
|
+
# form table the expression grammar keeps
|
|
17
|
+
# members plain hashes, one Member root per row, pairs per entry
|
|
18
|
+
# lifecycle one IR object feeding two separate fields
|
|
19
|
+
#
|
|
20
|
+
# Everything in this file is a difference in shape. If something here is
|
|
21
|
+
# only a difference in NAME, it is in the wrong file: rename the language.
|
|
22
|
+
module Readings
|
|
23
|
+
# A list the walk is about to offer, as rows it can shape into dispatches.
|
|
24
|
+
#
|
|
25
|
+
# FROM THE TABLE. This was nine hand-written cases keyed "Category.list", and
|
|
26
|
+
# every one of them was a fact `Assembly::Contracts` is the right place to
|
|
27
|
+
# keep: which shaper turns this list into rows. A list with no shaper reads
|
|
28
|
+
# straight off the node, which is most of them.
|
|
29
|
+
def rows_for(category, list_name, node)
|
|
30
|
+
shaper = Assembly.contract(category).shaper(list_name)
|
|
31
|
+
return Array(node.public_send(list_name)) unless shaper
|
|
32
|
+
|
|
33
|
+
public_send(shaper, node)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# A where-clause is read through its own to_h, which is where the IR spells a
|
|
37
|
+
# symbol argument as ":ceiling". Reading the OBJECT instead lost the colon,
|
|
38
|
+
# and nothing downstream could tell an argument from a literal of the same
|
|
39
|
+
# name.
|
|
40
|
+
def where_rows(node) = Array(node.wheres).map(&:to_h)
|
|
41
|
+
|
|
42
|
+
# The language holds a value object's NAME here ; the IR holds the object.
|
|
43
|
+
def value_object_names(node) = node.value_objects.map { |shape| { name: shape.hecks_name } }
|
|
44
|
+
|
|
45
|
+
# AN IDENTITY IS A LIST OF PARTS, so it is offered one part at a time — the
|
|
46
|
+
# same way attributes and transitions are. The IR holds the paths ; the
|
|
47
|
+
# language holds a row per path, and the ORDER between them is the whole
|
|
48
|
+
# meaning, because the identity is their join.
|
|
49
|
+
def identity_rows(node) = node.identity_paths.map { |path| { value: path } }
|
|
50
|
+
|
|
51
|
+
# Through to_h, which is where Bluebook.render_value spells a symbol argument as
|
|
52
|
+
# ":source". The raw with_spec lost the colon, and a binding that reads an
|
|
53
|
+
# argument became indistinguishable from one carrying a literal string.
|
|
54
|
+
def with_spec_rows(node) = pair_rows(node.to_h[:with_spec])
|
|
55
|
+
|
|
56
|
+
# THE SAME READ, ONE LEVEL IN — `compensates` folds `DispatchSpec`
|
|
57
|
+
# into the language's own `compensates_command_name`/
|
|
58
|
+
# `compensates_with_spec` (`Assembly::Contracts`' own comment on
|
|
59
|
+
# "Dispatch"), so its OWN with_spec pairs live nested one hash
|
|
60
|
+
# down from where `with_spec_rows` looks. `&.dig(...)` — no
|
|
61
|
+
# compensation at all is not an error, it is `pair_rows(nil)`, empty.
|
|
62
|
+
def compensates_with_spec_rows(node) = pair_rows(node.to_h[:compensates]&.dig(:with_spec))
|
|
63
|
+
|
|
64
|
+
# A read model carries the same options an ask does, plus its filters — see
|
|
65
|
+
# option_rows.
|
|
66
|
+
def read_model_option_rows(node) = option_rows(node, filters: true)
|
|
67
|
+
|
|
68
|
+
# The canonical-form table is the expression grammar's, not this chapter's, so
|
|
69
|
+
# the node is not consulted at all.
|
|
70
|
+
def normalisation_table(_node) = normalisation_rows
|
|
71
|
+
|
|
72
|
+
# `lifecycle :status do transition "Retire" => "retired", from: ["issued", "active"] end`
|
|
73
|
+
# is ONE declaration and TWO transitions. Offering it once would leave the
|
|
74
|
+
# second unjudged, which is the whole failure this judge exists to avoid.
|
|
75
|
+
def transition_rows(node)
|
|
76
|
+
lifecycle = node.respond_to?(:lifecycle) ? node.lifecycle : nil
|
|
77
|
+
return [] unless lifecycle
|
|
78
|
+
|
|
79
|
+
lifecycle.transitions.flat_map do |command, transition|
|
|
80
|
+
froms = transition.constrained? ? Array(transition.from) : [nil]
|
|
81
|
+
froms.map do |from|
|
|
82
|
+
{ command: command, from_state: from, to_state: transition.target }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# An OPEN MAP — a member's fields, a dispatch's argument bindings — has no
|
|
88
|
+
# value object that can hold it, so each entry becomes its own row. This is
|
|
89
|
+
# why Member and Dispatch are roots in the language rather than lists.
|
|
90
|
+
def pair_rows(map)
|
|
91
|
+
Array(map&.to_h).map { |key, value| { key: key, value: value } }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# EVERY SPECIFICATION OPTION AN ASK CARRIES, flattened to rows.
|
|
95
|
+
#
|
|
96
|
+
# `offset`, `cursor`, `nulls`, `authorize` and `inspect_query` are
|
|
97
|
+
# five options, one compound (authorize names a policy AND a
|
|
98
|
+
# tenant). `extra_options_to_h` already spells every one of them
|
|
99
|
+
# and drops the absent ones, so this reads that rather than
|
|
100
|
+
# naming them here — a sixth option needs no change on either
|
|
101
|
+
# side.
|
|
102
|
+
#
|
|
103
|
+
# `filters: true` adds a read model's wheres, order_by and limit —
|
|
104
|
+
# `at` tells repeated rows apart, so two wheres do not collapse.
|
|
105
|
+
#
|
|
106
|
+
# THE LANGUAGE MAY HOLD MORE THAN `to_h` CARRIES, and this is where that
|
|
107
|
+
# mattered. Until 2026-08-11, `ReadModel#to_h` omitted all three —
|
|
108
|
+
# `extra_options_to_h` rejects them by name, still does — so a read
|
|
109
|
+
# model's filtering had never been in the wire contract, and I first
|
|
110
|
+
# read that as a wall: if the wire cannot carry it, the language cannot
|
|
111
|
+
# hold it, and a graph assembled from the language must lose it.
|
|
112
|
+
#
|
|
113
|
+
# That was the wrong conclusion. `to_h` is a PROJECTION ; the language
|
|
114
|
+
# is the SOURCE. They have to agree about everything
|
|
115
|
+
# to_h spells, not about everything the language knows. Held as option
|
|
116
|
+
# rows, the filters survived the round trip regardless of whether the
|
|
117
|
+
# wire carried them too — which is exactly why, when a LATER task
|
|
118
|
+
# (Rust read-model codegen) needed `wheres`/`order_by`/`limit` on the
|
|
119
|
+
# wire for an unrelated reason, `ReadModel#to_h` could be extended to
|
|
120
|
+
# spell them (the same mechanism `Query#to_h` already used) without
|
|
121
|
+
# touching this method at all: this reads `node.wheres`/`node.
|
|
122
|
+
# order_by`/`node.limit` off the live object directly below
|
|
123
|
+
# (`filter_options`), never off `to_h`, so the wire format moving did
|
|
124
|
+
# not move this.
|
|
125
|
+
#
|
|
126
|
+
# Named `wheres`, `order_by` and `limit` so they gather back into exactly the
|
|
127
|
+
# declaration keys the assembly already reads.
|
|
128
|
+
def option_rows(node, filters: false)
|
|
129
|
+
return [] unless node.respond_to?(:extra_options_to_h)
|
|
130
|
+
|
|
131
|
+
spelled = node.extra_options_to_h
|
|
132
|
+
spelled = filter_options(node).merge(spelled) if filters
|
|
133
|
+
|
|
134
|
+
spelled.flat_map do |option, held|
|
|
135
|
+
case held
|
|
136
|
+
when Array then held.each_with_index.flat_map { |one, at| parts(option, one, at) }
|
|
137
|
+
else parts(option, held, nil)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def filter_options(node)
|
|
143
|
+
{
|
|
144
|
+
wheres: Array(node.wheres).map(&:to_h),
|
|
145
|
+
order_by: node.order_by&.to_h,
|
|
146
|
+
limit: node.limit&.to_h
|
|
147
|
+
}.reject { |_, held| held.nil? || held == [] }
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def parts(option, held, at)
|
|
151
|
+
Hash(held).map do |key, value|
|
|
152
|
+
{ option: option.to_s, key: key.to_s, value: value, at: at&.to_s }
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# A mutation is ONE declaration, but the language's Change holds a single
|
|
157
|
+
# field/kind/source triple — and an append binds SEVERAL fields at once
|
|
158
|
+
# (`append: { name: :name, amount: :amount }`). So an append is offered
|
|
159
|
+
# once per binding, and each one is judged.
|
|
160
|
+
#
|
|
161
|
+
# The judge used to send `field: v(""), kind: v("argument"), source: v("")`
|
|
162
|
+
# here — three stubbed values, so every rule about what a mutation reads
|
|
163
|
+
# was being handed a blank and could never refuse.
|
|
164
|
+
def mutation_rows(node)
|
|
165
|
+
Array(node.mutations).flat_map do |mutation|
|
|
166
|
+
# `:delegate`/`:corrects` (CommandBuilder#delegates_to's and
|
|
167
|
+
# #corrects_impl's own comments) ride the SAME multi-binding
|
|
168
|
+
# shape `:append` does — `with: {...}`/the assembled
|
|
169
|
+
# `as:`/`reason:`/`reverses:` hash is a field map, same as
|
|
170
|
+
# append's own `fields:`.
|
|
171
|
+
next set_row(mutation) unless [:append, :delegate, :corrects].include?(mutation.op)
|
|
172
|
+
|
|
173
|
+
mutation.source.map do |field, argument|
|
|
174
|
+
# Spelled the way Mutation#appended_fields spells it, because
|
|
175
|
+
# Assembly::Marks reads this row back through the same reader it
|
|
176
|
+
# reads that field with. `then_set :marks, append: { direction:
|
|
177
|
+
# "out" }` binds a LITERAL, and storing it raw made it
|
|
178
|
+
# indistinguishable from an argument called out.
|
|
179
|
+
{ target: mutation.target, op: mutation.op, field: field,
|
|
180
|
+
kind: argument.is_a?(Symbol) ? "argument" : "literal",
|
|
181
|
+
source: Literal.render(argument) }
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# A set/increment/decrement reads one thing: a command argument, or a
|
|
187
|
+
# literal written into the bluebook.
|
|
188
|
+
def set_row(mutation)
|
|
189
|
+
classified = mutation.to_h[:source] || {}
|
|
190
|
+
|
|
191
|
+
[{ target: mutation.target, op: mutation.op, field: mutation.target,
|
|
192
|
+
kind: classified[:kind],
|
|
193
|
+
source: classified[:name] || encode_literal(classified[:value]) }]
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# The normalisation table belongs to the expression grammar, not to any one
|
|
197
|
+
# bluebook — it is how the canonical form of a rule is spelled. The language
|
|
198
|
+
# models it because a bluebook's rules are canonicalised on the way in.
|
|
199
|
+
def normalisation_rows
|
|
200
|
+
table = Expression::CanonicalForm.table
|
|
201
|
+
return [] unless table
|
|
202
|
+
|
|
203
|
+
table.map do |entry|
|
|
204
|
+
{
|
|
205
|
+
strategy: entry[:strategy],
|
|
206
|
+
source_token: entry[:source_token],
|
|
207
|
+
replacement: entry[:replacement],
|
|
208
|
+
boundary: entry[:boundary],
|
|
209
|
+
position: entry[:position]
|
|
210
|
+
}
|
|
211
|
+
end
|
|
212
|
+
rescue StandardError
|
|
213
|
+
# The table is a convenience of the Ruby side ; a bluebook that cannot
|
|
214
|
+
# produce one is not malformed.
|
|
215
|
+
[]
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# What the BLUEBOOK calls a node, whichever kind of thing the node is.
|
|
219
|
+
#
|
|
220
|
+
# This used to sniff — `respond_to?(:hecks_name) ? … : node.name` — because
|
|
221
|
+
# only value objects had crossed over. Every construct answers now, so
|
|
222
|
+
# there is nothing to choose between. It disappears entirely when the DSL
|
|
223
|
+
# stops handing the judge nodes at all.
|
|
224
|
+
def declared_name(node) = node.hecks_name
|
|
225
|
+
|
|
226
|
+
# One field of a Declare payload. Mostly a reader of the same name — the
|
|
227
|
+
# exceptions are fields the IR keeps somewhere else, or not at all.
|
|
228
|
+
# READ FROM THE TABLE, not from a branch per category.
|
|
229
|
+
#
|
|
230
|
+
# These were eight hand-written cases — `Entity.owner`, `Member.shape`, two
|
|
231
|
+
# lifecycle members twice over, and three of a query's — each one restating
|
|
232
|
+
# something `Assembly::Contracts` already declares. A parent pointer is
|
|
233
|
+
# `:parent` there ; a folded field names the object and member it lives in.
|
|
234
|
+
# So the exceptions are looked up rather than repeated, and a new fold is one
|
|
235
|
+
# line in one file instead of two lines in two.
|
|
236
|
+
def field_value(category, node, field, parent_id)
|
|
237
|
+
return declared_name(node) if field == :name
|
|
238
|
+
|
|
239
|
+
contract = Assembly.contract(category)
|
|
240
|
+
# A setter names its target as a STRING and a Declare field arrives a Symbol,
|
|
241
|
+
# so the lookup keys on a Symbol either way. The case statement this replaced
|
|
242
|
+
# was type-blind because it interpolated ; a Hash is not.
|
|
243
|
+
named = field.to_sym
|
|
244
|
+
return parent_id if contract.kind_of(named) == :parent
|
|
245
|
+
|
|
246
|
+
object, member = contract.folded(named)
|
|
247
|
+
return through(node, object, member) if member
|
|
248
|
+
|
|
249
|
+
# `limit` is a language field AND an object in the IR — `Array(an_object)`
|
|
250
|
+
# wraps rather than destructures, so offering it stored
|
|
251
|
+
# "#<struct LimitSpec value=3>".
|
|
252
|
+
return node.limit&.to_h&.fetch(:value, nil) if "#{category}.#{field}" == "Query.limit"
|
|
253
|
+
|
|
254
|
+
# `provenance from: {...}` is a HASH offered into a text field, and
|
|
255
|
+
# handing it over raw let the runtime's own coercion spell it — which
|
|
256
|
+
# meant Ruby's `Hash#to_s`, whose spelling changed under us between
|
|
257
|
+
# 3.3 and 3.4. Encoded here, the same way `default:` already is and the
|
|
258
|
+
# same way Shapes#provenance reads it back.
|
|
259
|
+
return encode_literal(node.provenance) if field == :provenance
|
|
260
|
+
|
|
261
|
+
# `identified_by` is no longer a FIELD of any declaration — it is a list,
|
|
262
|
+
# filled by Identify one part at a time, so it is read through `identity_rows`
|
|
263
|
+
# like every other list rather than special-cased here. What this branch
|
|
264
|
+
# existed to protect is now structural : a path cannot come back as its head,
|
|
265
|
+
# because there is nowhere left that holds only a head.
|
|
266
|
+
|
|
267
|
+
node.respond_to?(field) ? node.public_send(field) : nil
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# One member of the object a field folds into. `to_h` first, because the
|
|
271
|
+
# member names are the ones the IR SPELLS — a Lifecycle's `default`, an
|
|
272
|
+
# OrderBy's `direction` — and reading the object raw is how a colon or a type
|
|
273
|
+
# goes missing.
|
|
274
|
+
def through(node, object, member)
|
|
275
|
+
held = node.respond_to?(object) ? node.public_send(object) : nil
|
|
276
|
+
return nil unless held
|
|
277
|
+
|
|
278
|
+
member == :transitions ? held : held.to_h[member]
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# What a setting command writes. A setter whose source is absent is not
|
|
282
|
+
# dispatched at all — ABSENT is not EMPTY, and offering "" would turn every
|
|
283
|
+
# "if you declare it, declare something" rule into "you must declare it".
|
|
284
|
+
def setter_value(category, node, target)
|
|
285
|
+
# `rows` folds into `closed_set` and `members` between them, with no single
|
|
286
|
+
# member to name, so it keeps its own reading — see Contract#folded.
|
|
287
|
+
return closed_set_size(node) if "#{category}.#{target}" == "ValueObject.rows"
|
|
288
|
+
|
|
289
|
+
object, member = Assembly.contract(category).folded(target.to_sym)
|
|
290
|
+
return through(node, object, member) if member
|
|
291
|
+
|
|
292
|
+
node.respond_to?(target) ? node.public_send(target) : nil
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
# Only a DECLARED closed set has a row count. An empty one is the defect,
|
|
296
|
+
# so `rows` must stay absent rather than arrive as zero.
|
|
297
|
+
def closed_set_size(node)
|
|
298
|
+
return nil unless node.respond_to?(:closed_set?) && node.closed_set?
|
|
299
|
+
|
|
300
|
+
Array(node.members).size
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# `Reference<Customer>` is an IR ENCODING, not a domain fact. The fact is
|
|
304
|
+
# that the attribute points at Customer's head — so the language is offered
|
|
305
|
+
# that head's ID, and resolution does the rest. Encoding and decoding both
|
|
306
|
+
# live here, because this is where the IR's shape differs from the
|
|
307
|
+
# language's and nowhere else should know the spelling.
|
|
308
|
+
def points_at(row, aggregate_id)
|
|
309
|
+
return nil unless row.reference?
|
|
310
|
+
|
|
311
|
+
# THE CHAPTER THIS HEAD IS IN, AND THE HEAD IT POINTS AT — which is exactly
|
|
312
|
+
# how an aggregate is identified, so it is built the same way rather than
|
|
313
|
+
# spelled again with a separator of its own. This is dispatched as a REAL
|
|
314
|
+
# REFERENCE VALUE (`Aggregate.Reference`'s `points_at:`), resolved by
|
|
315
|
+
# `repository.find` against the target Aggregate-within-Meta record's OWN
|
|
316
|
+
# stored id — so it MUST equal what that record's identity actually
|
|
317
|
+
# derives, not a wire-format spelling. `reference_type`, below, is the
|
|
318
|
+
# separate later reader that un-derives it back into "Reference<X>".
|
|
319
|
+
Naming.identity([aggregate_id.split(Naming::IDENTITY_JOIN).first, row.type.target_name])
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# A LITERAL, written so it can be read back exactly.
|
|
323
|
+
#
|
|
324
|
+
# The language holds a default and a literal mutation source as text, and
|
|
325
|
+
# `to_s` threw the type away: 0.0 came back "0.0", and `{ value: "good" }`
|
|
326
|
+
# came back its inspect string with nowhere to say it had been a hash. The
|
|
327
|
+
# language already stores code as text — `canonical: "cents >= 0"` — so an
|
|
328
|
+
# encoding is in keeping; it simply has to be SELF-DESCRIBING. That rule is
|
|
329
|
+
# now Hecks::Literal's, stated once and shared with every other
|
|
330
|
+
# to_h-bound literal field ; Shapes#decode_literal reads it back.
|
|
331
|
+
#
|
|
332
|
+
# nil stays nil rather than becoming "nil": absent is a real answer here,
|
|
333
|
+
# and the language's own field is optional.
|
|
334
|
+
def encode_literal(value) = value.nil? ? nil : Literal.render(value)
|
|
335
|
+
|
|
336
|
+
# The way back out: an aggregate id becomes the type the IR spells. The
|
|
337
|
+
# id is a JOIN of chapter + name (Naming::IDENTITY_JOIN, the same join
|
|
338
|
+
# `points_at` built it with, not the "::" a real bluebook's own type
|
|
339
|
+
# names never carry) ; the wire format wants only the bare name.
|
|
340
|
+
def reference_type(points_at_id) = "Reference<#{points_at_id.to_s.split(Naming::IDENTITY_JOIN).last}>"
|
|
341
|
+
|
|
342
|
+
# One value out of a row, named by the value object's field.
|
|
343
|
+
def row_value(row, field)
|
|
344
|
+
# A Hash FIRST. Hash answers to `key` (Hash#key(value)) and to `value` on
|
|
345
|
+
# some rows, so asking respond_to? before checking for a Hash reads a
|
|
346
|
+
# member pair through entirely the wrong method.
|
|
347
|
+
return row[field] if row.is_a?(Hash)
|
|
348
|
+
return row.public_send(field) if row.respond_to?(field)
|
|
349
|
+
# A Struct answers to [] but RAISES for a member it does not have, so it
|
|
350
|
+
# is read through to_h — a field the row simply lacks reads as absent.
|
|
351
|
+
return row.to_h[field] if row.respond_to?(:to_h) && !row.is_a?(String)
|
|
352
|
+
|
|
353
|
+
# A bare scalar row — `emits` is a list of event NAMES, and the
|
|
354
|
+
# Announcement value object has to call that string something.
|
|
355
|
+
row
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
end
|