@nshiab/simple-data-analysis-core 2.1.6 → 2.1.8

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.
Files changed (75) hide show
  1. package/esm/class/SimpleTable.d.ts +399 -90
  2. package/esm/class/SimpleTable.d.ts.map +1 -1
  3. package/esm/class/SimpleTable.js +393 -90
  4. package/esm/helpers/buildGraphTemporalCostStateSql.d.ts +1 -1
  5. package/esm/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -1
  6. package/esm/helpers/buildGraphTemporalCostStateSql.js +23 -9
  7. package/esm/helpers/graphRouteResultSchema.d.ts +1 -1
  8. package/esm/helpers/graphRouteResultSchema.d.ts.map +1 -1
  9. package/esm/helpers/graphRouteResultSchema.js +4 -3
  10. package/esm/helpers/graphRouteResultSelect.d.ts +1 -1
  11. package/esm/helpers/graphRouteResultSelect.d.ts.map +1 -1
  12. package/esm/helpers/graphRouteResultSelect.js +5 -2
  13. package/esm/helpers/prepareGraphMetricOptions.d.ts +14 -0
  14. package/esm/helpers/prepareGraphMetricOptions.d.ts.map +1 -0
  15. package/esm/helpers/prepareGraphMetricOptions.js +41 -0
  16. package/esm/helpers/prepareGraphRouteSql.d.ts +2 -2
  17. package/esm/helpers/prepareGraphRouteSql.d.ts.map +1 -1
  18. package/esm/helpers/prepareGraphRouteSql.js +4 -4
  19. package/esm/helpers/prepareGraphTemporalSql.d.ts +3 -0
  20. package/esm/helpers/prepareGraphTemporalSql.d.ts.map +1 -1
  21. package/esm/helpers/prepareGraphTemporalSql.js +7 -0
  22. package/esm/helpers/validateGraphRouteResultSchema.d.ts +1 -1
  23. package/esm/helpers/validateGraphRouteResultSchema.d.ts.map +1 -1
  24. package/esm/helpers/validateGraphRouteResultSchema.js +3 -1
  25. package/esm/methods/distances.d.ts +2 -0
  26. package/esm/methods/distances.d.ts.map +1 -1
  27. package/esm/methods/distances.js +274 -20
  28. package/esm/methods/findCycles.d.ts +1 -0
  29. package/esm/methods/findCycles.d.ts.map +1 -1
  30. package/esm/methods/findCycles.js +22 -15
  31. package/esm/methods/paths.d.ts +1 -0
  32. package/esm/methods/paths.d.ts.map +1 -1
  33. package/esm/methods/paths.js +21 -14
  34. package/esm/methods/shortestPath.d.ts +2 -0
  35. package/esm/methods/shortestPath.d.ts.map +1 -1
  36. package/esm/methods/shortestPath.js +155 -34
  37. package/llm.md +428 -108
  38. package/llms.txt +1 -1
  39. package/package.json +1 -1
  40. package/script/class/SimpleTable.d.ts +399 -90
  41. package/script/class/SimpleTable.d.ts.map +1 -1
  42. package/script/class/SimpleTable.js +393 -90
  43. package/script/helpers/buildGraphTemporalCostStateSql.d.ts +1 -1
  44. package/script/helpers/buildGraphTemporalCostStateSql.d.ts.map +1 -1
  45. package/script/helpers/buildGraphTemporalCostStateSql.js +23 -9
  46. package/script/helpers/graphRouteResultSchema.d.ts +1 -1
  47. package/script/helpers/graphRouteResultSchema.d.ts.map +1 -1
  48. package/script/helpers/graphRouteResultSchema.js +4 -3
  49. package/script/helpers/graphRouteResultSelect.d.ts +1 -1
  50. package/script/helpers/graphRouteResultSelect.d.ts.map +1 -1
  51. package/script/helpers/graphRouteResultSelect.js +5 -2
  52. package/script/helpers/prepareGraphMetricOptions.d.ts +14 -0
  53. package/script/helpers/prepareGraphMetricOptions.d.ts.map +1 -0
  54. package/script/helpers/prepareGraphMetricOptions.js +44 -0
  55. package/script/helpers/prepareGraphRouteSql.d.ts +2 -2
  56. package/script/helpers/prepareGraphRouteSql.d.ts.map +1 -1
  57. package/script/helpers/prepareGraphRouteSql.js +4 -4
  58. package/script/helpers/prepareGraphTemporalSql.d.ts +3 -0
  59. package/script/helpers/prepareGraphTemporalSql.d.ts.map +1 -1
  60. package/script/helpers/prepareGraphTemporalSql.js +7 -0
  61. package/script/helpers/validateGraphRouteResultSchema.d.ts +1 -1
  62. package/script/helpers/validateGraphRouteResultSchema.d.ts.map +1 -1
  63. package/script/helpers/validateGraphRouteResultSchema.js +3 -1
  64. package/script/methods/distances.d.ts +2 -0
  65. package/script/methods/distances.d.ts.map +1 -1
  66. package/script/methods/distances.js +274 -20
  67. package/script/methods/findCycles.d.ts +1 -0
  68. package/script/methods/findCycles.d.ts.map +1 -1
  69. package/script/methods/findCycles.js +22 -15
  70. package/script/methods/paths.d.ts +1 -0
  71. package/script/methods/paths.d.ts.map +1 -1
  72. package/script/methods/paths.js +21 -14
  73. package/script/methods/shortestPath.d.ts +2 -0
  74. package/script/methods/shortestPath.d.ts.map +1 -1
  75. package/script/methods/shortestPath.js +155 -34
