@jetta/blocks-allocator 0.0.0-stage → 0.1.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/README.md +103 -2
- package/package.json +67 -5
- package/src/Allocation_Attempt.js +135 -0
- package/src/Allocation_Error_Handler.js +69 -0
- package/src/Allocation_Flow.js +162 -0
- package/src/Allocation_Optimization/Allocation_LP.js +150 -0
- package/src/Allocation_Optimization/Block_Allocator.js +129 -0
- package/src/Allocation_Optimization/Block_Layer_Order.js +50 -0
- package/src/Allocation_Optimization/Block_Potential_Weight.js +54 -0
- package/src/Allocation_Optimization/Chosen_Blocks_Stock_Cap.js +82 -0
- package/src/Allocation_Optimization/block_builder/Allocation_Item_Creator.js +37 -0
- package/src/Allocation_Optimization/block_builder/Block_Item_List_Validator.js +18 -0
- package/src/Allocation_Optimization/block_builder/Block_Wall_Builder.js +303 -0
- package/src/Allocation_Optimization/block_builder/Blocks_Builder.js +40 -0
- package/src/Allocation_Optimization/block_builder/Next_Block_Position.js +33 -0
- package/src/Allocation_Optimization/block_builder/Slot_Item_Assigner.js +45 -0
- package/src/Allocation_Optimization/block_builder/Stacking_Validation.js +30 -0
- package/src/Allocation_Optimization/block_builder/assert_tie_ratio_block_matches_orientation_below.js +44 -0
- package/src/Allocation_Optimization/block_builder/block_shape_stock.js +129 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Empty_Block_Item_List_Exception.js +21 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception.js +14 -0
- package/src/Allocation_Optimization/block_builder/exceptions/No_Suitable_Item_Exception.js +16 -0
- package/src/Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception.js +21 -0
- package/src/Allocation_Optimization/block_builder/should_omit_block_group_id.js +29 -0
- package/src/Allocation_Optimization/block_builder/snap_elevated_block_wall_items.js +34 -0
- package/src/Allocation_Optimization/block_builder/stacking_rules_input.js +52 -0
- package/src/Allocation_Optimization/cap_chosen_blocks_by_shape_stock.js +110 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Preparer.js +21 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Selector.js +55 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Threshold_Resolver.js +28 -0
- package/src/Allocation_Optimization/density_groups/Adaptive_Density_Group_Thresholds.js +23 -0
- package/src/Allocation_Optimization/density_groups/Container_Utilization.js +67 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Partitioner.js +74 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Scheduler.js +168 -0
- package/src/Allocation_Optimization/density_groups/Density_Group_Stock.js +49 -0
- package/src/Allocation_Optimization/density_groups/Density_Groups_Strategy.js +26 -0
- package/src/Allocation_Optimization/density_groups/Item_Density_Calculator.js +20 -0
- package/src/Allocation_Optimization/density_groups/Lock_Weight_Ahead_Release.js +75 -0
- package/src/Allocation_Optimization/exceptions/Invalid_Item_Amount_Exception.js +17 -0
- package/src/Allocation_Optimization/exceptions/No_Valid_Allocation_Exception.js +14 -0
- package/src/Allocation_Optimization/exceptions/Optimization_Infeasible_Exception.js +14 -0
- package/src/Allocation_Optimization/functions/Measure_Reader.js +20 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Mode.js +25 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Cobination_Strategies.js +8 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Measure_Combination_Mode_Checkers.js +70 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Translation.js +22 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/Variable_Weight_Getter.js +85 -0
- package/src/Allocation_Optimization/functions/Weight_Getter/constants.js +16 -0
- package/src/Allocation_Optimization/functions/measure_to_optimize.js +6 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Capacity_Bias_Item_Order.js +76 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Choose_Item_Heuristic_Context.js +63 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Item_Chooser.js +159 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Item_For_Slot_Chooser.js +49 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Slot_Compatible_Items_Finder.js +88 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Slots_Items_Assigner.js +182 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Stack_Slot_Calculator.js +87 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/Weight_Slot_Distribution.js +72 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Empty_Slot_Exception.js +17 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/Item_Taller_Than_Limit_Exception.js +21 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Available_Items_Exception.js +14 -0
- package/src/Allocation_Optimization/item_consumption_heuristic/exceptions/No_Slots_For_Items_Exception.js +14 -0
- package/src/Allocation_Optimization/lp_model/Block_Weight_Calculator.js +31 -0
- package/src/Allocation_Optimization/lp_model/LP_Data_Processor.js +42 -0
- package/src/Allocation_Optimization/lp_model/LP_Item_Slot_Assignment.js +93 -0
- package/src/Allocation_Optimization/lp_model/LP_Result_Mapper.js +47 -0
- package/src/Allocation_Optimization/lp_model/model_builder/Dimension_Range_Helper.js +49 -0
- package/src/Allocation_Optimization/lp_model/model_builder/Item_Assignment_Variables.js +133 -0
- package/src/Allocation_Optimization/lp_model/model_builder/LP_Model_Builder.js +132 -0
- package/src/Allocation_Optimization/lp_model/model_builder/exceptions/Missing_Item_Stock_Exception.js +18 -0
- package/src/Allocation_Optimization/lp_model/model_builder/goal_function/Goal_Function_Creator.js +83 -0
- package/src/Allocation_Optimization/lp_model/model_builder/item_dimension_hashes.js +31 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Block_Item_Amount_Restriction.js +53 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Coherence_Restriction.js +65 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Container_Supported_Weight_Restriction.js +42 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Exact_Pass_Amount_Restriction.js +62 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Relational_Group_Restriction.js +97 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Single_Item_Type_Restriction.js +79 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Space_Restriction.js +47 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Unavailable_Block_Restriction.js +27 -0
- package/src/Allocation_Optimization/lp_model/model_builder/restrictions/Uniform_Block_Measure_Restriction.js +92 -0
- package/src/Allocation_Optimization/next_group_id_after_preloaded.js +30 -0
- package/src/Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier.js +74 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/Key_Item_Mapper.js +49 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Almost_Unique_Item.js +31 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Cant_Stack_It_Self.js +68 -0
- package/src/Allocation_Optimization/preferential_blocks/key_item/rules/Rule_Interface.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Intercalation_State.js +49 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Orientation_Filter.js +33 -0
- package/src/Allocation_Optimization/tie_ratio/Tie_Ratio_Vertical_Stack_Filter.js +20 -0
- package/src/Allocation_Optimization/tie_ratio/collect_tie_ratio_orientations_below_footprint.js +64 -0
- package/src/Allocation_Optimization/tie_ratio/filter_blocks_by_orientation.js +17 -0
- package/src/Allocation_Optimization/tie_ratio/find_orientation_below_space.js +77 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/allocated_item_penetrates_any.js +31 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/apply_loose_placement_to_allocated_item.js +94 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/axis_overlap_length.js +16 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/block_local_origin.js +18 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/box_fits_inside_container.js +39 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_allocated_item_at_placement.js +18 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_placement_on_generic_supporter.js +64 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/build_slot_grid_from_cluster.js +66 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/compare_group_ids.js +20 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/container_with_pending_wall_items.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/empty_space_is_on_floor.js +16 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/finalize_loose_item_placement.js +58 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_best_generic_supporter_placement.js +58 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_next_free_slot_index.js +119 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_supporter_directly_below.js +51 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/find_tie_ratio_supporter_cluster.js +57 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/footprint_xz_overlap_area.js +26 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/item_fits_supporter_slot.js +22 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_footprint_region_from_options.js +24 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_fits_inside_container.js +21 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_item_has_geometric_support.js +21 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/loose_on_block_slot_state.js +88 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/placement_coords_fit_inside_container.js +34 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/read_empilhar_area_igual_from_allocation_item.js +12 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/realigned_loose_geometry_gates.js +25 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_on_generic_supporter.js +65 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_loose_placement_position.js +68 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_placement_y_at_slot.js +45 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/resolve_without_tie_ratio_cluster.js +79 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/select_tie_ratio_slot_placement.js +84 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/slot_footprint_collision.js +105 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_cluster_selection.js +119 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_footprint_overlap.js +56 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_placement_plane.js +109 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/tie_ratio_supporter_predicate.js +23 -0
- package/src/Allocation_Optimization/tie_ratio/loose_on_block/try_tie_ratio_slot_placement.js +62 -0
- package/src/Allocation_Optimization/tie_ratio/snap_stacked_items_to_floor_footprints.js +138 -0
- package/src/Allocation_Optimization/tie_ratio/supporters_by_top_y_index.js +78 -0
- package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_below_empty_space.js +89 -0
- package/src/Allocation_Optimization/tie_ratio/tie_ratio_orientation_from_group.js +48 -0
- package/src/Block_Management.js +34 -0
- package/src/Blocks_Preparation/Cube_Map_Function.js +27 -0
- package/src/Blocks_Wall_Allocation.js +3 -0
- package/src/IO/Answer_Status.js +4 -0
- package/src/IO/Output_Builder.js +35 -0
- package/src/IO/count_allocated_items.js +31 -0
- package/src/IO/create_error_response.js +62 -0
- package/src/IO/format_allocation_error_message.js +25 -0
- package/src/Item_Continuation_Lock.js +129 -0
- package/src/Item_Picking_Continuity.js +41 -0
- package/src/allocation_flow/chooser_session_state.js +21 -0
- package/src/allocation_flow/compound_probe_fallback.js +17 -0
- package/src/allocation_flow/container_remaining_capacity.js +23 -0
- package/src/allocation_flow/density_group_item_filter.js +31 -0
- package/src/allocation_flow/effective_item_fingerprint.js +14 -0
- package/src/allocation_flow/item_continuation_lock_gate.js +38 -0
- package/src/allocation_flow/no_space_left_recovery.js +48 -0
- package/src/allocation_flow/run_allocation_iteration.js +155 -0
- package/src/allocation_flow/space_skip_state.js +91 -0
- package/src/allocation_flow/try_no_space_left_recovery.js +50 -0
- package/src/exceptions/Invalid_Parameter_Exception.js +17 -0
- package/src/exceptions/Relational_Allocation_Incomplete_Exception.js +24 -0
- package/src/exceptions/Relational_Colocation_Violation_Exception.js +23 -0
- package/src/exceptions/Relational_Config_Mismatch_Exception.js +17 -0
- package/src/exceptions/There_Is_No_Block_Options_To_Allocate_Exception.js +14 -0
- package/src/index.js +6 -0
- package/src/input_preparation/Block_Formatter.js +179 -0
- package/src/input_preparation/Input_Creator.js +76 -0
- package/src/input_preparation/Input_State_Preparation.js +47 -0
- package/src/input_preparation/State_Builder.js +27 -0
- package/src/input_preparation/block_formatter/align_flush_axis_config.js +36 -0
- package/src/input_preparation/block_formatter/align_flush_axis_single_round.js +112 -0
- package/src/input_preparation/block_formatter/align_flush_stacked_slots.js +67 -0
- package/src/input_preparation/block_formatter/overlapped_slots.js +24 -0
- package/src/input_preparation/block_formatter/parallelepiped_shell.js +38 -0
- package/src/input_preparation/block_formatter/rectangle_coverage.js +112 -0
- package/src/input_preparation/block_formatter/shell_face_coverage.js +64 -0
- package/src/input_preparation/block_formatter/shell_snap_convergence.js +104 -0
- package/src/input_preparation/block_preparation/Block_Data_To_Object_Transformer.js +57 -0
- package/src/input_preparation/block_preparation/Block_Module_Name.js +17 -0
- package/src/input_preparation/block_preparation/Blocks_Creator.js +101 -0
- package/src/input_preparation/block_preparation/Blocksmith.js +19 -0
- package/src/input_preparation/block_preparation/block_modules/create_block_candidates.js +41 -0
- package/src/input_preparation/block_preparation/block_modules/manual_blocks.js +10 -0
- package/src/input_preparation/block_preparation/block_modules/module_registry.js +20 -0
- package/src/input_preparation/block_preparation/block_modules/run_creator.js +34 -0
- package/src/input_preparation/block_preparation/block_modules/single_item_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/spiral_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/tie_ratio_blocks.js +12 -0
- package/src/input_preparation/block_preparation/block_modules/tower_blocks.js +12 -0
- package/src/input_preparation/block_preparation/exceptions/Failed_To_Create_Block_Exception.js +14 -0
- package/src/input_preparation/block_preparation/exceptions/Failed_To_Retrieve_Block_Exception.js +17 -0
- package/src/input_preparation/block_preparation/exceptions/Missing_Object_Store_Exception.js +10 -0
- package/src/input_preparation/block_preparation/exceptions/No_Blocks_Were_Created_Exception.js +14 -0
- package/src/input_preparation/block_preparation/input/Input_Creator.js +96 -0
- package/src/input_preparation/block_preparation/manual_blocks/Manual_Blocks.js +95 -0
- package/src/input_preparation/build_empty_space_finder_options.js +43 -0
- package/src/input_preparation/item_preparation/Items_Reader.js +27 -0
- package/src/input_preparation/min_extents_from_items.js +29 -0
- package/src/input_preparation/stackability_index/Blocks_Stackability_Index_Calculator.js +58 -0
- package/src/input_preparation/stackability_index/Slots_Stackability_index_Calculator.js +28 -0
- package/src/input_preparation/stackability_index/Stackability_Input_Creator.js +27 -0
- package/src/input_preparation/stackability_index/stackability_index_pop_stack.js +81 -0
- package/src/input_preparation/stacking_constraints/Weight_Stacking_Validation.js +15 -0
- package/src/lp_optimizer_result_status.js +20 -0
- package/src/messages/Allocator_Message.js +42 -0
- package/src/messages/resolve_error_message_entry.js +57 -0
- package/src/models/Allocated_Item.js +136 -0
- package/src/models/Allocation_Item.js +219 -0
- package/src/models/Block.js +198 -0
- package/src/models/Cargo_Profile.js +418 -0
- package/src/models/Preloaded_Allocated_Item.js +132 -0
- package/src/models/Slot.js +67 -0
- package/src/models/Stacking_Rules.js +58 -0
- package/src/models/auxiliaryFunctions/Available_Block_Module_List_Creator.js +9 -0
- package/src/models/auxiliaryFunctions/Measure_Translator.js +24 -0
- package/src/models/auxiliaryFunctions/item_json_reader.js +44 -0
- package/src/models/item_json_reader.js +71 -0
- package/src/models/placed_item_record.js +70 -0
- package/src/models/preloaded_rotation_helpers.js +38 -0
- package/src/models/slots_have_same_measure.js +45 -0
- package/src/models/transport/Container.js +162 -0
- package/src/models/transport/Transport.js +62 -0
- package/src/models/transport/build_stacking_feasibility_checker.js +64 -0
- package/src/models/transport/container_stacking_checkpoint.js +42 -0
- package/src/models/transport/factory/Container_Factory.js +46 -0
- package/src/models/transport/factory/Corner_Casting_Factory.js +62 -0
- package/src/models/transport/factory/Previously_Allocated_Item_Factory.js +28 -0
- package/src/models/transport/factory/Transport_Factory.js +13 -0
- package/src/models/transport/items_for_empty_space_finder.js +91 -0
- package/src/models/transport/resolve_container_stacking_inputs.js +23 -0
- package/src/models/transport/stacking_input_from_wire.js +58 -0
- package/src/optimizer_connection_errors.js +50 -0
- package/src/relational/Relational_Error_Codes.js +7 -0
- package/src/relational/finalize_relational_allocation.js +20 -0
- package/src/relational/has_relational_items.js +11 -0
- package/src/relational/is_relational_error_code.js +15 -0
- package/src/relational/resolve_relational_container_sequences.js +29 -0
- package/src/run_core_allocation.js +118 -0
- package/src/space_and_block_chooser/Space_And_Blocks_Chooser.js +115 -0
- package/src/space_and_block_chooser/blocks_filters/Block_Filter_Interface.js +19 -0
- package/src/space_and_block_chooser/blocks_filters/Filter_Runner.js +46 -0
- package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Block_With_Overlapped_Slots_Filter.js +14 -0
- package/src/space_and_block_chooser/blocks_filters/initial_blocks_filter/Initial_Blocks_Filter_List.js +19 -0
- package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Blocks_Bigger_Than_Space_Filter.js +17 -0
- package/src/space_and_block_chooser/blocks_filters/pos_selection_filters/Post_Selection_Filter_List.js +9 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Insuficient_Items_Filter.js +81 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/Pre_Selection_Filter_List.js +8 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Blocks_Lower_Than_Max_Tower_Height.js +23 -0
- package/src/space_and_block_chooser/blocks_filters/pre_selection_filter/max_tower_height/Max_Tower_Height.js +82 -0
- package/src/space_and_block_chooser/build_allocated_item_snapshots.js +19 -0
- package/src/space_and_block_chooser/compound_first_empty_space_branch.js +61 -0
- package/src/space_and_block_chooser/compound_first_with_leftover_fill.js +142 -0
- package/src/space_and_block_chooser/compound_first_without_leftover_fill.js +56 -0
- package/src/space_and_block_chooser/empty_spaces_where_post_selection_keeps_blocks.js +83 -0
- package/src/space_and_block_chooser/exceptions/Invalid_Space_To_Allocate_Exception.js +14 -0
- package/src/space_and_block_chooser/leftover_space_memory.js +113 -0
- package/src/space_and_block_chooser/leftover_unitary_blocks.js +153 -0
- package/src/space_and_block_chooser/leftover_unitary_empty_spaces.js +135 -0
- package/src/space_and_block_chooser/probe_set_pool.js +35 -0
- package/src/space_and_block_chooser/run_space_and_block_selection_attempt.js +88 -0
- package/src/tools/Array_Validator.js +6 -0
- package/src/tools/Clone.js +27 -0
- package/src/tools/Hash.js +8 -0
- package/src/tools/Rounder.js +5 -0
- package/src/tools/String_To_Boolean.js +12 -0
- package/src/tools/cargo_profile/Cargo_Profile_Field_Value_Resolver.js +44 -0
- package/src/tools/compact_items_with_stock.js +9 -0
- package/src/tools/mm_to_allocation_domain.js +14 -0
- package/src/tracing/Allocation_Tracer.js +52 -0
- package/src/tracing/Trace_Context.js +18 -0
- package/src/tracing/trace_outcome.js +18 -0
- package/src/tracing/traced_step.js +57 -0
- package/src/validation/Item_Continuation_Lock_Flag.js +52 -0
- package/src/validation/Item_Validation.js +29 -0
- package/src/validation/Relational_Colocation_Validator.js +60 -0
- package/src/validation/Relational_Completeness_Validator.js +146 -0
- package/src/validation/Relational_Continuation_Lock_Validation.js +37 -0
- package/src/validation/Relational_Proportional_Normalizer.js +194 -0
- package/src/validation/Validation.js +9 -0
- package/src/validation/Validation_Runner.js +20 -0
- package/src/validation/exceptions/Invalid_Block_Module_Config_Exception.js +14 -0
- package/src/validation/exceptions/Invalid_Input_Exception.js +14 -0
- package/src/validation/exceptions/Invalid_Input_Type_Exception.js +14 -0
- package/src/validation/schemas/allocated_item_schema.js +18 -0
- package/src/validation/schemas/allocation_request_schema.js +178 -0
- package/src/validation/schemas/container_row_schema.js +16 -0
- package/src/validation/schemas/item_schema.js +60 -0
- package/src/validation/schemas/transport_env_schema.js +19 -0
- package/src/validation/validate_block_module_config.js +147 -0
package/README.md
CHANGED
|
@@ -1,3 +1,104 @@
|
|
|
1
|
-
# Temporary Holding Version
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
# @jetta/blocks-allocator
|
|
3
|
+
|
|
4
|
+
Library that allocates items into pre-assembled block structures. Queue and Temporal communication live in `blocks-wall-allocation`. This package exposes `run_core_allocation`.
|
|
5
|
+
|
|
6
|
+
## Requirements
|
|
7
|
+
|
|
8
|
+
- Node.js 24+
|
|
9
|
+
- npm
|
|
10
|
+
- A reachable optimizer for live allocation (`NATS_SERVERS`). Tests mock the optimizer in process.
|
|
11
|
+
|
|
12
|
+
## How to install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @jetta/blocks-allocator
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Local development:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Scripts
|
|
25
|
+
|
|
26
|
+
| Command | Description |
|
|
27
|
+
|---------|-------------|
|
|
28
|
+
| `npm test` | Mocha tests |
|
|
29
|
+
| `npm run lint` | ESLint |
|
|
30
|
+
| `npm run lint:package` | publint strict check of the packed tarball |
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
const run_core_allocation = require('@jetta/blocks-allocator')
|
|
36
|
+
|
|
37
|
+
const output = await run_core_allocation(request, {
|
|
38
|
+
object_store: {
|
|
39
|
+
get_object(bucket_name, object_key)
|
|
40
|
+
{
|
|
41
|
+
return object_store_driver.get_object(bucket_name, object_key)
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
tracer
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
`object_store` is required only when manual blocks are enabled. `tracer` is optional. Without it, allocation still runs and tracing steps are skipped.
|
|
49
|
+
|
|
50
|
+
`run_core_allocation.resolve_trace_id(request)` resolves the id the service should pass to its tracer.
|
|
51
|
+
|
|
52
|
+
## Dependencies
|
|
53
|
+
|
|
54
|
+
Algorithm libraries: `@jetta/lp-framework`, `@jetta/empty-spaces-manager`, `@jetta/number-compare`, `@jetta/stacking-constraints`, the block-creator packages, `@jettacargo/stackability-index-calculator-core@1.0.4`, `@jetta/item-amount-controller`, and `zod`.
|
|
55
|
+
|
|
56
|
+
## Env Variables
|
|
57
|
+
|
|
58
|
+
`NATS_SERVERS` : NATS URL(s) for optimizer request-reply (required for a live run)
|
|
59
|
+
`OPTIMIZER_NATS_SUBJECT` : subject (default `optimizer.optimize`; dig uses `optimizer.dev.optimize`)
|
|
60
|
+
`OPTIMIZER_NATS_TIMEOUT_MS` : request timeout ms (default 300000; covers dig scale-from-zero)
|
|
61
|
+
`MANUAL_BLOCKS_BUCKET_NAME` : bucket passed to `object_store.get_object` when manual blocks are loaded
|
|
62
|
+
|
|
63
|
+
## External Dependencies
|
|
64
|
+
- optimizer NATS worker (`python-optimizer-nats-{ENV}`) + JetStream stream/consumer
|
|
65
|
+
- NATS: `nats://nats.nats.svc.cluster.local:4222`
|
|
66
|
+
|
|
67
|
+
## Supported Cargo Profile Options
|
|
68
|
+
- allocation.blocks.use_unitary_items_as_block
|
|
69
|
+
- enable the use of individual items as a possible blocks
|
|
70
|
+
- deafult: false
|
|
71
|
+
- allocation.optimization.enable_blocks_extra_score
|
|
72
|
+
- gives a extra score to non individual item blocks on LP optimization
|
|
73
|
+
- deafult: false
|
|
74
|
+
- allocation.optimization.measure_to_optimize
|
|
75
|
+
- "width" of "length", used to set which dimension is optimized
|
|
76
|
+
- deafult: "width"
|
|
77
|
+
- allocation.stacking.enable_stacking_constraints_service
|
|
78
|
+
- enables stacking rules
|
|
79
|
+
- deafult: true
|
|
80
|
+
- allocation.empty_space.chooser.score_strategy_criterias
|
|
81
|
+
- empty space chooser score criterias
|
|
82
|
+
- allocation.empty_space.chooser.enable_full_containes_removal
|
|
83
|
+
- when enabled, the chooser will disconsider all sub containers that is fully contained in other
|
|
84
|
+
|
|
85
|
+
## Empty-space merge tolerance (optional `config.algoritmo`)
|
|
86
|
+
|
|
87
|
+
Optional keys on `config.algoritmo` (validated at parse time), alongside other cargo profile keys. In the empty-space model, **width** is axis **X** and **length** is axis **Z** (same as `Space.width` / `Space.length` in `@jetta/empty-spaces-manager`).
|
|
88
|
+
|
|
89
|
+
- `empty_space_merge_gap_percent_width` (0–100): max horizontal merge gap along **width** (X), as a percent of the smallest item **width** over all rotations.
|
|
90
|
+
- `empty_space_merge_gap_percent_length` (0–100): same for **length** (Z).
|
|
91
|
+
- `empty_space_merge_max_vertical_offset_mm` (≥ 0): max vertical gap in **millimeters** for merging stacked empty regions with overlapping floor projection; absent or `0` disables this merge. Internal geometry uses the same numeric unit as container/item dimensions (typically mm), so the value is rounded into that domain.
|
|
92
|
+
|
|
93
|
+
Omit the keys or set them to `0` for the previous strict merge behavior.
|
|
94
|
+
|
|
95
|
+
The same spacing rules are implemented in `@jetta/empty-spaces-manager` as pure APIs (`merge_tolerance_from_operational_gaps`, `horizontal_epsilon_from_gap_percent`) so any allocator can pass **numbers only** (`OperationalMergeGaps` + `RotationMinExtents`) without duplicating formulas.
|
|
96
|
+
|
|
97
|
+
## Fluxos do agente
|
|
98
|
+
|
|
99
|
+
Notas de feature em [.cursor/ai_changelog/INDEX.md](.cursor/ai_changelog/INDEX.md).
|
|
100
|
+
|
|
101
|
+
| Invocação | Skill | Saída |
|
|
102
|
+
|-----------|-------|-------|
|
|
103
|
+
| `KB: JET-XXXX` | `document-feature-knowledge` | Doc em `.cursor/ai_changelog/` |
|
|
104
|
+
| `PR: JET-XXXX` | `create-pr-description` | Rascunho de título e corpo de PR (chat) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,68 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@jetta/blocks-allocator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Blocks wall allocation library",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"private": false,
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"audit": "npm audit --omit=dev",
|
|
18
|
+
"preversion": "git fetch --prune --tags",
|
|
19
|
+
"version": "npm run lint && npm run lint:package",
|
|
20
|
+
"prepack": "npm run lint && npm run lint:package",
|
|
21
|
+
"postversion": "git push origin HEAD --follow-tags",
|
|
22
|
+
"publish:alpha": "npm version --tag-version-prefix=alpha-v",
|
|
23
|
+
"publish:stable": "npm version",
|
|
24
|
+
"prerelease:alpha": "npm version prerelease --tag-version-prefix=alpha-v",
|
|
25
|
+
"prerelease:alpha:minor": "npm version preminor --tag-version-prefix=alpha-v",
|
|
26
|
+
"prerelease:alpha:major": "npm version premajor --tag-version-prefix=alpha-v",
|
|
27
|
+
"test": "npx mocha --require test/mocha_setup.js --recursive 2>&1",
|
|
28
|
+
"test:verbose": "npx mocha --require test/mocha_setup_verbose.js --recursive 2>&1",
|
|
29
|
+
"lint": "eslint .",
|
|
30
|
+
"lint:fix": "eslint . --fix",
|
|
31
|
+
"lint:package": "publint --strict --pack npm",
|
|
32
|
+
"memory:profile": "node debug/memory_profile.js",
|
|
33
|
+
"generate:block-modules-goldens": "node scripts/generate_block_modules_compatibility_goldens.js",
|
|
34
|
+
"perf": "node scripts/allocation_perf_runner.js"
|
|
35
|
+
},
|
|
36
|
+
"type": "commonjs",
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=24"
|
|
39
|
+
},
|
|
40
|
+
"author": "",
|
|
41
|
+
"license": "ISC",
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@jetta/empty-spaces-manager": "^0.1.1-0",
|
|
44
|
+
"@jetta/item-amount-controller": "0.1.0-0",
|
|
45
|
+
"@jetta/logger": "^2.0.1",
|
|
46
|
+
"@jetta/lp-framework": "2.1.0-6",
|
|
47
|
+
"@jetta/number-compare": "^3.0.2-4",
|
|
48
|
+
"@jetta/stacking-constraints": "^1.1.0",
|
|
49
|
+
"@jetta/tie-ratio-block-creator-core": "1.2.2-3",
|
|
50
|
+
"@jetta/z-intersected-block-creator": "^0.0.1-42",
|
|
51
|
+
"@jettacargo/single-item-block-creator-core": "2.0.1-0",
|
|
52
|
+
"@jettacargo/spiral-block-creator-core": "2.1.2",
|
|
53
|
+
"@jettacargo/stackability-index-calculator-core": "1.0.4",
|
|
54
|
+
"@jettacargo/tower-block-creator-core": "3.0.0-3",
|
|
55
|
+
"zod": "^4.4.3"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"chai": "^6.2.2",
|
|
59
|
+
"chai-as-promised": "^8.0.2",
|
|
60
|
+
"dotenv": "^17.4.2",
|
|
61
|
+
"eslint": "^10.3.0",
|
|
62
|
+
"eslint-plugin-promise": "^7.3.0",
|
|
63
|
+
"mocha": "^11.7.5",
|
|
64
|
+
"proxyquire": "^2.1.3",
|
|
65
|
+
"publint": "^0.3.25",
|
|
66
|
+
"sinon": "^22.0.0"
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const { Item_Amount_Controller } = require('@jetta/item-amount-controller')
|
|
2
|
+
const compact_items_with_stock = require('./tools/compact_items_with_stock')
|
|
3
|
+
const { handle_attempt_exception } = require('./Allocation_Error_Handler')
|
|
4
|
+
const Block_Allocator = require('./Allocation_Optimization/Block_Allocator')
|
|
5
|
+
const {Logger} = require('@jetta/logger')
|
|
6
|
+
const logger = new Logger('Allocation Attempt')
|
|
7
|
+
const { mark_trace_outcome } = require('./tracing/trace_outcome')
|
|
8
|
+
const { TRACE_CONTEXT } = require('./tracing/Trace_Context')
|
|
9
|
+
|
|
10
|
+
function empty_wall_output()
|
|
11
|
+
{
|
|
12
|
+
return {
|
|
13
|
+
single_slot_allocated_item_ids: new Set(),
|
|
14
|
+
last_allocated_item_id: null,
|
|
15
|
+
placed_tie_ratio_block: false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
class Allocation_Attempt
|
|
20
|
+
{
|
|
21
|
+
#attempt_id = 0
|
|
22
|
+
#item_list
|
|
23
|
+
#amount_controller
|
|
24
|
+
#allocator
|
|
25
|
+
|
|
26
|
+
constructor(input_state)
|
|
27
|
+
{
|
|
28
|
+
this.#item_list = input_state.items_to_allocate
|
|
29
|
+
this.#amount_controller = new Item_Amount_Controller(input_state.items_to_allocate)
|
|
30
|
+
this.#allocator = new Block_Allocator()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Attempts allocation on the chosen space, retrying with reduced block options on recoverable failures.
|
|
35
|
+
* @param {object[]} block_list - Candidate blocks for the chosen space.
|
|
36
|
+
* @param {object} space_to_allocate - Empty space selected by the chooser.
|
|
37
|
+
* @param {Record<string, number>} block_amount_map - Block amount restrictions updated on failures.
|
|
38
|
+
* @param {object} container - Current transport container.
|
|
39
|
+
* @param {object[]} effective_item_list - Items exposed to the LP for this iteration.
|
|
40
|
+
* @param {string|null} picking_continuity_seed - Last allocated SKU id from the prior wall.
|
|
41
|
+
* @returns {Promise<object>} Wall output ids for continuation hooks.
|
|
42
|
+
*/
|
|
43
|
+
async try_to_allocate(
|
|
44
|
+
block_list,
|
|
45
|
+
space_to_allocate,
|
|
46
|
+
block_amount_map,
|
|
47
|
+
container,
|
|
48
|
+
effective_item_list,
|
|
49
|
+
picking_continuity_seed
|
|
50
|
+
)
|
|
51
|
+
{
|
|
52
|
+
let wall_output = empty_wall_output()
|
|
53
|
+
while (block_list.length > 0)
|
|
54
|
+
{
|
|
55
|
+
try
|
|
56
|
+
{
|
|
57
|
+
wall_output = await this.#allocation_attempt(
|
|
58
|
+
container,
|
|
59
|
+
space_to_allocate,
|
|
60
|
+
block_list,
|
|
61
|
+
block_amount_map,
|
|
62
|
+
effective_item_list,
|
|
63
|
+
picking_continuity_seed
|
|
64
|
+
)
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
catch (exception)
|
|
68
|
+
{
|
|
69
|
+
container.discard_provisional_stackings()
|
|
70
|
+
const keep_trying = handle_attempt_exception(exception, block_list, block_amount_map)
|
|
71
|
+
if (!keep_trying)
|
|
72
|
+
{
|
|
73
|
+
break
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return wall_output
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
#update_item_amount(allocated_items)
|
|
81
|
+
{
|
|
82
|
+
this.#amount_controller.discount_item_list( allocated_items )
|
|
83
|
+
this.#amount_controller.update_item_list_amount( this.#item_list )
|
|
84
|
+
this.#item_list = compact_items_with_stock(this.#item_list)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async #allocation_attempt(
|
|
88
|
+
container,
|
|
89
|
+
space_to_allocate,
|
|
90
|
+
avaiable_usable_blocks,
|
|
91
|
+
block_amount_map,
|
|
92
|
+
effective_item_list,
|
|
93
|
+
picking_continuity_seed
|
|
94
|
+
)
|
|
95
|
+
{
|
|
96
|
+
const attempt = this.#attempt_id++
|
|
97
|
+
logger.debug('allocation attempt ' + attempt)
|
|
98
|
+
const allocation_output = await this.#allocator.optimize_and_allocate(
|
|
99
|
+
container,
|
|
100
|
+
space_to_allocate,
|
|
101
|
+
avaiable_usable_blocks,
|
|
102
|
+
this.#amount_controller,
|
|
103
|
+
this.#item_list,
|
|
104
|
+
block_amount_map,
|
|
105
|
+
effective_item_list,
|
|
106
|
+
picking_continuity_seed
|
|
107
|
+
)
|
|
108
|
+
this.#update_state(container, allocation_output)
|
|
109
|
+
mark_trace_outcome(TRACE_CONTEXT.BLOCK_WALL_ALLOCATED)
|
|
110
|
+
logger.debug('wall allocated, going to the next wall...')
|
|
111
|
+
return {
|
|
112
|
+
single_slot_allocated_item_ids: allocation_output.single_slot_allocated_item_ids ?? new Set(),
|
|
113
|
+
last_allocated_item_id: allocation_output.last_allocated_item_id ?? null,
|
|
114
|
+
placed_tie_ratio_block: allocation_output.placed_tie_ratio_block ?? false
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#update_state(container, allocation_output)
|
|
119
|
+
{
|
|
120
|
+
container.find_empty_spaces(allocation_output.item_to_find_space_list)
|
|
121
|
+
const existing_items = new Set(container.get_allocated_items())
|
|
122
|
+
const items_to_merge = allocation_output.allocated_item_list.filter(
|
|
123
|
+
item => !existing_items.has(item)
|
|
124
|
+
)
|
|
125
|
+
container.merge_item_list(items_to_merge)
|
|
126
|
+
this.#update_item_amount(allocation_output.allocated_item_list)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get_attempt_id()
|
|
130
|
+
{
|
|
131
|
+
return this.#attempt_id
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
module.exports = Allocation_Attempt
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
const {NoSpaceLeftException} = require('@jetta/empty-spaces-manager')
|
|
2
|
+
const There_Is_No_Block_Options_To_Allocate_Exception = require('./exceptions/There_Is_No_Block_Options_To_Allocate_Exception')
|
|
3
|
+
const Optimization_Infeasible_Exception = require('./Allocation_Optimization/exceptions/Optimization_Infeasible_Exception')
|
|
4
|
+
const Restricted_Block_Exception = require('./Allocation_Optimization/block_builder/exceptions/Restricted_Block_Exception')
|
|
5
|
+
const { restrict_block, clean_blocks_restricted_to_0 } = require('./Block_Management')
|
|
6
|
+
const No_Valid_Allocation_Exception = require('./Allocation_Optimization/exceptions/No_Valid_Allocation_Exception')
|
|
7
|
+
const Invalid_Stacking_Exception = require('./Allocation_Optimization/block_builder/exceptions/Invalid_Stacking_Exception')
|
|
8
|
+
const {Logger} = require('@jetta/logger')
|
|
9
|
+
const logger = new Logger('Allocation Attempt Error Handler')
|
|
10
|
+
const { mark_trace_outcome } = require('./tracing/trace_outcome')
|
|
11
|
+
const { TRACE_CONTEXT } = require('./tracing/Trace_Context')
|
|
12
|
+
|
|
13
|
+
function handle_attempt_exception(exception, block_list, block_amount_restrictions)
|
|
14
|
+
{
|
|
15
|
+
if (exception instanceof Invalid_Stacking_Exception)
|
|
16
|
+
{
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (exception instanceof Restricted_Block_Exception)
|
|
21
|
+
{
|
|
22
|
+
restrict_block(exception, block_amount_restrictions)
|
|
23
|
+
clean_blocks_restricted_to_0(block_list, block_amount_restrictions)
|
|
24
|
+
logger.warn(JSON.stringify(exception.block_to_restrict))
|
|
25
|
+
const restricted_block_list = Object.keys(block_amount_restrictions)
|
|
26
|
+
const has_non_restricted_block = block_list.some(block => !restricted_block_list.includes(block.get_id()))
|
|
27
|
+
if (has_non_restricted_block)
|
|
28
|
+
{
|
|
29
|
+
mark_trace_outcome(TRACE_CONTEXT.BLOCK_WALL_RETRY_OTHER_BLOCKS)
|
|
30
|
+
}
|
|
31
|
+
return has_non_restricted_block
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (exception instanceof Optimization_Infeasible_Exception || exception instanceof No_Valid_Allocation_Exception)
|
|
35
|
+
{
|
|
36
|
+
logger.warn('Optimization_Infeasible_Exception')
|
|
37
|
+
return false // não tem mais o que fazer
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
logger.error(exception.message)
|
|
41
|
+
throw exception // erro inesperado, propaga
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function handle_allocation_exception(exception, attempt_id)
|
|
45
|
+
{
|
|
46
|
+
if (can_continue_allocation(exception))
|
|
47
|
+
{
|
|
48
|
+
logger.warn('choosen space can\'t fit any of the possible blocks => attempt id ' + attempt_id)
|
|
49
|
+
return true // ainda vamos tentar
|
|
50
|
+
}
|
|
51
|
+
if (exception instanceof NoSpaceLeftException)
|
|
52
|
+
{
|
|
53
|
+
logger.warn('no space left => attempt id ' + attempt_id)
|
|
54
|
+
mark_trace_outcome(TRACE_CONTEXT.BLOCK_WALL_SPACE_EXHAUSTED)
|
|
55
|
+
return false // não tem mais o que fazer
|
|
56
|
+
}
|
|
57
|
+
logger.error(exception.message)
|
|
58
|
+
throw exception // erro inesperado, propaga
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function can_continue_allocation(error)
|
|
62
|
+
{
|
|
63
|
+
const is_invalid_stacking = error instanceof Invalid_Stacking_Exception
|
|
64
|
+
const does_not_have_block_for_space = error instanceof There_Is_No_Block_Options_To_Allocate_Exception
|
|
65
|
+
return is_invalid_stacking || does_not_have_block_for_space
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
module.exports = {handle_attempt_exception,handle_allocation_exception}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
const { handle_allocation_exception } = require('./Allocation_Error_Handler')
|
|
2
|
+
const Allocation_Attempt = require('./Allocation_Attempt')
|
|
3
|
+
const Preferential_Block_Identifier = require('./Allocation_Optimization/preferential_blocks/Preferential_Block_Identifier')
|
|
4
|
+
const Item_Continuation_Lock = require('./Item_Continuation_Lock')
|
|
5
|
+
const Item_Picking_Continuity = require('./Item_Picking_Continuity')
|
|
6
|
+
const { create_density_group_scheduler } = require('./Allocation_Optimization/density_groups/Density_Group_Scheduler')
|
|
7
|
+
const Space_Skip_State = require('./allocation_flow/space_skip_state')
|
|
8
|
+
const { create_chooser_session_state } = require('./allocation_flow/chooser_session_state')
|
|
9
|
+
const { run_allocation_iteration } = require('./allocation_flow/run_allocation_iteration')
|
|
10
|
+
const { try_no_space_left_recovery } = require('./allocation_flow/try_no_space_left_recovery')
|
|
11
|
+
const { remaining_items_fit_container } = require('./allocation_flow/container_remaining_capacity')
|
|
12
|
+
const {Logger} = require('@jetta/logger')
|
|
13
|
+
const logger = new Logger('Allocation Flow')
|
|
14
|
+
const Cargo_Profile = require('./models/Cargo_Profile')
|
|
15
|
+
const { validate_transport_colocation } = require('./validation/Relational_Colocation_Validator')
|
|
16
|
+
const { validate_relational_completeness } = require('./validation/Relational_Completeness_Validator')
|
|
17
|
+
const {
|
|
18
|
+
normalize_relational_proportional_allocation
|
|
19
|
+
} = require('./validation/Relational_Proportional_Normalizer')
|
|
20
|
+
const has_relational_items = require('./relational/has_relational_items')
|
|
21
|
+
const { traced_step } = require('./tracing/traced_step')
|
|
22
|
+
const { TRACE_CONTEXT } = require('./tracing/Trace_Context')
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Orchestrates allocation over each container in order until items are exhausted or the loop stops.
|
|
26
|
+
*/
|
|
27
|
+
class Allocation_flow
|
|
28
|
+
{
|
|
29
|
+
#transport
|
|
30
|
+
#block_list
|
|
31
|
+
#item_list
|
|
32
|
+
#preferential_block_identifier
|
|
33
|
+
#space_skip_state = new Space_Skip_State()
|
|
34
|
+
#chooser_session = create_chooser_session_state()
|
|
35
|
+
#allocation_attempt
|
|
36
|
+
#item_lock = new Item_Continuation_Lock()
|
|
37
|
+
#picking_continuity = new Item_Picking_Continuity()
|
|
38
|
+
#density_scheduler = null
|
|
39
|
+
#recovery_state = { count: 0 }
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param {object} input_state - Prepared input: `transport`, `items_to_allocate`, `blocks`.
|
|
43
|
+
*/
|
|
44
|
+
constructor(input_state)
|
|
45
|
+
{
|
|
46
|
+
this.#transport = input_state.transport
|
|
47
|
+
this.#item_list = input_state.items_to_allocate
|
|
48
|
+
this.#block_list = input_state.blocks
|
|
49
|
+
this.#preferential_block_identifier = new Preferential_Block_Identifier(this.#transport, this.#item_list)
|
|
50
|
+
this.#allocation_attempt = new Allocation_Attempt(input_state)
|
|
51
|
+
this.#density_scheduler = create_density_group_scheduler(this.#item_list)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#build_iteration_context()
|
|
55
|
+
{
|
|
56
|
+
return {
|
|
57
|
+
item_list: this.#item_list,
|
|
58
|
+
block_list: this.#block_list,
|
|
59
|
+
preferential_block_identifier: this.#preferential_block_identifier,
|
|
60
|
+
space_skip_state: this.#space_skip_state,
|
|
61
|
+
chooser_session: this.#chooser_session,
|
|
62
|
+
allocation_attempt: this.#allocation_attempt,
|
|
63
|
+
item_lock: this.#item_lock,
|
|
64
|
+
picking_continuity: this.#picking_continuity,
|
|
65
|
+
density_scheduler: this.#density_scheduler,
|
|
66
|
+
recovery_state: this.#recovery_state
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @returns {Promise<object>}
|
|
72
|
+
*/
|
|
73
|
+
async allocate()
|
|
74
|
+
{
|
|
75
|
+
const container_sequence_list = this.#resolve_container_sequences()
|
|
76
|
+
for (const container_sequence of container_sequence_list)
|
|
77
|
+
{
|
|
78
|
+
const container = this.#transport.get_container_by_sequence(container_sequence)
|
|
79
|
+
logger.debug(`Allocating container ${container_sequence} of ${this.#transport.container_amount()}`)
|
|
80
|
+
await traced_step(TRACE_CONTEXT.CONTAINER_ALLOCATION, async () =>
|
|
81
|
+
this.#run_container_iterations(container)
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
normalize_relational_proportional_allocation(this.#transport, this.#item_list)
|
|
86
|
+
validate_relational_completeness(this.#transport, this.#item_list)
|
|
87
|
+
validate_transport_colocation(this.#transport)
|
|
88
|
+
return this.#transport
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
#resolve_container_sequences()
|
|
92
|
+
{
|
|
93
|
+
const all_sequences = this.#transport.get_container_sequence_list()
|
|
94
|
+
|
|
95
|
+
if (!Cargo_Profile.enforce_relational_group_co_location())
|
|
96
|
+
{
|
|
97
|
+
return all_sequences
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const has_relational_items_present = has_relational_items(this.#item_list)
|
|
101
|
+
if (!has_relational_items_present || all_sequences.length === 0)
|
|
102
|
+
{
|
|
103
|
+
return all_sequences
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return [all_sequences[0]]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async #run_container_iterations(container)
|
|
110
|
+
{
|
|
111
|
+
this.#picking_continuity.reset()
|
|
112
|
+
this.#chooser_session.tie_ratio_intercalation_state.reset()
|
|
113
|
+
let capacity = remaining_items_fit_container(this.#item_list, container)
|
|
114
|
+
this.#item_list = capacity.item_list
|
|
115
|
+
while (capacity.has_capacity)
|
|
116
|
+
{
|
|
117
|
+
const locked_item = this.#item_lock.resolve_locked_item(this.#item_list)
|
|
118
|
+
const amount_before = this.#item_lock.snapshot_locked_amount(locked_item)
|
|
119
|
+
const should_continue = await this.#run_single_iteration(
|
|
120
|
+
this.#build_iteration_context(),
|
|
121
|
+
container,
|
|
122
|
+
locked_item
|
|
123
|
+
)
|
|
124
|
+
this.#item_lock.release_if_no_progress(amount_before, locked_item)
|
|
125
|
+
if (!should_continue)
|
|
126
|
+
{
|
|
127
|
+
break
|
|
128
|
+
}
|
|
129
|
+
capacity = remaining_items_fit_container(this.#item_list, container)
|
|
130
|
+
this.#item_list = capacity.item_list
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
async #run_single_iteration(context, container, locked_item)
|
|
135
|
+
{
|
|
136
|
+
try
|
|
137
|
+
{
|
|
138
|
+
return await run_allocation_iteration(context, container, locked_item)
|
|
139
|
+
}
|
|
140
|
+
catch (error)
|
|
141
|
+
{
|
|
142
|
+
const recovery = try_no_space_left_recovery({
|
|
143
|
+
error,
|
|
144
|
+
container,
|
|
145
|
+
locked_item,
|
|
146
|
+
item_list: this.#item_list,
|
|
147
|
+
space_skip_state: this.#space_skip_state,
|
|
148
|
+
chooser_session: this.#chooser_session,
|
|
149
|
+
density_scheduler: this.#density_scheduler,
|
|
150
|
+
recovery_state: this.#recovery_state
|
|
151
|
+
})
|
|
152
|
+
this.#item_list = recovery.item_list
|
|
153
|
+
if (recovery.recovered)
|
|
154
|
+
{
|
|
155
|
+
return true
|
|
156
|
+
}
|
|
157
|
+
return handle_allocation_exception(error, this.#allocation_attempt.get_attempt_id())
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = Allocation_flow
|