@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
@@ -2775,42 +2775,24 @@ class SimpleTable extends Simple_js_1.default {
2775
2775
  return (0, topologicalSort_js_1.default)(this, sourceColumn, targetColumn, options);
2776
2776
  }
2777
2777
  /**
2778
- * Finds the shortest distance from each starting node to every node it can
2779
- * reach by following one or more connections. By default, distance is the
2780
- * number of connections along the shortest route. Use the `weight` option
2781
- * to find the smallest sum of values from a numeric column, such as travel
2782
- * time.
2778
+ * Finds the shortest routes from each starting node to every reachable
2779
+ * node. Without options, shortest means the fewest connections. Use `weight`
2780
+ * to report total cost and `elapsedTime` to report duration including waiting
2781
+ * between connections. Use `minimize` to choose which metric defines shortest.
2783
2782
  *
2784
- * The `direction` option lets you follow connections from source to target,
2785
- * from target to source, or in either direction. The result has `start`,
2786
- * `node`, and `distance` columns, sorted by `start`, then by increasing
2787
- * `distance`, then by `node` to break ties. The closest nodes appear first
2788
- * for each start.
2789
- *
2790
- * Each row gives the shortest distance from `start` to `node`. Intermediate
2791
- * steps along the route are not returned. To get the steps between two
2792
- * different nodes, use `shortestPath()` for the shortest routes or `paths()`
2793
- * for all routes without repeated nodes.
2783
+ * Each row contains `start`, `node`, and `steps`, plus `total` when `weight`
2784
+ * is supplied and `elapsedTimeMs` when enabled. Routes tied on the chosen
2785
+ * metric produce separate rows only when their reported summaries differ;
2786
+ * identical summaries appear once.
2794
2787
  *
2795
- * A starting node appears in its own results only when a self-connection
2796
- * or a route leads back to it. Its distance is the shortest actual return
2797
- * route, using at least one connection. With `direction: "both"`, this
2798
- * can mean following the same connection out and back.
2788
+ * Routes cannot repeat nodes except for a final return to the start. A start
2789
+ * appears in its own results only through an actual return or self-connection,
2790
+ * never with zero steps. With `direction: "both"`, a return can follow the
2791
+ * same connection out and back. Use `shortestPath()` to inspect individual
2792
+ * connections between two different nodes.
2799
2793
  *
2800
- * Unknown starting IDs and starts with no connections to follow produce
2801
- * no rows. Empty start arrays and duplicate starting IDs throw an error.
2802
- * Weights must be non-null, finite, and non-negative.
2803
- *
2804
- * Use the `startTimeColumn` or `endTimeColumn` options to follow connections
2805
- * in chronological order. The `minGapMs` option sets the minimum gap between
2806
- * consecutive connections, in milliseconds. With both time columns, gaps are
2807
- * measured from one connection's end to the next connection's start; with one
2808
- * column, between their timestamps. The `strictOrdering` option defaults to
2809
- * `true`, rejecting zero-duration gaps. These options only work with
2810
- * `direction: "outgoing"` or `direction: "incoming"`.
2811
- *
2812
- * The minimum gap applies only between consecutive connections, not before
2813
- * the first connection.
2794
+ * Reporting weight or elapsed time can require substantial time and memory
2795
+ * on dense networks because many routes may need to be explored.
2814
2796
  *
2815
2797
  * The next five examples each start with this data:
2816
2798
  *
@@ -2830,12 +2812,12 @@ class SimpleTable extends Simple_js_1.default {
2830
2812
  * .log();
2831
2813
  * ```
2832
2814
  *
2833
- * | start | node | distance |
2815
+ * | start | node | steps |
2834
2816
  * | --- | --- | ---: |
2835
2817
  * | A | B | 1 |
2836
2818
  * | A | C | 2 |
2837
2819
  *
2838
- * With `weight: "minutes"`, distance is the shortest total travel time:
2820
+ * With `weight: "minutes"`, `total` is the sum of travel times:
2839
2821
  *
2840
2822
  * @example
2841
2823
  * ```ts
@@ -2844,10 +2826,10 @@ class SimpleTable extends Simple_js_1.default {
2844
2826
  * .log();
2845
2827
  * ```
2846
2828
  *
2847
- * | start | node | distance |
2848
- * | --- | --- | ---: |
2849
- * | A | B | 4 |
2850
- * | A | C | 5 |
2829
+ * | start | node | steps | total |
2830
+ * | --- | --- | ---: | ---: |
2831
+ * | A | B | 1 | 4 |
2832
+ * | A | C | 2 | 5 |
2851
2833
  *
2852
2834
  * With `direction: "incoming"`, connections are followed from target to
2853
2835
  * source. Starting at C:
@@ -2859,7 +2841,7 @@ class SimpleTable extends Simple_js_1.default {
2859
2841
  * .log();
2860
2842
  * ```
2861
2843
  *
2862
- * | start | node | distance |
2844
+ * | start | node | steps |
2863
2845
  * | --- | --- | ---: |
2864
2846
  * | C | B | 1 |
2865
2847
  * | C | A | 2 |
@@ -2875,14 +2857,14 @@ class SimpleTable extends Simple_js_1.default {
2875
2857
  * .log();
2876
2858
  * ```
2877
2859
  *
2878
- * | start | node | distance |
2860
+ * | start | node | steps |
2879
2861
  * | --- | --- | ---: |
2880
2862
  * | A | B | 1 |
2881
2863
  * | A | A | 2 |
2882
2864
  * | A | C | 2 |
2883
2865
  * | A | D | 2 |
2884
2866
  *
2885
- * A appears at distance 2 because A → B → A follows a connection out
2867
+ * A appears with 2 steps because A → B → A follows a connection out
2886
2868
  * and back.
2887
2869
  *
2888
2870
  * An array of starting nodes gives separate distances for each start:
@@ -2896,12 +2878,12 @@ class SimpleTable extends Simple_js_1.default {
2896
2878
  * .log();
2897
2879
  * ```
2898
2880
  *
2899
- * | start | node | distance |
2900
- * | --- | --- | ---: |
2901
- * | A | B | 4 |
2902
- * | A | C | 5 |
2903
- * | D | B | 2 |
2904
- * | D | C | 3 |
2881
+ * | start | node | steps | total |
2882
+ * | --- | --- | ---: | ---: |
2883
+ * | A | B | 1 | 4 |
2884
+ * | A | C | 2 | 5 |
2885
+ * | D | B | 1 | 2 |
2886
+ * | D | C | 2 | 3 |
2905
2887
  *
2906
2888
  * A direct self-connection and a longer return route can both lead back
2907
2889
  * to the start. This example uses different data:
@@ -2922,13 +2904,13 @@ class SimpleTable extends Simple_js_1.default {
2922
2904
  * .log();
2923
2905
  * ```
2924
2906
  *
2925
- * | start | node | distance |
2926
- * | --- | --- | ---: |
2927
- * | A | B | 2 |
2928
- * | A | A | 5 |
2907
+ * | start | node | steps | total |
2908
+ * | --- | --- | ---: | ---: |
2909
+ * | A | B | 1 | 2 |
2910
+ * | A | A | 2 | 5 |
2929
2911
  *
2930
2912
  * Chronological options can rule out a cheaper sequence that departs too
2931
- * early. For this example, F2 leaves before F1 arrives, while F3 meets the
2913
+ * early. Here, B → C leaves before A → B arrives, while B → D meets the
2932
2914
  * one-hour minimum exactly:
2933
2915
  *
2934
2916
  * | origin | destination | departureTime | arrivalTime | minutes |
@@ -2949,23 +2931,147 @@ class SimpleTable extends Simple_js_1.default {
2949
2931
  * .log();
2950
2932
  * ```
2951
2933
  *
2952
- * | start | node | distance |
2953
- * | --- | --- | ---: |
2954
- * | A | B | 2 |
2955
- * | A | D | 5 |
2934
+ * | start | node | steps | total |
2935
+ * | --- | --- | ---: | ---: |
2936
+ * | A | B | 1 | 2 |
2937
+ * | A | D | 2 | 5 |
2938
+ *
2939
+ * For the next four examples, `flights` contains these rows, with departure
2940
+ * and arrival stored as timestamps on the same day:
2941
+ *
2942
+ * | flightId | origin | destination | departure | arrival | price |
2943
+ * | --- | --- | --- | --- | --- | ---: |
2944
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
2945
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
2946
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
2947
+ *
2948
+ * Find the fastest journey from A to each reachable destination, including
2949
+ * layovers:
2950
+ *
2951
+ * @example
2952
+ * ```ts
2953
+ * await flights
2954
+ * .distances("origin", "destination", "A", {
2955
+ * startTimeColumn: "departure",
2956
+ * endTimeColumn: "arrival",
2957
+ * minGapMs: 60 * 60 * 1000,
2958
+ * elapsedTime: true,
2959
+ * })
2960
+ * .log();
2961
+ * ```
2962
+ *
2963
+ * | start | node | steps | elapsedTimeMs |
2964
+ * | --- | --- | ---: | ---: |
2965
+ * | A | B | 1 | 3600000 |
2966
+ * | A | C | 1 | 10800000 |
2967
+ *
2968
+ * The direct flight to C takes three hours (10,800,000 milliseconds).
2969
+ * The route through B takes four hours including its layover.
2970
+ *
2971
+ * Find the fastest journeys from A while also adding up their prices:
2972
+ *
2973
+ * @example
2974
+ * ```ts
2975
+ * await flights
2976
+ * .distances("origin", "destination", "A", {
2977
+ * startTimeColumn: "departure",
2978
+ * endTimeColumn: "arrival",
2979
+ * minGapMs: 60 * 60 * 1000,
2980
+ * elapsedTime: true,
2981
+ * weight: "price",
2982
+ * minimize: "elapsedTime",
2983
+ * })
2984
+ * .log();
2985
+ * ```
2986
+ *
2987
+ * | start | node | steps | total | elapsedTimeMs |
2988
+ * | --- | --- | ---: | ---: | ---: |
2989
+ * | A | B | 1 | 40 | 3600000 |
2990
+ * | A | C | 1 | 120 | 10800000 |
2991
+ *
2992
+ * Use `minimize: "weight"` to find the cheapest journeys instead. The
2993
+ * selected route to C now takes two steps through B and costs 80:
2994
+ *
2995
+ * @example
2996
+ * ```ts
2997
+ * await flights
2998
+ * .distances("origin", "destination", "A", {
2999
+ * startTimeColumn: "departure",
3000
+ * endTimeColumn: "arrival",
3001
+ * minGapMs: 60 * 60 * 1000,
3002
+ * elapsedTime: true,
3003
+ * weight: "price",
3004
+ * minimize: "weight",
3005
+ * })
3006
+ * .log();
3007
+ * ```
3008
+ *
3009
+ * | start | node | steps | total | elapsedTimeMs |
3010
+ * | --- | --- | ---: | ---: | ---: |
3011
+ * | A | B | 1 | 40 | 3600000 |
3012
+ * | A | C | 2 | 80 | 14400000 |
3013
+ *
3014
+ * Choose the fewest connections while still reporting price and elapsed
3015
+ * time. The direct flight to C has one step, even though it costs more:
3016
+ *
3017
+ * @example
3018
+ * ```ts
3019
+ * await flights
3020
+ * .distances("origin", "destination", "A", {
3021
+ * startTimeColumn: "departure",
3022
+ * endTimeColumn: "arrival",
3023
+ * minGapMs: 60 * 60 * 1000,
3024
+ * elapsedTime: true,
3025
+ * weight: "price",
3026
+ * minimize: "steps",
3027
+ * })
3028
+ * .log();
3029
+ * ```
3030
+ *
3031
+ * | start | node | steps | total | elapsedTimeMs |
3032
+ * | --- | --- | ---: | ---: | ---: |
3033
+ * | A | B | 1 | 40 | 3600000 |
3034
+ * | A | C | 1 | 120 | 10800000 |
3035
+ *
3036
+ * When two routes to C both take two steps but have different prices,
3037
+ * minimizing steps while reporting price returns both summaries:
3038
+ *
3039
+ * @example
3040
+ * ```ts
3041
+ * await connections
3042
+ * .loadArray([
3043
+ * { origin: "A", destination: "B", price: 20 },
3044
+ * { origin: "B", destination: "C", price: 30 },
3045
+ * { origin: "A", destination: "D", price: 40 },
3046
+ * { origin: "D", destination: "C", price: 40 },
3047
+ * ])
3048
+ * .distances("origin", "destination", "A", {
3049
+ * weight: "price",
3050
+ * minimize: "steps",
3051
+ * })
3052
+ * .filter("node = 'C'")
3053
+ * .log();
3054
+ * ```
3055
+ *
3056
+ * | start | node | steps | total |
3057
+ * | --- | --- | ---: | ---: |
3058
+ * | A | C | 2 | 50 |
3059
+ * | A | C | 2 | 80 |
2956
3060
  *
2957
3061
  * @param sourceColumn - The name of the column containing each connection's source node ID.
2958
3062
  * @param targetColumn - The name of the column containing each connection's target node ID.
2959
- * @param startNodes - One starting node ID or an array of distinct starting node IDs.
3063
+ * @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.
2960
3064
  * @param options - An optional object with direction, time, and result configuration.
2961
- * @param options.direction - The direction in which to follow connections. Defaults to `"outgoing"`.
3065
+ * @param options.direction - The direction in which to follow connections. Defaults to `"outgoing"`. Chronological traversal supports only `"outgoing"` and `"incoming"`.
2962
3066
  * @param options.startTimeColumn - The name of the column containing each connection's start time. Use this or `endTimeColumn` to follow connections in chronological order.
2963
3067
  * @param options.endTimeColumn - The name of the column containing each connection's end time. Use this or `startTimeColumn` to follow connections in chronological order.
2964
- * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3068
+ * @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.
2965
3069
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
2966
- * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3070
+ * @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.
3071
+ * @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.
3072
+ * @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.
2967
3073
  * @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`.
2968
- * @returns The result table, so methods can be chained.
3074
+ * @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.
2969
3075
  * @category Graph Operations
2970
3076
  */