@@ -2770,42 +2770,24 @@ class SimpleTable extends Simple {
2770
2770
  return topologicalSort(this, sourceColumn, targetColumn, options);
2771
2771
  }
2772
2772
  /**
2773
- * Finds the shortest distance from each starting node to every node it can
2774
- * reach by following one or more connections. By default, distance is the
2775
- * number of connections along the shortest route. Use the `weight` option
2776
- * to find the smallest sum of values from a numeric column, such as travel
2777
- * time.
2773
+ * Finds the shortest routes from each starting node to every reachable
2774
+ * node. Without options, shortest means the fewest connections. Use `weight`
2775
+ * to report total cost and `elapsedTime` to report duration including waiting
2776
+ * between connections. Use `minimize` to choose which metric defines shortest.
2778
2777
  *
2779
- * The `direction` option lets you follow connections from source to target,
2780
- * from target to source, or in either direction. The result has `start`,
2781
- * `node`, and `distance` columns, sorted by `start`, then by increasing
2782
- * `distance`, then by `node` to break ties. The closest nodes appear first
2783
- * for each start.
2784
- *
2785
- * Each row gives the shortest distance from `start` to `node`. Intermediate
2786
- * steps along the route are not returned. To get the steps between two
2787
- * different nodes, use `shortestPath()` for the shortest routes or `paths()`
2788
- * for all routes without repeated nodes.
2778
+ * Each row contains `start`, `node`, and `steps`, plus `total` when `weight`
2779
+ * is supplied and `elapsedTimeMs` when enabled. Routes tied on the chosen
2780
+ * metric produce separate rows only when their reported summaries differ;
2781
+ * identical summaries appear once.
2789
2782
  *
2790
- * A starting node appears in its own results only when a self-connection
2791
- * or a route leads back to it. Its distance is the shortest actual return
2792
- * route, using at least one connection. With `direction: "both"`, this
2793
- * can mean following the same connection out and back.
2783
+ * Routes cannot repeat nodes except for a final return to the start. A start
2784
+ * appears in its own results only through an actual return or self-connection,
2785
+ * never with zero steps. With `direction: "both"`, a return can follow the
2786
+ * same connection out and back. Use `shortestPath()` to inspect individual
2787
+ * connections between two different nodes.
2794
2788
  *
2795
- * Unknown starting IDs and starts with no connections to follow produce
2796
- * no rows. Empty start arrays and duplicate starting IDs throw an error.
2797
- * Weights must be non-null, finite, and non-negative.
2798
- *
2799
- * Use the `startTimeColumn` or `endTimeColumn` options to follow connections
2800
- * in chronological order. The `minGapMs` option sets the minimum gap between
2801
- * consecutive connections, in milliseconds. With both time columns, gaps are
2802
- * measured from one connection's end to the next connection's start; with one
2803
- * column, between their timestamps. The `strictOrdering` option defaults to
2804
- * `true`, rejecting zero-duration gaps. These options only work with
2805
- * `direction: "outgoing"` or `direction: "incoming"`.
2806
- *
2807
- * The minimum gap applies only between consecutive connections, not before
2808
- * the first connection.
2789
+ * Reporting weight or elapsed time can require substantial time and memory
2790
+ * on dense networks because many routes may need to be explored.
2809
2791
  *
2810
2792
  * The next five examples each start with this data:
2811
2793
  *
@@ -2825,12 +2807,12 @@ class SimpleTable extends Simple {
2825
2807
  * .log();
2826
2808
  * ```
2827
2809
  *
2828
- * | start | node | distance |
2810
+ * | start | node | steps |
2829
2811
  * | --- | --- | ---: |
2830
2812
  * | A | B | 1 |
2831
2813
  * | A | C | 2 |
2832
2814
  *
2833
- * With `weight: "minutes"`, distance is the shortest total travel time:
2815
+ * With `weight: "minutes"`, `total` is the sum of travel times:
2834
2816
  *
2835
2817
  * @example
2836
2818
  * ```ts
@@ -2839,10 +2821,10 @@ class SimpleTable extends Simple {
2839
2821
  * .log();
2840
2822
  * ```
2841
2823
  *
2842
- * | start | node | distance |
2843
- * | --- | --- | ---: |
2844
- * | A | B | 4 |
2845
- * | A | C | 5 |
2824
+ * | start | node | steps | total |
2825
+ * | --- | --- | ---: | ---: |
2826
+ * | A | B | 1 | 4 |
2827
+ * | A | C | 2 | 5 |
2846
2828
  *
2847
2829
  * With `direction: "incoming"`, connections are followed from target to
2848
2830
  * source. Starting at C:
@@ -2854,7 +2836,7 @@ class SimpleTable extends Simple {
2854
2836
  * .log();
2855
2837
  * ```
2856
2838
  *
2857
- * | start | node | distance |
2839
+ * | start | node | steps |
2858
2840
  * | --- | --- | ---: |
2859
2841
  * | C | B | 1 |
2860
2842
  * | C | A | 2 |
@@ -2870,14 +2852,14 @@ class SimpleTable extends Simple {
2870
2852
  * .log();
2871
2853
  * ```
2872
2854
  *
2873
- * | start | node | distance |
2855
+ * | start | node | steps |
2874
2856
  * | --- | --- | ---: |
2875
2857
  * | A | B | 1 |
2876
2858
  * | A | A | 2 |
2877
2859
  * | A | C | 2 |
2878
2860
  * | A | D | 2 |
2879
2861
  *
2880
- * A appears at distance 2 because A → B → A follows a connection out
2862
+ * A appears with 2 steps because A → B → A follows a connection out
2881
2863
  * and back.
2882
2864
  *
2883
2865
  * An array of starting nodes gives separate distances for each start:
@@ -2891,12 +2873,12 @@ class SimpleTable extends Simple {
2891
2873
  * .log();
2892
2874
  * ```
2893
2875
  *
2894
- * | start | node | distance |
2895
- * | --- | --- | ---: |
2896
- * | A | B | 4 |
2897
- * | A | C | 5 |
2898
- * | D | B | 2 |
2899
- * | D | C | 3 |
2876
+ * | start | node | steps | total |
2877
+ * | --- | --- | ---: | ---: |
2878
+ * | A | B | 1 | 4 |
2879
+ * | A | C | 2 | 5 |
2880
+ * | D | B | 1 | 2 |
2881
+ * | D | C | 2 | 3 |
2900
2882
  *
2901
2883
  * A direct self-connection and a longer return route can both lead back
2902
2884
  * to the start. This example uses different data:
@@ -2917,13 +2899,13 @@ class SimpleTable extends Simple {
2917
2899
  * .log();
2918
2900
  * ```
2919
2901
  *
2920
- * | start | node | distance |
2921
- * | --- | --- | ---: |
2922
- * | A | B | 2 |
2923
- * | A | A | 5 |
2902
+ * | start | node | steps | total |
2903
+ * | --- | --- | ---: | ---: |
2904
+ * | A | B | 1 | 2 |
2905
+ * | A | A | 2 | 5 |
2924
2906
  *
2925
2907
  * Chronological options can rule out a cheaper sequence that departs too
2926
- * early. For this example, F2 leaves before F1 arrives, while F3 meets the
2908
+ * early. Here, B → C leaves before A → B arrives, while B → D meets the
2927
2909
  * one-hour minimum exactly:
2928
2910
  *
2929
2911
  * | origin | destination | departureTime | arrivalTime | minutes |
@@ -2944,23 +2926,147 @@ class SimpleTable extends Simple {
2944
2926
  * .log();
2945
2927
  * ```
2946
2928
  *
2947
- * | start | node | distance |
2948
- * | --- | --- | ---: |
2949
- * | A | B | 2 |
2950
- * | A | D | 5 |
2929
+ * | start | node | steps | total |
2930
+ * | --- | --- | ---: | ---: |
2931
+ * | A | B | 1 | 2 |
2932
+ * | A | D | 2 | 5 |
2933
+ *
2934
+ * For the next four examples, `flights` contains these rows, with departure
2935
+ * and arrival stored as timestamps on the same day:
2936
+ *
2937
+ * | flightId | origin | destination | departure | arrival | price |
2938
+ * | --- | --- | --- | --- | --- | ---: |
2939
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
2940
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
2941
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
2942
+ *
2943
+ * Find the fastest journey from A to each reachable destination, including
2944
+ * layovers:
2945
+ *
2946
+ * @example
2947
+ * ```ts
2948
+ * await flights
2949
+ * .distances("origin", "destination", "A", {
2950
+ * startTimeColumn: "departure",
2951
+ * endTimeColumn: "arrival",
2952
+ * minGapMs: 60 * 60 * 1000,
2953
+ * elapsedTime: true,
2954
+ * })
2955
+ * .log();
2956
+ * ```
2957
+ *
2958
+ * | start | node | steps | elapsedTimeMs |
2959
+ * | --- | --- | ---: | ---: |
2960
+ * | A | B | 1 | 3600000 |
2961
+ * | A | C | 1 | 10800000 |
2962
+ *
2963
+ * The direct flight to C takes three hours (10,800,000 milliseconds).
2964
+ * The route through B takes four hours including its layover.
2965
+ *
2966
+ * Find the fastest journeys from A while also adding up their prices:
2967
+ *
2968
+ * @example
2969
+ * ```ts
2970
+ * await flights
2971
+ * .distances("origin", "destination", "A", {
2972
+ * startTimeColumn: "departure",
2973
+ * endTimeColumn: "arrival",
2974
+ * minGapMs: 60 * 60 * 1000,
2975
+ * elapsedTime: true,
2976
+ * weight: "price",
2977
+ * minimize: "elapsedTime",
2978
+ * })
2979
+ * .log();
2980
+ * ```
2981
+ *
2982
+ * | start | node | steps | total | elapsedTimeMs |
2983
+ * | --- | --- | ---: | ---: | ---: |
2984
+ * | A | B | 1 | 40 | 3600000 |
2985
+ * | A | C | 1 | 120 | 10800000 |
2986
+ *
2987
+ * Use `minimize: "weight"` to find the cheapest journeys instead. The
2988
+ * selected route to C now takes two steps through B and costs 80:
2989
+ *
2990
+ * @example
2991
+ * ```ts
2992
+ * await flights
2993
+ * .distances("origin", "destination", "A", {
2994
+ * startTimeColumn: "departure",
2995
+ * endTimeColumn: "arrival",
2996
+ * minGapMs: 60 * 60 * 1000,
2997
+ * elapsedTime: true,
2998
+ * weight: "price",
2999
+ * minimize: "weight",
3000
+ * })
3001
+ * .log();
3002
+ * ```
3003
+ *
3004
+ * | start | node | steps | total | elapsedTimeMs |
3005
+ * | --- | --- | ---: | ---: | ---: |
3006
+ * | A | B | 1 | 40 | 3600000 |
3007
+ * | A | C | 2 | 80 | 14400000 |
3008
+ *
3009
+ * Choose the fewest connections while still reporting price and elapsed
3010
+ * time. The direct flight to C has one step, even though it costs more:
3011
+ *
3012
+ * @example
3013
+ * ```ts
3014
+ * await flights
3015
+ * .distances("origin", "destination", "A", {
3016
+ * startTimeColumn: "departure",
3017
+ * endTimeColumn: "arrival",
3018
+ * minGapMs: 60 * 60 * 1000,
3019
+ * elapsedTime: true,
3020
+ * weight: "price",
3021
+ * minimize: "steps",
3022
+ * })
3023
+ * .log();
3024
+ * ```
3025
+ *
3026
+ * | start | node | steps | total | elapsedTimeMs |
3027
+ * | --- | --- | ---: | ---: | ---: |
3028
+ * | A | B | 1 | 40 | 3600000 |
3029
+ * | A | C | 1 | 120 | 10800000 |
3030
+ *
3031
+ * When two routes to C both take two steps but have different prices,
3032
+ * minimizing steps while reporting price returns both summaries:
3033
+ *
3034
+ * @example
3035
+ * ```ts
3036
+ * await connections
3037
+ * .loadArray([
3038
+ * { origin: "A", destination: "B", price: 20 },
3039
+ * { origin: "B", destination: "C", price: 30 },
3040
+ * { origin: "A", destination: "D", price: 40 },
3041
+ * { origin: "D", destination: "C", price: 40 },
3042
+ * ])
3043
+ * .distances("origin", "destination", "A", {
3044
+ * weight: "price",
3045
+ * minimize: "steps",
3046
+ * })
3047
+ * .filter("node = 'C'")
3048
+ * .log();
3049
+ * ```
3050
+ *
3051
+ * | start | node | steps | total |
3052
+ * | --- | --- | ---: | ---: |
3053
+ * | A | C | 2 | 50 |
3054
+ * | A | C | 2 | 80 |
2951
3055
  *
2952
3056
  * @param sourceColumn - The name of the column containing each connection's source node ID.
2953
3057
  * @param targetColumn - The name of the column containing each connection's target node ID.
2954
- * @param startNodes - One starting node ID or an array of distinct starting node IDs.
3058
+ * @param startNodes - One starting node ID or a non-empty array of distinct IDs. Unknown IDs and starts with no connections to follow produce no rows. Empty arrays and duplicate IDs throw an error.
2955
3059
  * @param options - An optional object with direction, time, and result configuration.
2956
- * @param options.direction - The direction in which to follow connections. Defaults to `"outgoing"`.
3060
+ * @param options.direction - The direction in which to follow connections. Defaults to `"outgoing"`. Chronological traversal supports only `"outgoing"` and `"incoming"`.
2957
3061
  * @param options.startTimeColumn - The name of the column containing each connection's start time. Use this or `endTimeColumn` to follow connections in chronological order.
2958
3062
  * @param options.endTimeColumn - The name of the column containing each connection's end time. Use this or `startTimeColumn` to follow connections in chronological order.
2959
- * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3063
+ * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds; does not apply before the first connection. With both time columns, measured from one connection's end to the next's start; with one column, between timestamps. Must be a non-negative integer. Defaults to `0`. Requires a time column.
2960
3064
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
2961
- * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3065
+ * @param options.weight - The name of the numeric column used as the cost of each connection. Values must be non-null, finite, and non-negative. Adds `total`, the cumulative sum of those costs. If omitted, no `total` column is generated.
3066
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns. Optimization compares native timestamp precision before conversion to milliseconds.
3067
+ * @param options.minimize - The metric used to select optimal routes: `"steps"`, `"weight"`, or `"elapsedTime"`. Defaults to `"weight"` when only `weight` is enabled, `"elapsedTime"` when only elapsed-time reporting is enabled, and `"steps"` when neither is enabled. Required when both are enabled. `"steps"` is always available; the other metrics require their corresponding options.
2962
3068
  * @param options.outputTable - If `true`, stores the result in a new table with a generated name. If a string, uses it as the new table's name. If `false` or omitted, overwrites the current table. Defaults to `false`.
2963
- * @returns The result table, so methods can be chained.
3069
+ * @returns The table of distinct optimal summaries with `start`, `node`, and `steps`, plus `total` when `weight` is supplied and `elapsedTimeMs` when enabled, so methods can be chained. Sorted by start, the chosen metric, node, then remaining metrics in the order steps, total, elapsed time.
2964
3070
  * @category Graph Operations
2965
3071
  */
