@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
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
const { cube_map_function } = require('../Blocks_Preparation/Cube_Map_Function')
|
|
2
|
+
const round = require('../tools/Rounder')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 1-slot blocks of leftover SKUs: not used by remaining compounds, or remembered after compounds are gone.
|
|
6
|
+
* @param {object[]} pre_selected_block_list
|
|
7
|
+
* @param {object[]} compound_block_list
|
|
8
|
+
* @param {Set<string>|string[]} [remembered_sku_hashes]
|
|
9
|
+
* @returns {object[]}
|
|
10
|
+
*/
|
|
11
|
+
function leftover_unitary_blocks(pre_selected_block_list, compound_block_list, remembered_sku_hashes)
|
|
12
|
+
{
|
|
13
|
+
const remembered = to_hash_set(remembered_sku_hashes)
|
|
14
|
+
if (remembered.size > 0)
|
|
15
|
+
{
|
|
16
|
+
return pre_selected_block_list.filter(block => is_unitary_matching_hashes(block, remembered))
|
|
17
|
+
}
|
|
18
|
+
return pre_selected_block_list.filter(
|
|
19
|
+
block => is_leftover_unitary_block(block, compound_slot_shape_hashes(compound_block_list))
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Stores leftover SKU shape hashes while compounds still remain.
|
|
25
|
+
* @param {{ leftover_sku_shape_hashes?: string[] }|undefined} session
|
|
26
|
+
* @param {object[]} leftover_block_list
|
|
27
|
+
* @param {object[]} compound_block_list
|
|
28
|
+
*/
|
|
29
|
+
function remember_leftover_sku_hashes(session, leftover_block_list, compound_block_list)
|
|
30
|
+
{
|
|
31
|
+
if (!session || compound_block_list.length === 0 || leftover_block_list.length === 0)
|
|
32
|
+
{
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
if (session.leftover_sku_shape_hashes?.length > 0)
|
|
36
|
+
{
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
session.leftover_sku_shape_hashes = [...leftover_sku_shape_hashes(leftover_block_list)]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Width/height/length hashes for leftover 1-slot blocks, including swapped floor axes.
|
|
44
|
+
* @param {object[]} leftover_block_list
|
|
45
|
+
* @returns {Set<string>}
|
|
46
|
+
*/
|
|
47
|
+
function leftover_sku_shape_hashes(leftover_block_list)
|
|
48
|
+
{
|
|
49
|
+
const hashes = new Set()
|
|
50
|
+
for (const block of leftover_block_list)
|
|
51
|
+
{
|
|
52
|
+
add_slot_orientation_hashes(hashes, block)
|
|
53
|
+
}
|
|
54
|
+
return hashes
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function add_slot_orientation_hashes(hashes, block)
|
|
58
|
+
{
|
|
59
|
+
if (typeof block.get_slot_list !== 'function')
|
|
60
|
+
{
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
const slot_list = block.get_slot_list()
|
|
64
|
+
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
65
|
+
{
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
hashes.add(cube_map_function(slot_list[0]))
|
|
69
|
+
hashes.add(swapped_length_width_hash(slot_list[0]))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function swapped_length_width_hash(slot)
|
|
73
|
+
{
|
|
74
|
+
return round(slot.get_length()) + ';' + round(slot.get_height()) + ';' + round(slot.get_width())
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function to_hash_set(remembered_sku_hashes)
|
|
78
|
+
{
|
|
79
|
+
if (!remembered_sku_hashes)
|
|
80
|
+
{
|
|
81
|
+
return new Set()
|
|
82
|
+
}
|
|
83
|
+
if (remembered_sku_hashes instanceof Set)
|
|
84
|
+
{
|
|
85
|
+
return remembered_sku_hashes
|
|
86
|
+
}
|
|
87
|
+
return new Set(remembered_sku_hashes)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function compound_slot_shape_hashes(compound_block_list)
|
|
91
|
+
{
|
|
92
|
+
const hashes = new Set()
|
|
93
|
+
for (const block of compound_block_list)
|
|
94
|
+
{
|
|
95
|
+
if (typeof block.get_slot_list !== 'function')
|
|
96
|
+
{
|
|
97
|
+
continue
|
|
98
|
+
}
|
|
99
|
+
for (const slot of block.get_slot_list())
|
|
100
|
+
{
|
|
101
|
+
if (typeof slot.get_width !== 'function')
|
|
102
|
+
{
|
|
103
|
+
continue
|
|
104
|
+
}
|
|
105
|
+
hashes.add(cube_map_function(slot))
|
|
106
|
+
hashes.add(swapped_length_width_hash(slot))
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return hashes
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function is_leftover_unitary_block(block, compound_slot_hashes)
|
|
113
|
+
{
|
|
114
|
+
if (typeof block.get_slot_list !== 'function')
|
|
115
|
+
{
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
const slot_list = block.get_slot_list()
|
|
119
|
+
if (slot_list.length !== 1)
|
|
120
|
+
{
|
|
121
|
+
return false
|
|
122
|
+
}
|
|
123
|
+
if (compound_slot_hashes.size === 0)
|
|
124
|
+
{
|
|
125
|
+
return true
|
|
126
|
+
}
|
|
127
|
+
if (typeof slot_list[0].get_width !== 'function')
|
|
128
|
+
{
|
|
129
|
+
return true
|
|
130
|
+
}
|
|
131
|
+
return !compound_slot_hashes.has(cube_map_function(slot_list[0]))
|
|
132
|
+
&& !compound_slot_hashes.has(swapped_length_width_hash(slot_list[0]))
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function is_unitary_matching_hashes(block, remembered)
|
|
136
|
+
{
|
|
137
|
+
if (typeof block.get_slot_list !== 'function')
|
|
138
|
+
{
|
|
139
|
+
return false
|
|
140
|
+
}
|
|
141
|
+
const slot_list = block.get_slot_list()
|
|
142
|
+
if (slot_list.length !== 1 || typeof slot_list[0].get_width !== 'function')
|
|
143
|
+
{
|
|
144
|
+
return false
|
|
145
|
+
}
|
|
146
|
+
return remembered.has(cube_map_function(slot_list[0]))
|
|
147
|
+
|| remembered.has(swapped_length_width_hash(slot_list[0]))
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
leftover_unitary_blocks.remember_leftover_sku_hashes = remember_leftover_sku_hashes
|
|
151
|
+
leftover_unitary_blocks.leftover_sku_shape_hashes = leftover_sku_shape_hashes
|
|
152
|
+
|
|
153
|
+
module.exports = leftover_unitary_blocks
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
const leftover_unitary_blocks = require('./leftover_unitary_blocks')
|
|
2
|
+
const empty_spaces_where_post_selection_keeps_blocks = require('./empty_spaces_where_post_selection_keeps_blocks')
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Spaces that fail the compound probe but keep at least one pre-selected block.
|
|
6
|
+
* @param {Function} run_filters
|
|
7
|
+
* @param {object} filter_data
|
|
8
|
+
* @param {object[]} empty_space_list
|
|
9
|
+
* @param {object[]} pre_selected_block_list
|
|
10
|
+
* @param {object[]} compound_viable_spaces
|
|
11
|
+
* @returns {Promise<object[]>}
|
|
12
|
+
*/
|
|
13
|
+
async function leftover_unitary_empty_spaces(
|
|
14
|
+
run_filters,
|
|
15
|
+
filter_data,
|
|
16
|
+
empty_space_list,
|
|
17
|
+
pre_selected_block_list,
|
|
18
|
+
compound_viable_spaces
|
|
19
|
+
)
|
|
20
|
+
{
|
|
21
|
+
const leftover_candidates = empty_space_list.filter(
|
|
22
|
+
space => !compound_viable_spaces.includes(space)
|
|
23
|
+
)
|
|
24
|
+
if (leftover_candidates.length === 0)
|
|
25
|
+
{
|
|
26
|
+
return []
|
|
27
|
+
}
|
|
28
|
+
return empty_spaces_where_post_selection_keeps_blocks(
|
|
29
|
+
run_filters,
|
|
30
|
+
filter_data,
|
|
31
|
+
leftover_candidates,
|
|
32
|
+
pre_selected_block_list
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Uses leftover spaces with leftover-SKU unitaries, or the original lists when leftover is empty.
|
|
38
|
+
* @param {object[]} empty_space_list
|
|
39
|
+
* @param {object[]} pre_selected_block_list
|
|
40
|
+
* @param {object[]} leftover_empty_spaces
|
|
41
|
+
* @param {object[]} [leftover_block_list]
|
|
42
|
+
* @returns {{ empty_spaces_for_chooser: object[], blocks_for_post_selection: object[], leftover_empty_spaces: object[], skip_cluster_rank: boolean }}
|
|
43
|
+
*/
|
|
44
|
+
function leftover_or_legacy_resolution(
|
|
45
|
+
empty_space_list,
|
|
46
|
+
pre_selected_block_list,
|
|
47
|
+
leftover_empty_spaces,
|
|
48
|
+
leftover_block_list
|
|
49
|
+
)
|
|
50
|
+
{
|
|
51
|
+
const blocks_for_leftover = leftover_block_list ?? pre_selected_block_list
|
|
52
|
+
if (leftover_empty_spaces.length > 0 && blocks_for_leftover.length > 0)
|
|
53
|
+
{
|
|
54
|
+
return {
|
|
55
|
+
empty_spaces_for_chooser: leftover_empty_spaces,
|
|
56
|
+
blocks_for_post_selection: blocks_for_leftover,
|
|
57
|
+
leftover_empty_spaces,
|
|
58
|
+
skip_cluster_rank: true
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
empty_spaces_for_chooser: empty_space_list,
|
|
63
|
+
blocks_for_post_selection: pre_selected_block_list,
|
|
64
|
+
leftover_empty_spaces: leftover_empty_spaces.length > 0 ? leftover_empty_spaces : [],
|
|
65
|
+
skip_cluster_rank: false
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* ISSUE-1745 skip: all spaces and blocks, no compound probe, no cluster rank.
|
|
71
|
+
* @param {object[]} empty_space_list
|
|
72
|
+
* @param {object[]} pre_selected_block_list
|
|
73
|
+
* @returns {{ empty_spaces_for_chooser: object[], blocks_for_post_selection: object[], leftover_empty_spaces: object[], skip_cluster_rank: boolean }}
|
|
74
|
+
*/
|
|
75
|
+
function skip_probe_resolution(empty_space_list, pre_selected_block_list)
|
|
76
|
+
{
|
|
77
|
+
return {
|
|
78
|
+
empty_spaces_for_chooser: empty_space_list,
|
|
79
|
+
blocks_for_post_selection: pre_selected_block_list,
|
|
80
|
+
leftover_empty_spaces: [],
|
|
81
|
+
skip_cluster_rank: true
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Compound-viable spaces first; leftover or legacy when the probe is skipped or empty.
|
|
87
|
+
* @param {object} filter_data
|
|
88
|
+
* @param {object[]} empty_space_list
|
|
89
|
+
* @param {object[]} pre_selected_block_list
|
|
90
|
+
* @param {object[]} compound_block_list
|
|
91
|
+
* @param {object[]} viable_spaces
|
|
92
|
+
* @param {object[]} leftover_empty_spaces
|
|
93
|
+
* @returns {object}
|
|
94
|
+
*/
|
|
95
|
+
function resolve_compound_first_or_leftover(
|
|
96
|
+
filter_data,
|
|
97
|
+
empty_space_list,
|
|
98
|
+
pre_selected_block_list,
|
|
99
|
+
compound_block_list,
|
|
100
|
+
viable_spaces,
|
|
101
|
+
leftover_empty_spaces
|
|
102
|
+
)
|
|
103
|
+
{
|
|
104
|
+
const skip_probe = filter_data.obligate_compound_session?.skip_compound_probe === true
|
|
105
|
+
if (!skip_probe && viable_spaces.length > 0)
|
|
106
|
+
{
|
|
107
|
+
return {
|
|
108
|
+
empty_spaces_for_chooser: viable_spaces,
|
|
109
|
+
blocks_for_post_selection: compound_block_list,
|
|
110
|
+
leftover_empty_spaces,
|
|
111
|
+
skip_cluster_rank: false
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (viable_spaces.length === 0 && filter_data.obligate_compound_session)
|
|
115
|
+
{
|
|
116
|
+
filter_data.obligate_compound_session.skip_compound_probe = true
|
|
117
|
+
}
|
|
118
|
+
return leftover_or_legacy_resolution(
|
|
119
|
+
empty_space_list,
|
|
120
|
+
pre_selected_block_list,
|
|
121
|
+
leftover_empty_spaces,
|
|
122
|
+
leftover_unitary_blocks(
|
|
123
|
+
pre_selected_block_list,
|
|
124
|
+
compound_block_list,
|
|
125
|
+
filter_data.obligate_compound_session?.leftover_sku_shape_hashes
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = {
|
|
131
|
+
leftover_unitary_empty_spaces,
|
|
132
|
+
leftover_or_legacy_resolution,
|
|
133
|
+
skip_probe_resolution,
|
|
134
|
+
resolve_compound_first_or_leftover
|
|
135
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const PROBE_SET_POOL = [new Set(), new Set()]
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns an empty Set from a small pool (probe paths must not retain references).
|
|
5
|
+
* @returns {Set<object>}
|
|
6
|
+
*/
|
|
7
|
+
function borrow_empty_set()
|
|
8
|
+
{
|
|
9
|
+
const borrowed = PROBE_SET_POOL.pop()
|
|
10
|
+
if (borrowed)
|
|
11
|
+
{
|
|
12
|
+
borrowed.clear()
|
|
13
|
+
return borrowed
|
|
14
|
+
}
|
|
15
|
+
return new Set()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const MAX_POOLED_SETS = 2
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {Set<object>} probe_set
|
|
22
|
+
*/
|
|
23
|
+
function release_probe_set(probe_set)
|
|
24
|
+
{
|
|
25
|
+
if (PROBE_SET_POOL.length < MAX_POOLED_SETS)
|
|
26
|
+
{
|
|
27
|
+
probe_set.clear()
|
|
28
|
+
PROBE_SET_POOL.push(probe_set)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
borrow_empty_set,
|
|
34
|
+
release_probe_set
|
|
35
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const pre_selection_filters = require('./blocks_filters/pre_selection_filter/Pre_Selection_Filter_List')
|
|
2
|
+
const pos_selection_filters = require('./blocks_filters/pos_selection_filters/Post_Selection_Filter_List')
|
|
3
|
+
const resolve_empty_spaces_and_blocks_for_obligate_compound_first = require('./compound_first_empty_space_branch')
|
|
4
|
+
const Cargo_Profile = require('../models/Cargo_Profile')
|
|
5
|
+
const {ClassicEmptySpaceChooser} = require('@jetta/empty-spaces-manager')
|
|
6
|
+
const build_allocated_item_snapshots = require('./build_allocated_item_snapshots')
|
|
7
|
+
const Invalid_Space_To_Allocate_Exception = require('./exceptions/Invalid_Space_To_Allocate_Exception')
|
|
8
|
+
const {Logger} = require('@jetta/logger')
|
|
9
|
+
|
|
10
|
+
const logger = new Logger('Space and Blocks Creator')
|
|
11
|
+
|
|
12
|
+
function choose_best_empty_space(
|
|
13
|
+
container,
|
|
14
|
+
empty_space_list,
|
|
15
|
+
item_list,
|
|
16
|
+
spaces_to_avoid = new Set(),
|
|
17
|
+
skip_cluster_rank = false
|
|
18
|
+
)
|
|
19
|
+
{
|
|
20
|
+
const chooser = new ClassicEmptySpaceChooser({
|
|
21
|
+
container,
|
|
22
|
+
empty_spaces: empty_space_list,
|
|
23
|
+
items: item_list,
|
|
24
|
+
allocated_items: build_allocated_item_snapshots(container),
|
|
25
|
+
cargo_profile: Cargo_Profile.get_cargo_profile_as_js_object(),
|
|
26
|
+
spaces_to_avoid
|
|
27
|
+
})
|
|
28
|
+
const classic_winner = chooser.evaluate_spaces()
|
|
29
|
+
if (skip_cluster_rank)
|
|
30
|
+
{
|
|
31
|
+
return classic_winner
|
|
32
|
+
}
|
|
33
|
+
return classic_winner
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function run_post_selection_or_null_on_invalid_space(run_filters, filter_data)
|
|
37
|
+
{
|
|
38
|
+
try
|
|
39
|
+
{
|
|
40
|
+
const pos_selection_block_list = await run_filters(pos_selection_filters, filter_data)
|
|
41
|
+
if (pos_selection_block_list.length > 0)
|
|
42
|
+
{
|
|
43
|
+
return pos_selection_block_list
|
|
44
|
+
}
|
|
45
|
+
return null
|
|
46
|
+
}
|
|
47
|
+
catch (error)
|
|
48
|
+
{
|
|
49
|
+
if (error instanceof Invalid_Space_To_Allocate_Exception)
|
|
50
|
+
{
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
throw error
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Runs pre-selection, optional compound-first narrowing, empty-space choice, and post-selection.
|
|
59
|
+
*
|
|
60
|
+
* @param {Function} run_filters
|
|
61
|
+
* @param {Object} filter_data
|
|
62
|
+
* @param {Array<Object>} empty_space_list
|
|
63
|
+
* @returns {Promise<{ chosen_empty_space: Object, pos_selection_block_list: Array<Object>|null }>}
|
|
64
|
+
*/
|
|
65
|
+
async function run_space_and_block_selection_attempt(run_filters, filter_data, empty_space_list)
|
|
66
|
+
{
|
|
67
|
+
logger.debug('filtering blocks before blocks and choosing empty space...')
|
|
68
|
+
const pre_selected_block_list = await run_filters(pre_selection_filters, filter_data)
|
|
69
|
+
const resolved = await resolve_empty_spaces_and_blocks_for_obligate_compound_first(
|
|
70
|
+
run_filters,
|
|
71
|
+
filter_data,
|
|
72
|
+
empty_space_list,
|
|
73
|
+
pre_selected_block_list
|
|
74
|
+
)
|
|
75
|
+
const chosen_empty_space = choose_best_empty_space(
|
|
76
|
+
filter_data.container,
|
|
77
|
+
resolved.empty_spaces_for_chooser,
|
|
78
|
+
filter_data.item_list,
|
|
79
|
+
filter_data.spaces_to_avoid,
|
|
80
|
+
resolved.skip_cluster_rank === true
|
|
81
|
+
)
|
|
82
|
+
filter_data.empty_space = chosen_empty_space
|
|
83
|
+
filter_data.block_list = resolved.blocks_for_post_selection
|
|
84
|
+
const pos_selection_block_list = await run_post_selection_or_null_on_invalid_space(run_filters, filter_data)
|
|
85
|
+
return { chosen_empty_space, pos_selection_block_list }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = run_space_and_block_selection_attempt
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const is_number = (val) => typeof val === 'number' && !isNaN(val)
|
|
2
|
+
const is_string = (val) => typeof val === 'string'
|
|
3
|
+
|
|
4
|
+
module.exports = function clone(val)
|
|
5
|
+
{
|
|
6
|
+
if (is_number(val))
|
|
7
|
+
{
|
|
8
|
+
return clone_number(val)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (is_string(val))
|
|
12
|
+
{
|
|
13
|
+
return clone_string(val)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return JSON.parse(JSON.stringify(val))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function clone_string(val)
|
|
20
|
+
{
|
|
21
|
+
return String(val)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function clone_number(val)
|
|
25
|
+
{
|
|
26
|
+
return Number(val)
|
|
27
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const is_boolean = (input) => typeof input === 'boolean'
|
|
2
|
+
const is_number = (input) => typeof input === 'number'
|
|
3
|
+
const is_undefined = (input) => input === undefined
|
|
4
|
+
const is_true_str = (input) => ['true', '1', 'yes', 'on'].includes(String(input).trim().toLowerCase())
|
|
5
|
+
|
|
6
|
+
const str_to_bool = (input, def = false) =>
|
|
7
|
+
is_boolean(input) ? input :
|
|
8
|
+
is_number(input) ? input !== 0 :
|
|
9
|
+
is_undefined(input) ? def :
|
|
10
|
+
is_true_str(input)
|
|
11
|
+
|
|
12
|
+
module.exports = str_to_bool
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses a finite number from a numeric value or a decimal string; otherwise returns fallback.
|
|
3
|
+
* @param {unknown} raw
|
|
4
|
+
* @param {number} fallback
|
|
5
|
+
* @returns {number}
|
|
6
|
+
*/
|
|
7
|
+
function finite_float_from_string_or_number(raw, fallback)
|
|
8
|
+
{
|
|
9
|
+
const parsed = typeof raw === 'number' ? raw : parseFloat(raw)
|
|
10
|
+
return Number.isFinite(parsed) ? parsed : fallback
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Parses a finite integer from a numeric value or a string; otherwise returns fallback.
|
|
15
|
+
* @param {unknown} raw
|
|
16
|
+
* @param {number} fallback
|
|
17
|
+
* @returns {number}
|
|
18
|
+
*/
|
|
19
|
+
function finite_int_from_string_or_number(raw, fallback)
|
|
20
|
+
{
|
|
21
|
+
const parsed = typeof raw === 'number' ? Math.trunc(raw) : parseInt(raw, 10)
|
|
22
|
+
return Number.isFinite(parsed) ? parsed : fallback
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Like {@link finite_float_from_string_or_number} but returns undefined when raw is nullish or not parseable.
|
|
27
|
+
* @param {unknown} raw
|
|
28
|
+
* @returns {number|undefined}
|
|
29
|
+
*/
|
|
30
|
+
function optional_finite_float_from_string_or_number(raw)
|
|
31
|
+
{
|
|
32
|
+
if (raw === undefined || raw === null)
|
|
33
|
+
{
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
36
|
+
const parsed = typeof raw === 'number' ? raw : parseFloat(raw)
|
|
37
|
+
return Number.isFinite(parsed) ? parsed : undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
finite_float_from_string_or_number,
|
|
42
|
+
finite_int_from_string_or_number,
|
|
43
|
+
optional_finite_float_from_string_or_number,
|
|
44
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a new list containing only items with positive remaining amount.
|
|
3
|
+
* @param {Array<{ get_amount: () => number }>} item_list
|
|
4
|
+
* @returns {Array<{ get_amount: () => number }>}
|
|
5
|
+
*/
|
|
6
|
+
module.exports = function compact_items_with_stock(item_list)
|
|
7
|
+
{
|
|
8
|
+
return item_list.filter(item => item.get_amount() > 0)
|
|
9
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const round = require('./Rounder')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Converts vertical gap from API millimeters into internal geometry units.
|
|
5
|
+
* Container and item extents use the same numeric domain (typically millimeters).
|
|
6
|
+
* @param {number} mm - Non-negative value from `config.algoritmo.empty_space_merge_max_vertical_offset_mm`.
|
|
7
|
+
* @returns {number} Rounded domain value for {@link EmptySpaceFinder} merge tolerance.
|
|
8
|
+
*/
|
|
9
|
+
function mm_to_allocation_domain(mm)
|
|
10
|
+
{
|
|
11
|
+
return round(mm)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
module.exports = mm_to_allocation_domain
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const { AsyncLocalStorage } = require('async_hooks')
|
|
2
|
+
|
|
3
|
+
const storage = new AsyncLocalStorage()
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolves a request trace id from allocation input.
|
|
7
|
+
* Prefers `trace_id`; falls back to `_id` or a synthetic id so tracing never throws.
|
|
8
|
+
* @param {object} input - Allocation request payload.
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
function resolve_trace_id(input)
|
|
12
|
+
{
|
|
13
|
+
if (input == null || typeof input !== 'object')
|
|
14
|
+
{
|
|
15
|
+
return `bw-${Date.now()}`
|
|
16
|
+
}
|
|
17
|
+
if (input.trace_id != null && String(input.trace_id).length > 0)
|
|
18
|
+
{
|
|
19
|
+
return String(input.trace_id)
|
|
20
|
+
}
|
|
21
|
+
if (input._id != null && String(input._id).length > 0)
|
|
22
|
+
{
|
|
23
|
+
return String(input._id)
|
|
24
|
+
}
|
|
25
|
+
return `bw-${Date.now()}`
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @returns {object|null} Current request tracer, or null outside a binding.
|
|
30
|
+
*/
|
|
31
|
+
function get_tracer()
|
|
32
|
+
{
|
|
33
|
+
const store = storage.getStore()
|
|
34
|
+
return store?.tracer ?? null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Replaces the active tracer (mainly for tests).
|
|
39
|
+
* @param {object} tracer
|
|
40
|
+
* @param {() => Promise<*>|*} fn
|
|
41
|
+
* @returns {Promise<*>|*}
|
|
42
|
+
*/
|
|
43
|
+
function run_with_existing_tracer(tracer, fn)
|
|
44
|
+
{
|
|
45
|
+
return storage.run({ tracer }, fn)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
resolve_trace_id,
|
|
50
|
+
run_with_existing_tracer,
|
|
51
|
+
get_tracer
|
|
52
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stable English jstracer context names for blocks-wall timing spans.
|
|
3
|
+
*/
|
|
4
|
+
const TRACE_CONTEXT = Object.freeze({
|
|
5
|
+
MAIN_FLOW: 'main flow',
|
|
6
|
+
MAP_EMPTY_SPACES: 'map empty spaces',
|
|
7
|
+
BLOCKS_GENERATION: 'blocks generation',
|
|
8
|
+
CONTAINER_ALLOCATION: 'container allocation',
|
|
9
|
+
SPACE_AND_BLOCK_CHOICE: 'space and block choice',
|
|
10
|
+
LP_OPTIMIZE: 'lp optimize',
|
|
11
|
+
ITEM_SELECTION_POSITIONING: 'item selection positioning',
|
|
12
|
+
CHOSEN_BLOCK_STACKING_VALIDATION: 'chosen block stacking validation',
|
|
13
|
+
BLOCK_WALL_ALLOCATED: 'block wall allocated',
|
|
14
|
+
BLOCK_WALL_RETRY_OTHER_BLOCKS: 'block wall retry other blocks',
|
|
15
|
+
BLOCK_WALL_SPACE_EXHAUSTED: 'block wall space exhausted'
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
module.exports = { TRACE_CONTEXT }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { get_tracer } = require('./Allocation_Tracer')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Records a short success transaction for a wall-outcome context (allocated / retry / exhausted).
|
|
5
|
+
* @param {string} context - Outcome context name.
|
|
6
|
+
*/
|
|
7
|
+
function mark_trace_outcome(context)
|
|
8
|
+
{
|
|
9
|
+
const tracer = get_tracer()
|
|
10
|
+
if (!tracer)
|
|
11
|
+
{
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
const tx_id = tracer.start_transaction(context)
|
|
15
|
+
tracer.end_transaction_succesfully(tx_id)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = { mark_trace_outcome }
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const { get_tracer } = require('./Allocation_Tracer')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Runs an async step under a Manual_Tracer transaction that always closes.
|
|
5
|
+
* @param {string} context - jstracer context name.
|
|
6
|
+
* @param {() => Promise<*>} fn - Step body.
|
|
7
|
+
* @returns {Promise<*>}
|
|
8
|
+
*/
|
|
9
|
+
async function traced_step(context, fn)
|
|
10
|
+
{
|
|
11
|
+
const tracer = get_tracer()
|
|
12
|
+
if (!tracer)
|
|
13
|
+
{
|
|
14
|
+
return await fn()
|
|
15
|
+
}
|
|
16
|
+
const tx_id = tracer.start_transaction(context)
|
|
17
|
+
try
|
|
18
|
+
{
|
|
19
|
+
const result = await fn()
|
|
20
|
+
tracer.end_transaction_succesfully(tx_id)
|
|
21
|
+
return result
|
|
22
|
+
}
|
|
23
|
+
catch (error)
|
|
24
|
+
{
|
|
25
|
+
tracer.end_transaction_with_failure(tx_id)
|
|
26
|
+
throw error
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Runs a sync step under a Manual_Tracer transaction that always closes.
|
|
32
|
+
* @param {string} context - jstracer context name.
|
|
33
|
+
* @param {() => *} fn - Step body.
|
|
34
|
+
* @returns {*}
|
|
35
|
+
*/
|
|
36
|
+
function traced_step_sync(context, fn)
|
|
37
|
+
{
|
|
38
|
+
const tracer = get_tracer()
|
|
39
|
+
if (!tracer)
|
|
40
|
+
{
|
|
41
|
+
return fn()
|
|
42
|
+
}
|
|
43
|
+
const tx_id = tracer.start_transaction(context)
|
|
44
|
+
try
|
|
45
|
+
{
|
|
46
|
+
const result = fn()
|
|
47
|
+
tracer.end_transaction_succesfully(tx_id)
|
|
48
|
+
return result
|
|
49
|
+
}
|
|
50
|
+
catch (error)
|
|
51
|
+
{
|
|
52
|
+
tracer.end_transaction_with_failure(tx_id)
|
|
53
|
+
throw error
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = { traced_step, traced_step_sync }
|