2971
3077
  distances(sourceColumn, targetColumn, startNodes, options = {}) {
@@ -2986,15 +3092,17 @@ class SimpleTable extends Simple_js_1.default {
2986
3092
  * containing these IDs as the `edgeId` argument. If your table is missing
2987
3093
  * an ID column, you can easily create one with `addId()`.
2988
3094
  *
2989
- * The result starts with the `pathId`, `step`, `weight`, and `total`
2990
- * columns, followed by all original columns. Steps start at one and follow
2991
- * the search direction. The `weight` column is the connection cost, and
2992
- * `total` is the sum of those costs up to and including the current step.
2993
- * Without the `weight` option, each connection costs one.
3095
+ * The result starts with `pathId`, `step`, and `weight`, followed by the
3096
+ * optional metric columns and all original columns. Steps start at one and
3097
+ * follow the search direction. The `weight` column is the connection cost,
3098
+ * or one when no `weight` option is supplied. Supplying `weight` also adds
3099
+ * `total`, the sum of those costs up to and including the current step.
3100
+ * Enabling `elapsedTime` adds cumulative `elapsedTimeMs`, including gaps.
2994
3101
  *
2995
- * If an input column is already named `pathId`, `step`, `weight`, or `total`
2996
- * (regardless of capitalization), the method throws an error. Rename it
2997
- * with `renameColumns()` first.
3102
+ * If an input column conflicts with a generated result column (regardless
3103
+ * of capitalization), the method throws an error. Rename it with
3104
+ * `renameColumns()` first. `total` is reserved only when `weight` is supplied,
3105
+ * and `elapsedTimeMs` only when elapsed-time reporting is enabled.
2998
3106
  *
2999
3107
  * Each row is one connection along a route.
3000
3108
  *
@@ -3009,6 +3117,16 @@ class SimpleTable extends Simple_js_1.default {
3009
3117
  * The minimum gap applies only between consecutive connections, not before
3010
3118
  * the first connection.
3011
3119
  *
3120
+ * Use `minimize: "steps"` to choose the fewest connections even when weight
3121
+ * or elapsed-time reporting is enabled. Without an explicit `minimize`, the
3122
+ * method minimizes weight when only `weight` is enabled, elapsed time when
3123
+ * only `elapsedTime` is enabled, and steps when neither is enabled. With
3124
+ * both enabled, specify `"steps"`, `"weight"`, or `"elapsedTime"` explicitly.
3125
+ * Elapsed-time reporting requires both time columns.
3126
+ *
3127
+ * All routes tied on the selected metric are returned, even if their other
3128
+ * metrics differ. Each route reports its own weights and elapsed times.
3129
+ *
3012
3130
  * Routes are numbered from zero by comparing their sequences of connection
3013
3131
  * IDs, element by element. Rows are sorted by `pathId`, then `step`.
3014
3132
  *
@@ -3039,14 +3157,14 @@ class SimpleTable extends Simple_js_1.default {
3039
3157
  * .log();
3040
3158
  * ```
3041
3159
  *
3042
- * | pathId | step | weight | total | edgeId | source | target |
3043
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3044
- * | 0 | 1 | 1 | 1 | E1 | A | B |
3045
- * | 0 | 2 | 1 | 2 | E3 | B | D |
3046
- * | 0 | 3 | 1 | 3 | E5 | D | E |
3047
- * | 1 | 1 | 1 | 1 | E2 | A | C |
3048
- * | 1 | 2 | 1 | 2 | E4 | C | D |
3049
- * | 1 | 3 | 1 | 3 | E5 | D | E |
3160
+ * | pathId | step | weight | edgeId | source | target |
3161
+ * | ---: | ---: | ---: | --- | --- | --- |
3162
+ * | 0 | 1 | 1 | E1 | A | B |
3163
+ * | 0 | 2 | 1 | E3 | B | D |
3164
+ * | 0 | 3 | 1 | E5 | D | E |
3165
+ * | 1 | 1 | 1 | E2 | A | C |
3166
+ * | 1 | 2 | 1 | E4 | C | D |
3167
+ * | 1 | 3 | 1 | E5 | D | E |
3050
3168
  *
3051
3169
  * For an input without connection IDs, use `addId()` first:
3052
3170
  *
@@ -3065,10 +3183,10 @@ class SimpleTable extends Simple_js_1.default {
3065
3183
  * .log();
3066
3184
  * ```
3067
3185
  *
3068
- * | pathId | step | weight | total | source | target | edgeId |
3069
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3070
- * | 0 | 1 | 1 | 1 | A | B | edge-0 |
3071
- * | 0 | 2 | 1 | 2 | B | E | edge-1 |
3186
+ * | pathId | step | weight | source | target | edgeId |
3187
+ * | ---: | ---: | ---: | --- | --- | --- |
3188
+ * | 0 | 1 | 1 | A | B | edge-0 |
3189
+ * | 0 | 2 | 1 | B | E | edge-1 |
3072
3190
  *
3073
3191
  * The next two examples each start with these flights. The direct flight
3074
3192
  * takes ten minutes; the route through B and D takes three:
@@ -3108,9 +3226,9 @@ class SimpleTable extends Simple_js_1.default {
3108
3226
  * .log();
3109
3227
  * ```
3110
3228
  *
3111
- * | pathId | step | weight | total | flightId | origin | destination | minutes |
3112
- * | ---: | ---: | ---: | ---: | --- | --- | --- | ---: |
3113
- * | 0 | 1 | 1 | 1 | F1 | A | E | 10 |
3229
+ * | pathId | step | weight | flightId | origin | destination | minutes |
3230
+ * | ---: | ---: | ---: | --- | --- | --- | ---: |
3231
+ * | 0 | 1 | 1 | F1 | A | E | 10 |
3114
3232
  *
3115
3233
  * With time options, the cheaper route through B is ruled out because F2
3116
3234
  * leaves before F1 arrives. The route through C meets the one-hour minimum
@@ -3157,9 +3275,87 @@ class SimpleTable extends Simple_js_1.default {
3157
3275
  * .log();
3158
3276
  * ```
3159
3277
  *
3160
- * | pathId | step | weight | total | edgeId | source | target |
3161
- * | ---: | ---: | ---: | ---: | --- | --- | --- |
3162
- * | 0 | 1 | 1 | 1 | F1 | A | B |
3278
+ * | pathId | step | weight | edgeId | source | target |
3279
+ * | ---: | ---: | ---: | --- | --- | --- |
3280
+ * | 0 | 1 | 1 | F1 | A | B |
3281
+ *
3282
+ * For the next three examples, `flights` contains these rows, with departure
3283
+ * and arrival stored as timestamps on the same day:
3284
+ *
3285
+ * | flightId | origin | destination | departure | arrival | price |
3286
+ * | --- | --- | --- | --- | --- | ---: |
3287
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3288
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
3289
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
3290
+ * | F4 | A | D | 2025-01-01 09:00 | 2025-01-01 09:30 | 60 |
3291
+ * | F5 | D | C | 2025-01-01 10:30 | 2025-01-01 11:00 | 80 |
3292
+ *
3293
+ * Find the fastest journey from A to C, including layovers:
3294
+ *
3295
+ * @example
3296
+ * ```ts
3297
+ * await flights
3298
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3299
+ * startTimeColumn: "departure",
3300
+ * endTimeColumn: "arrival",
3301
+ * minGapMs: 60 * 60 * 1000,
3302
+ * elapsedTime: true,
3303
+ * })
3304
+ * .log();
3305
+ * ```
3306
+ *
3307
+ * | pathId | step | weight | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3308
+ * | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3309
+ * | 0 | 1 | 1 | 1800000 | F4 | A | D | 2025-01-01 09:00:00 | 2025-01-01 09:30:00 | 60 |
3310
+ * | 0 | 2 | 1 | 7200000 | F5 | D | C | 2025-01-01 10:30:00 | 2025-01-01 11:00:00 | 80 |
3311
+ *
3312
+ * The route through D takes two hours (7,200,000 milliseconds), including
3313
+ * a one-hour layover. The direct flight takes three hours.
3314
+ *
3315
+ * Find the fastest journey while also adding up its price:
3316
+ *
3317
+ * @example
3318
+ * ```ts
3319
+ * await flights
3320
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3321
+ * startTimeColumn: "departure",
3322
+ * endTimeColumn: "arrival",
3323
+ * minGapMs: 60 * 60 * 1000,
3324
+ * elapsedTime: true,
3325
+ * weight: "price",
3326
+ * minimize: "elapsedTime",
3327
+ * })
3328
+ * .log();
3329
+ * ```
3330
+ *
3331
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3332
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3333
+ * | 0 | 1 | 60 | 60 | 1800000 | F4 | A | D | 2025-01-01 09:00:00 | 2025-01-01 09:30:00 | 60 |
3334
+ * | 0 | 2 | 80 | 140 | 7200000 | F5 | D | C | 2025-01-01 10:30:00 | 2025-01-01 11:00:00 | 80 |
3335
+ *
3336
+ * Use `minimize: "weight"` to find the cheapest journey instead.
3337
+ * All ties on the chosen metric are returned.
3338
+ *
3339
+ * Choose the fewest flights while still reporting price and elapsed time.
3340
+ * The direct flight takes one step, although the route through D is faster:
3341
+ *
3342
+ * @example
3343
+ * ```ts
3344
+ * await flights
3345
+ * .shortestPath("origin", "destination", "flightId", "A", "C", {
3346
+ * startTimeColumn: "departure",
3347
+ * endTimeColumn: "arrival",
3348
+ * minGapMs: 60 * 60 * 1000,
3349
+ * elapsedTime: true,
3350
+ * weight: "price",
3351
+ * minimize: "steps",
3352
+ * })
3353
+ * .log();
3354
+ * ```
3355
+ *
3356
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3357
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3358
+ * | 0 | 1 | 120 | 120 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3163
3359
  *
3164
3360
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3165
3361
  * @param targetColumn - The name of the column containing each connection's target node ID.
@@ -3172,9 +3368,11 @@ class SimpleTable extends Simple_js_1.default {
3172
3368
  * @param options.endTimeColumn - The name of the column containing each connection's end time. Use this or `startTimeColumn` to follow connections in chronological order.
3173
3369
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3174
3370
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3175
- * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3371
+ * @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.
3372
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3373
+ * @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.
3176
3374
  * @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`.
3177
- * @returns The result table, so methods can be chained.
3375
+ * @returns The table of route connections with optional cumulative `total` and `elapsedTimeMs` metrics, so methods can be chained.
3178
3376
  * @category Graph Operations
3179
3377
  */
3180
3378
  shortestPath(sourceColumn, targetColumn, edgeId, start, end, options = {}) {
@@ -3386,6 +3584,59 @@ class SimpleTable extends Simple_js_1.default {
3386
3584
  * | 0 | 1 | 3 | 3 | F3 | B | D | 2025-01-01 11:00:00 | 2025-01-01 12:00:00 | 3 |
3387
3585
  * | 0 | 2 | 2 | 5 | F1 | A | B | 2025-01-01 08:00:00 | 2025-01-01 10:00:00 | 2 |
3388
3586
  *
3587
+ * For the next two examples, `flights` contains these rows, with departure
3588
+ * and arrival stored as timestamps on the same day:
3589
+ *
3590
+ * | flightId | origin | destination | departure | arrival | price |
3591
+ * | --- | --- | --- | --- | --- | ---: |
3592
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3593
+ * | F2 | B | C | 2025-01-01 12:00 | 2025-01-01 13:00 | 40 |
3594
+ * | F3 | A | C | 2025-01-01 09:00 | 2025-01-01 12:00 | 120 |
3595
+ *
3596
+ * Report elapsed time for every path, including layovers:
3597
+ *
3598
+ * @example
3599
+ * ```ts
3600
+ * await flights
3601
+ * .paths("origin", "destination", "flightId", "A", "C", {
3602
+ * startTimeColumn: "departure",
3603
+ * endTimeColumn: "arrival",
3604
+ * minGapMs: 60 * 60 * 1000,
3605
+ * elapsedTime: true,
3606
+ * })
3607
+ * .log();
3608
+ * ```
3609
+ *
3610
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3611
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3612
+ * | 0 | 1 | 1 | 1 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3613
+ * | 0 | 2 | 1 | 2 | 14400000 | F2 | B | C | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 40 |
3614
+ * | 1 | 1 | 1 | 1 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3615
+ *
3616
+ * The route through B takes four hours (14,400,000 milliseconds),
3617
+ * including its two-hour layover. The direct flight takes three hours.
3618
+ *
3619
+ * Add up prices while continuing to report elapsed time for every path:
3620
+ *
3621
+ * @example
3622
+ * ```ts
3623
+ * await flights
3624
+ * .paths("origin", "destination", "flightId", "A", "C", {
3625
+ * startTimeColumn: "departure",
3626
+ * endTimeColumn: "arrival",
3627
+ * minGapMs: 60 * 60 * 1000,
3628
+ * elapsedTime: true,
3629
+ * weight: "price",
3630
+ * })
3631
+ * .log();
3632
+ * ```
3633
+ *
3634
+ * | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3635
+ * | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3636
+ * | 0 | 1 | 40 | 40 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3637
+ * | 0 | 2 | 40 | 80 | 14400000 | F2 | B | C | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 40 |
3638
+ * | 1 | 1 | 120 | 120 | 10800000 | F3 | A | C | 2025-01-01 09:00:00 | 2025-01-01 12:00:00 | 120 |
3639
+ *
3389
3640
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3390
3641
  * @param targetColumn - The name of the column containing each connection's target node ID.
3391
3642
  * @param edgeId - The name of the column uniquely identifying each connection (edge).
@@ -3398,6 +3649,7 @@ class SimpleTable extends Simple_js_1.default {
3398
3649
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3399
3650
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3400
3651
  * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3652
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3401
3653
  * @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`.
3402
3654
  * @returns The result table, so methods can be chained.
3403
3655
  * @category Graph Operations
@@ -3653,6 +3905,56 @@ class SimpleTable extends Simple_js_1.default {
3653
3905
  * | B | 0 | 2 | 1 | 2 | F2 | C | A | 2025-01-01 10:00:00 |
3654
3906
  * | B | 0 | 3 | 1 | 3 | F1 | B | C | 2025-01-01 09:00:00 |
3655
3907
  *
3908
+ * For the next two examples, `flights` contains these rows, with departure
3909
+ * and arrival stored as timestamps on the same day:
3910
+ *
3911
+ * | flightId | origin | destination | departure | arrival | price |
3912
+ * | --- | --- | --- | --- | --- | ---: |
3913
+ * | F1 | A | B | 2025-01-01 09:00 | 2025-01-01 10:00 | 40 |
3914
+ * | F2 | B | A | 2025-01-01 12:00 | 2025-01-01 13:00 | 60 |
3915
+ *
3916
+ * Report elapsed time for every cycle, including layovers:
3917
+ *
3918
+ * @example
3919
+ * ```ts
3920
+ * await flights
3921
+ * .findCycles("origin", "destination", "flightId", "A", {
3922
+ * startTimeColumn: "departure",
3923
+ * endTimeColumn: "arrival",
3924
+ * minGapMs: 60 * 60 * 1000,
3925
+ * elapsedTime: true,
3926
+ * })
3927
+ * .log();
3928
+ * ```
3929
+ *
3930
+ * | start | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3931
+ * | --- | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3932
+ * | A | 0 | 1 | 1 | 1 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3933
+ * | A | 0 | 2 | 1 | 2 | 14400000 | F2 | B | A | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 60 |
3934
+ *
3935
+ * The return journey takes four hours (14,400,000 milliseconds),
3936
+ * including the two-hour layover at B.
3937
+ *
3938
+ * Add up prices while continuing to report elapsed time for every cycle:
3939
+ *
3940
+ * @example
3941
+ * ```ts
3942
+ * await flights
3943
+ * .findCycles("origin", "destination", "flightId", "A", {
3944
+ * startTimeColumn: "departure",
3945
+ * endTimeColumn: "arrival",
3946
+ * minGapMs: 60 * 60 * 1000,
3947
+ * elapsedTime: true,
3948
+ * weight: "price",
3949
+ * })
3950
+ * .log();
3951
+ * ```
3952
+ *
3953
+ * | start | pathId | step | weight | total | elapsedTimeMs | flightId | origin | destination | departure | arrival | price |
3954
+ * | --- | ---: | ---: | ---: | ---: | ---: | --- | --- | --- | --- | --- | ---: |
3955
+ * | A | 0 | 1 | 40 | 40 | 3600000 | F1 | A | B | 2025-01-01 09:00:00 | 2025-01-01 10:00:00 | 40 |
3956
+ * | A | 0 | 2 | 60 | 100 | 14400000 | F2 | B | A | 2025-01-01 12:00:00 | 2025-01-01 13:00:00 | 60 |
3957
+ *
3656
3958
  * @param sourceColumn - The name of the column containing each connection's source node ID.
3657
3959
  * @param targetColumn - The name of the column containing each connection's target node ID.
3658
3960
  * @param edgeId - The name of the column uniquely identifying each connection (edge).
@@ -3664,6 +3966,7 @@ class SimpleTable extends Simple_js_1.default {
3664
3966
  * @param options.minGapMs - The minimum gap between consecutive connections, in milliseconds. Must be a non-negative integer. Defaults to `0`. Requires a time column.
3665
3967
  * @param options.strictOrdering - Whether to reject zero-duration gaps between consecutive connections (equal timestamps). Defaults to `true`. Requires a time column.
3666
3968
  * @param options.weight - The name of the numeric column used as the cost of each connection. If omitted, each connection costs one.
3969
+ * @param options.elapsedTime - Whether to add cumulative `elapsedTimeMs` in milliseconds, including connection gaps. Defaults to `false`. Requires both time columns.
3667
3970
  * @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`.
3668
3971
  * @returns The result table, so methods can be chained.
3669
3972
  * @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"}