2966
3072
  distances(sourceColumn, targetColumn, startNodes, options = {}) {
@@ -2981,15 +3087,17 @@ class SimpleTable extends Simple {
2981
3087
  * containing these IDs as the `edgeId` argument. If your table is missing
2982
3088
  * an ID column, you can easily create one with `addId()`.
2983
3089
  *
2984
- * The result starts with the `pathId`, `step`, `weight`, and `total`
2985
- * columns, followed by all original columns. Steps start at one and follow
2986
- * the search direction. The `weight` column is the connection cost, and
2987
- * `total` is the sum of those costs up to and including the current step.
2988
- * Without the `weight` option, each connection costs one.
3090
+ * The result starts with `pathId`, `step`, and `weight`, followed by the
3091
+ * optional metric columns and all original columns. Steps start at one and
3092
+ * follow the search direction. The `weight` column is the connection cost,
3093
+ * or one when no `weight` option is supplied. Supplying `weight` also adds
3094
+ * `total`, the sum of those costs up to and including the current step.
3095
+ * Enabling `elapsedTime` adds cumulative `elapsedTimeMs`, including gaps.
2989
3096
  *
2990
- * If an input column is already named `pathId`, `step`, `weight`, or `total`
2991
- * (regardless of capitalization), the method throws an error. Rename it
2992
- * with `renameColumns()` first.
3097
+ * If an input column conflicts with a generated result column (regardless
3098
+ * of capitalization), the method throws an error. Rename it with
3099
+ * `renameColumns()` first. `total` is reserved only when `weight` is supplied,
3100
+ * and `elapsedTimeMs` only when elapsed-time reporting is enabled.
2993
3101
  *
2994
3102
  * Each row is one connection along a route.
2995
3103
  *
@@ -3004,6 +3112,16 @@ class SimpleTable extends Simple {
3004
3112
  * The minimum gap applies only between consecutive connections, not before
3005
3113
  * the first connection.
3006
3114
  *
3115
+ * Use `minimize: "steps"` to choose the fewest connections even when weight
3116
+ * or elapsed-time reporting is enabled. Without an explicit `minimize`, the
3117
+ * method minimizes weight when only `weight` is enabled, elapsed time when
3118
+ * only `elapsedTime` is enabled, and steps when neither is enabled. With
3119
+ * both enabled, specify `"steps"`, `"weight"`, or `"elapsedTime"` explicitly.
3120
+ * Elapsed-time reporting requires both time columns.
3121
+ *
3122
+ * All routes tied on the selected metric are returned, even if their other
3123
+ * metrics differ. Each route reports its own weights and elapsed times.
3124
+ *
3007
3125
  * Routes are numbered from zero by comparing their sequences of connection
3008
3126
  * IDs, element by element. Rows are sorted by `pathId`, then `step`.
3009
3127
  *
@@ -3034,14 +3152,14 @@ class SimpleTable extends Simple {
3034
3152
  * .log();
3035
3153
  * ```
3036
3154
  *
3037
- * | pathId | step | weight | total | edgeId | source | target |
3038
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3039
- * | 0 | 1 | 1 | 1 | E1 | A | B |
3040
- * | 0 | 2 | 1 | 2 | E3 | B | D |
3041
- * | 0 | 3 | 1 | 3 | E5 | D | E |
3042
- * | 1 | 1 | 1 | 1 | E2 | A | C |
3043
- * | 1 | 2 | 1 | 2 | E4 | C | D |
3044
- * | 1 | 3 | 1 | 3 | E5 | D | E |
3155
+ * | pathId | step | weight | edgeId | source | target |
3156
+ * | ---: | ---: | ---: | --- | --- | --- |
3157
+ * | 0 | 1 | 1 | E1 | A | B |
3158
+ * | 0 | 2 | 1 | E3 | B | D |
3159
+ * | 0 | 3 | 1 | E5 | D | E |
3160
+ * | 1 | 1 | 1 | E2 | A | C |
3161
+ * | 1 | 2 | 1 | E4 | C | D |
3162
+ * | 1 | 3 | 1 | E5 | D | E |
3045
3163
  *
3046
3164
  * For an input without connection IDs, use `addId()` first:
3047
3165
  *
@@ -3060,10 +3178,10 @@ class SimpleTable extends Simple {
3060
3178
  * .log();
3061
3179
  * ```
3062
3180
  *
3063
- * | pathId | step | weight | total | source | target | edgeId |
3064
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3065
- * | 0 | 1 | 1 | 1 | A | B | edge-0 |
3066
- * | 0 | 2 | 1 | 2 | B | E | edge-1 |
3181
+ * | pathId | step | weight | source | target | edgeId |
3182
+ * | ---: | ---: | ---: | --- | --- | --- |
3183
+ * | 0 | 1 | 1 | A | B | edge-0 |
3184
+ * | 0 | 2 | 1 | B | E | edge-1 |
3067
3185
  *
3068
3186
  * The next two examples each start with these flights. The direct flight
3069
3187
  * takes ten minutes; the route through B and D takes three:
@@ -3103,9 +3221,9 @@ class SimpleTable extends Simple {
3103
3221
  * .log();
3104
3222
  * ```
3105
3223
  *
3106
- * | pathId | step | weight | total | flightId | origin | destination | minutes |
3107
- * | ---: | ---: | ---: | ---: | --- | --- | --- | ---: |
3108
- * | 0 | 1 | 1 | 1 | F1 | A | E | 10 |
3224
+ * | pathId | step | weight | flightId | origin | destination | minutes |
3225
+ * | ---: | ---: | ---: | --- | --- | --- | ---: |
3226
+ * | 0 | 1 | 1 | F1 | A | E | 10 |
3109
3227
  *
3110
3228
  * With time options, the cheaper route through B is ruled out because F2
3111
3229
  * leaves before F1 arrives. The route through C meets the one-hour minimum
@@ -3152,9 +3270,87 @@ class SimpleTable extends Simple {
3152
3270
  * .log();
3153
3271
  * ```
3154
3272
  *
3155
- * | pathId | step | weight | total | edgeId | source | target |
3156
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3157
- * | 0 | 1 | 1 | 1 | F1 | A | B |
3273
+ * | pathId | step | weight | edgeId | source | target |
3274
+ * | ---: | ---: | ---: | --- | --- | --- |
3275
+ * | 0 | 1 | 1 | F1 | A | B |
3276
+ *
3277
+ * For the next three examples, `flights` contains these rows, with departure
3278
+ * and arrival stored as timestamps on the same day:
3279
+ *
3280
+ * | flightId | origin | destination | departure | arrival | price |
3281
+ * | --- | --- | --- | --- | --- | ---: |
3282
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3283
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
3284
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
3285
+ * | F4 | A | D | 2025-01-01 09:00 | 2025-01-01 09:30 | 60 |
3286
+ * | F5 | D | C | 2025-01-01 10:30 | 2025-01-01 11:00 | 80 |
3287
+ *
3288
+ * Find the fastest journey from A to C, including layovers:
3289
+ *
3290
+ * @example
3291
+ * ```ts
3292
+ * await flights
3293
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3294
+ * startTimeColumn: "departure",
3295
+ * endTimeColumn: "arrival",
3296
+ * minGapMs: 60 * 60 * 1000,
3297
+ * elapsedTime: true,
3298
+ * })
3299
+ * .log();
3300
+ * ```
3301
+ *
3302
+ * | pathId | step | weight | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3303
+ * | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3304
+ * | 0 | 1 | 1 | 1800000 | F4 | A | D | 2025-01-01 09:00:00 | 2025-01-01 09:30:00 | 60 |
3305
+ * | 0 | 2 | 1 | 7200000 | F5 | D | C | 2025-01-01 10:30:00 | 2025-01-01 11:00:00 | 80 |
3306
+ *
3307
+ * The route through D takes two hours (7,200,000 milliseconds), including
3308
+ * a one-hour layover. The direct flight takes three hours.
3309
+ *
3310
+ * Find the fastest journey while also adding up its price:
3311
+ *
3312
+ * @example
3313
+ * ```ts
3314
+ * await flights
3315
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3316
+ * startTimeColumn: "departure",
3317
+ * endTimeColumn: "arrival",
3318
+ * minGapMs: 60 * 60 * 1000,
3319
+ * elapsedTime: true,
3320
+ * weight: "price",
3321
+ * minimize: "elapsedTime",
3322
+ * })
3323
+ * .log();
3324
+ * ```
3325
+ *
3326
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3327
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3328
+ * | 0 | 1 | 60 | 60 | 1800000 | F4 | A | D | 2025-01-01 09:00:00 | 2025-01-01 09:30:00 | 60 |
3329
+ * | 0 | 2 | 80 | 140 | 7200000 | F5 | D | C | 2025-01-01 10:30:00 | 2025-01-01 11:00:00 | 80 |
3330
+ *
3331
+ * Use `minimize: "weight"` to find the cheapest journey instead.
3332
+ * All ties on the chosen metric are returned.
3333
+ *
3334
+ * Choose the fewest flights while still reporting price and elapsed time.
3335
+ * The direct flight takes one step, although the route through D is faster:
3336
+ *
3337
+ * @example
3338
+ * ```ts
3339
+ * await flights
3340
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3341
+ * startTimeColumn: "departure",
3342
+ * endTimeColumn: "arrival",
3343
+ * minGapMs: 60 * 60 * 1000,
3344
+ * elapsedTime: true,
3345
+ * weight: "price",
3346
+ * minimize: "steps",
3347
+ * })
3348
+ * .log();
3349
+ * ```
3350
+ *
3351
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3352
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3353
+ * | 0 | 1 | 120 | 120 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3158
3354
  *
3159
3355
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3160
3356
  * @param targetColumn - The name of the column containing each connection's target node ID.
@@ -3167,9 +3363,11 @@ class SimpleTable extends Simple {
3167
3363
  * @param options.endTimeColumn - The name of the column containing each connection's end time. Use this or `startTimeColumn` to follow connections in chronological order.
3168
3364
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3169
3365
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3170
- * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3366
+ * @param options.weight - The name of the numeric column used as the cost of each connection. Adds `total`, the cumulative sum of those costs. If omitted, no `total` column is generated.
3367
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3368
+ * @param options.minimize - The metric used to select optimal routes: `"steps"`, `"weight"`, or `"elapsedTime"`. Defaults to `"weight"` when only `weight` is enabled, `"elapsedTime"` when only elapsed-time reporting is enabled, and `"steps"` when neither is enabled. Required when both are enabled. `"steps"` is always available; the other metrics require their corresponding options.
3171
3369
  * @param options.outputTable - If `true`, stores the result in a new table with a generated name. If a string, uses it as the new table's name. If `false` or omitted, overwrites the current table. Defaults to `false`.
3172
- * @returns The result table, so methods can be chained.
3370
+ * @returns The table of route connections with optional cumulative `total` and `elapsedTimeMs` metrics, so methods can be chained.
3173
3371
  * @category Graph Operations
3174
3372
  */
3175
3373
  shortestPath(sourceColumn, targetColumn, edgeId, start, end, options = {}) {
@@ -3381,6 +3579,59 @@ class SimpleTable extends Simple {
3381
3579
  * | 0 | 1 | 3 | 3 | F3 | B | D | 2025-01-01 11:00:00 | 2025-01-01 12:00:00 | 3 |
3382
3580
  * | 0 | 2 | 2 | 5 | F1 | A | B | 2025-01-01 08:00:00 | 2025-01-01 10:00:00 | 2 |
3383
3581
  *
3582
+ * For the next two examples, `flights` contains these rows, with departure
3583
+ * and arrival stored as timestamps on the same day:
3584
+ *
3585
+ * | flightId | origin | destination | departure | arrival | price |
3586
+ * | --- | --- | --- | --- | --- | ---: |
3587
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3588
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
3589
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
3590
+ *
3591
+ * Report elapsed time for every path, including layovers:
3592
+ *
3593
+ * @example
3594
+ * ```ts
3595
+ * await flights
3596
+ * .paths("origin", "destination", "flightId", "A", "C", {
3597
+ * startTimeColumn: "departure",
3598
+ * endTimeColumn: "arrival",
3599
+ * minGapMs: 60 * 60 * 1000,
3600
+ * elapsedTime: true,
3601
+ * })
3602
+ * .log();
3603
+ * ```
3604
+ *
3605
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3606
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3607
+ * | 0 | 1 | 1 | 1 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3608
+ * | 0 | 2 | 1 | 2 | 14400000 | F2 | B | C | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 40 |
3609
+ * | 1 | 1 | 1 | 1 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3610
+ *
3611
+ * The route through B takes four hours (14,400,000 milliseconds),
3612
+ * including its two-hour layover. The direct flight takes three hours.
3613
+ *
3614
+ * Add up prices while continuing to report elapsed time for every path:
3615
+ *
3616
+ * @example
3617
+ * ```ts
3618
+ * await flights
3619
+ * .paths("origin", "destination", "flightId", "A", "C", {
3620
+ * startTimeColumn: "departure",
3621
+ * endTimeColumn: "arrival",
3622
+ * minGapMs: 60 * 60 * 1000,
3623
+ * elapsedTime: true,
3624
+ * weight: "price",
3625
+ * })
3626
+ * .log();
3627
+ * ```
3628
+ *
3629
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3630
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3631
+ * | 0 | 1 | 40 | 40 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3632
+ * | 0 | 2 | 40 | 80 | 14400000 | F2 | B | C | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 40 |
3633
+ * | 1 | 1 | 120 | 120 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3634
+ *
3384
3635
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3385
3636
  * @param targetColumn - The name of the column containing each connection's target node ID.
3386
3637
  * @param edgeId - The name of the column uniquely identifying each connection (edge).
@@ -3393,6 +3644,7 @@ class SimpleTable extends Simple {
3393
3644
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3394
3645
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3395
3646
  * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3647
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3396
3648
  * @param options.outputTable - If `true`, stores the result in a new table with a generated name. If a string, uses it as the new table's name. If `false` or omitted, overwrites the current table. Defaults to `false`.
3397
3649
  * @returns The result table, so methods can be chained.
3398
3650
  * @category Graph Operations
@@ -3648,6 +3900,56 @@ class SimpleTable extends Simple {
3648
3900
  * | B | 0 | 2 | 1 | 2 | F2 | C | A | 2025-01-01 10:00:00 |
3649
3901
  * | B | 0 | 3 | 1 | 3 | F1 | B | C | 2025-01-01 09:00:00 |
3650
3902
  *
3903
+ * For the next two examples, `flights` contains these rows, with departure
3904
+ * and arrival stored as timestamps on the same day:
3905
+ *
3906
+ * | flightId | origin | destination | departure | arrival | price |
3907
+ * | --- | --- | --- | --- | --- | ---: |
3908
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3909
+ * | F2 | B | A | 2025-01-01 12:00 | 2025-01-01 13:00 | 60 |
3910
+ *
3911
+ * Report elapsed time for every cycle, including layovers:
3912
+ *
3913
+ * @example
3914
+ * ```ts
3915
+ * await flights
3916
+ * .findCycles("origin", "destination", "flightId", "A", {
3917
+ * startTimeColumn: "departure",
3918
+ * endTimeColumn: "arrival",
3919
+ * minGapMs: 60 * 60 * 1000,
3920
+ * elapsedTime: true,
3921
+ * })
3922
+ * .log();
3923
+ * ```
3924
+ *
3925
+ * | start | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3926
+ * | --- | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3927
+ * | A | 0 | 1 | 1 | 1 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3928
+ * | A | 0 | 2 | 1 | 2 | 14400000 | F2 | B | A | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 60 |
3929
+ *
3930
+ * The return journey takes four hours (14,400,000 milliseconds),
3931
+ * including the two-hour layover at B.
3932
+ *
3933
+ * Add up prices while continuing to report elapsed time for every cycle:
3934
+ *
3935
+ * @example
3936
+ * ```ts
3937
+ * await flights
3938
+ * .findCycles("origin", "destination", "flightId", "A", {
3939
+ * startTimeColumn: "departure",
3940
+ * endTimeColumn: "arrival",
3941
+ * minGapMs: 60 * 60 * 1000,
3942
+ * elapsedTime: true,
3943
+ * weight: "price",
3944
+ * })
3945
+ * .log();
3946
+ * ```
3947
+ *
3948
+ * | start | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3949
+ * | --- | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3950
+ * | A | 0 | 1 | 40 | 40 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3951
+ * | A | 0 | 2 | 60 | 100 | 14400000 | F2 | B | A | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 60 |
3952
+ *
3651
3953
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3652
3954
  * @param targetColumn - The name of the column containing each connection's target node ID.
3653
3955
  * @param edgeId - The name of the column uniquely identifying each connection (edge).
@@ -3659,6 +3961,7 @@ class SimpleTable extends Simple {
3659
3961
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3660
3962
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3661
3963
  * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3964
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3662
3965
  * @param options.outputTable - If `true`, stores the result in a new table with a generated name. If a string, uses it as the new table's name. If `false` or omitted, overwrites the current table. Defaults to `false`.
3663
3966
  * @returns The result table, so methods can be chained.
3664
3967
  * @category Graph Operations
@@ -8,5 +8,5 @@ export type GraphTemporalCostStateSql = {
8
8
  withClause: string;
9
9
  };
10
10
  /** Builds keyed best-cost chronological states from an arbitrary start relation. */
11
- export default function buildGraphTemporalCostStateSql(prepared: PreparedGraphSql, startsSelect: string | ((validEdgesRelation: string) => string), direction: Exclude<GraphDirection, "both">, temporal: PreparedGraphTemporalSql, distanceType: string, edgeWeight: string, eventSelections?: string[]): GraphTemporalCostStateSql;
11
+ export default function buildGraphTemporalCostStateSql(prepared: PreparedGraphSql, startsSelect: string | ((validEdgesRelation: string) => string), direction: Exclude<GraphDirection, "both">, temporal: PreparedGraphTemporalSql, distanceType: string, edgeWeight: string, eventSelections?: string[], minimize?: "weight" | "steps"): GraphTemporalCostStateSql;
12
12
  //# sourceMappingURL=buildGraphTemporalCostStateSql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"buildGraphTemporalCostStateSql.d.ts","sourceRoot":"","sources":["../../src/helpers/buildGraphTemporalCostStateSql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,MAAM,yBAAyB,GAAG;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,8BAA8B,CACpD,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAC,EAC/D,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,EAC1C,QAAQ,EAAE,wBAAwB,EAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAM,EAAO,GAC7B,yBAAyB,CAuF3B"}
1
+ {"version":3,"file":"buildGraphTemporalCostStateSql.d.ts","sourceRoot":"","sources":["../../src/helpers/buildGraphTemporalCostStateSql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EACjB,MAAM,4BAA4B,CAAC;AAGpC,MAAM,MAAM,yBAAyB,GAAG;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,OAAO,UAAU,8BAA8B,CACpD,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,EAAE,MAAM,GAAG,CAAC,CAAC,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAC,EAC/D,SAAS,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,EAC1C,QAAQ,EAAE,wBAAwB,EAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,MAAM,EAAO,EAC9B,QAAQ,GAAE,QAAQ,GAAG,OAAkB,GACtC,yBAAyB,CAyG3B"}