sveltekit-ui 1.1.50 → 1.1.52
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/.vercel/output/config.json +4 -0
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/environment.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/index4.svelte.js +6 -4
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/internal.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/server.js +79 -28
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/entries/pages/trader/_page.server.js +295 -0
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/entries/pages/trader/_page.svelte.js +237 -0
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/0.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/1.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/2.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/3.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/4.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/5.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/6.js +1 -1
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/nodes/7.js +10 -0
- package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/vercel-tmp/manifest.js +10 -2
- package/.vercel/output/static/_app/immutable/assets/7.P3YGQ1pf.css +1 -0
- package/.vercel/output/static/_app/immutable/chunks/BAahZk91.js +1 -0
- package/.vercel/output/static/_app/immutable/chunks/{DytjpG3-.js → BPT8hUnt.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/{CYNOZRXD.js → BwSlGzN3.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/{CwRDtGo7.js → C1JBm0c-.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/{X7N3eqG8.js → C7ic0CC_.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/{DstdO2wO.js → C_Pzoflo.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/{DYeG_PLy.js → DthNgRcX.js} +1 -1
- package/.vercel/output/static/_app/immutable/chunks/dNI4qYWa.js +11 -0
- package/.vercel/output/static/_app/immutable/chunks/k2CTozZP.js +3 -0
- package/.vercel/output/static/_app/immutable/chunks/{DbQYcTxj.js → reUr01i3.js} +1 -1
- package/.vercel/output/static/_app/immutable/entry/app.BmAvfs9y.js +2 -0
- package/.vercel/output/static/_app/immutable/entry/start.BjMIYpc9.js +1 -0
- package/.vercel/output/static/_app/immutable/nodes/{0.DjBmDT2W.js → 0.Ny4VwAhi.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/1.DPmv3j1s.js +1 -0
- package/.vercel/output/static/_app/immutable/nodes/{2.B2Mv2js_.js → 2.WACi8m_j.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/{3.DfTdFu6f.js → 3.BR0VfEGG.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/{4.-NUgN-qG.js → 4.CaKMIjEy.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/{5.DQzwEh_Q.js → 5.CBcmyemr.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/{6.CHqFV7yW.js → 6.DBqG0cc_.js} +1 -1
- package/.vercel/output/static/_app/immutable/nodes/7.B7MLhsUA.js +1 -0
- package/.vercel/output/static/_app/version.json +1 -1
- package/dist/Components/Chart/index.svelte.js +5 -6
- package/package.json +4 -4
- package/src/lib/Components/Chart/index.svelte.js +5 -6
- package/.vercel/output/static/_app/immutable/chunks/CHLFeW6J.js +0 -1
- package/.vercel/output/static/_app/immutable/chunks/CQvXHdV8.js +0 -3
- package/.vercel/output/static/_app/immutable/chunks/qWZacszp.js +0 -11
- package/.vercel/output/static/_app/immutable/entry/app.icZmSapd.js +0 -2
- package/.vercel/output/static/_app/immutable/entry/start.CfrdPaSv.js +0 -1
- package/.vercel/output/static/_app/immutable/nodes/1.cXeHVOr1.js +0 -1
- /package/.vercel/output/static/_app/immutable/chunks/{C7Ex2Xh-.js → Du1izqHO.js} +0 -0
- /package/.vercel/output/static/_app/immutable/chunks/{B0BvW1x3.js → DxLN9Q9A.js} +0 -0
- /package/.vercel/output/static/_app/immutable/chunks/{Cfug8aQt.js → v_jBEYI6.js} +0 -0
package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/environment.js
CHANGED
|
@@ -37,7 +37,7 @@ function set_public_env(environment) {
|
|
|
37
37
|
}
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region \0virtual:__sveltekit/environment
|
|
40
|
-
var version = "
|
|
40
|
+
var version = "1774227794535";
|
|
41
41
|
var prerendering = false;
|
|
42
42
|
function set_building() {}
|
|
43
43
|
function set_prerendering() {
|
|
@@ -171,6 +171,7 @@ function create_chart_manager(config) {
|
|
|
171
171
|
const y_axis_width = 70;
|
|
172
172
|
const x_axis_height = 30;
|
|
173
173
|
let range_to_show_default = 500;
|
|
174
|
+
let min_visible_bars = 20;
|
|
174
175
|
let x_edge_padding_ratio = .5;
|
|
175
176
|
let datasets = null;
|
|
176
177
|
let chart_prepped = null;
|
|
@@ -255,6 +256,7 @@ function create_chart_manager(config) {
|
|
|
255
256
|
function scroll_frame(e, shown_start_x, shown_end_x, min_x_scrollable, max_x_scrollable, frame_width, min_period_sec = 60, max_range_sec = null) {
|
|
256
257
|
const shown_x_range = shown_end_x - shown_start_x;
|
|
257
258
|
const change_sec = (Math.round(shown_x_range * .01 / 60) + 1) * 60;
|
|
259
|
+
const min_range_sec = Math.max(Number(min_visible_bars) || 0, 1) * min_period_sec;
|
|
258
260
|
const max_allowed_range_sec = Number.isFinite(max_range_sec) && max_range_sec > 0 ? max_range_sec : min_period_sec * 1e4;
|
|
259
261
|
let shown_end_x_loc = shown_end_x;
|
|
260
262
|
let shown_start_x_loc = shown_start_x;
|
|
@@ -266,7 +268,7 @@ function create_chart_manager(config) {
|
|
|
266
268
|
shown_end_x_loc += change_sec;
|
|
267
269
|
}
|
|
268
270
|
let x_pd = e.offsetX / frame_width;
|
|
269
|
-
if (e.deltaY < -1 && shown_x_range >
|
|
271
|
+
if (e.deltaY < -1 && shown_x_range > min_range_sec) {
|
|
270
272
|
shown_start_x_loc += Math.round(change_sec * x_pd / 10) * 10;
|
|
271
273
|
shown_end_x_loc -= Math.round(change_sec * (1 - x_pd) / 10) * 10;
|
|
272
274
|
} else if (e.deltaY > 1 && shown_x_range < max_allowed_range_sec) {
|
|
@@ -1142,7 +1144,8 @@ function create_chart_manager(config) {
|
|
|
1142
1144
|
return n < min ? min : n > max ? max : n;
|
|
1143
1145
|
}
|
|
1144
1146
|
function clamp_range_to_limits(range_sec) {
|
|
1145
|
-
|
|
1147
|
+
const min_period_sec = get_min_period_sec_from_chart() ?? 60;
|
|
1148
|
+
return clamp(range_sec, Math.max(Number(min_visible_bars) || 0, 1) * min_period_sec, get_max_range_sec_from_chart() ?? range_sec);
|
|
1146
1149
|
}
|
|
1147
1150
|
function clamp_y_range_to_limits(range_y, axis) {
|
|
1148
1151
|
const data_low_y = axis?.data_low_y;
|
|
@@ -1483,9 +1486,7 @@ function create_chart_manager(config) {
|
|
|
1483
1486
|
min_x_scrollable = all_data_start_x_loc + Math.floor(range_to_show * .1);
|
|
1484
1487
|
max_x_scrollable = all_data_end_x_loc - Math.floor(range_to_show * .1);
|
|
1485
1488
|
if (shown_start_x == null || isNaN(shown_start_x)) shown_start_x = shown_start_x_loc;
|
|
1486
|
-
else if (shown_start_x >= max_x_scrollable) shown_start_x = min_x_scrollable;
|
|
1487
1489
|
if (shown_end_x == null || isNaN(shown_end_x)) shown_end_x = all_data_end_x_loc;
|
|
1488
|
-
else if (shown_end_x <= min_x_scrollable) shown_end_x = max_x_scrollable;
|
|
1489
1490
|
let prepped_frames = [];
|
|
1490
1491
|
for (let frame of frames) {
|
|
1491
1492
|
const frame_height = frame_width() / frame.aspect_ratio;
|
|
@@ -1755,6 +1756,7 @@ function create_chart_manager(config) {
|
|
|
1755
1756
|
function init(config) {
|
|
1756
1757
|
console.log("init_chart", config);
|
|
1757
1758
|
range_to_show_default = config?.range_to_show_default ?? 500;
|
|
1759
|
+
min_visible_bars = config?.min_visible_bars ?? 20;
|
|
1758
1760
|
x_edge_padding_ratio = config?.x_edge_padding_ratio ?? .5;
|
|
1759
1761
|
datasets = config?.datasets;
|
|
1760
1762
|
chart_prepped = prep_chart({ ...config?.chart });
|
package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/internal.js
CHANGED
|
@@ -773,7 +773,7 @@ var options = {
|
|
|
773
773
|
app: ({ head, body, assets, nonce, env }) => "<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"\">\n <head>\n <meta charset=\"utf-8\" />\n <link rel=\"icon\" type=\"image/svg+xml\" sizes=\"any\" href=\"" + assets + "/favicon.svg\" />\n <link rel=\"icon\" type=\"image/png\" href=\"" + assets + "/favicon.png\" />\n <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"" + assets + "/apple-touch-icon.png\" />\n <link rel=\"manifest\" href=\"" + assets + "/site.webmanifest\" />\n <meta name=\"theme-color\" media=\"(prefers-color-scheme: light)\" content=\"oklch(97% 0.01 261)\" />\n <meta name=\"theme-color\" media=\"(prefers-color-scheme: dark)\" content=\"oklch(3% 0.01 261)\" />\n <meta name=\"viewport\" content=\"width=device-width\" />\n " + head + "\n </head>\n <body data-sveltekit-preload-data=\"hover\">\n <div style=\"display: contents\">" + body + "</div>\n </body>\n</html>\n",
|
|
774
774
|
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <title>" + message + "</title>\n\n <style>\n body {\n --bg: white;\n --fg: #222;\n --divider: #ccc;\n background: var(--bg);\n color: var(--fg);\n font-family:\n system-ui,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n Roboto,\n Oxygen,\n Ubuntu,\n Cantarell,\n 'Open Sans',\n 'Helvetica Neue',\n sans-serif;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100vh;\n margin: 0;\n }\n\n .error {\n display: flex;\n align-items: center;\n max-width: 32rem;\n margin: 0 1rem;\n }\n\n .status {\n font-weight: 200;\n font-size: 3rem;\n line-height: 1;\n position: relative;\n top: -0.05rem;\n }\n\n .message {\n border-left: 1px solid var(--divider);\n padding: 0 0 0 1rem;\n margin: 0 0 0 1rem;\n min-height: 2.5rem;\n display: flex;\n align-items: center;\n }\n\n .message h1 {\n font-weight: 400;\n font-size: 1em;\n margin: 0;\n }\n\n @media (prefers-color-scheme: dark) {\n body {\n --bg: #222;\n --fg: #ddd;\n --divider: #666;\n }\n }\n </style>\n </head>\n <body>\n <div class=\"error\">\n <span class=\"status\">" + status + "</span>\n <div class=\"message\">\n <h1>" + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n"
|
|
775
775
|
},
|
|
776
|
-
version_hash: "
|
|
776
|
+
version_hash: "os530e"
|
|
777
777
|
};
|
|
778
778
|
async function get_hooks() {
|
|
779
779
|
let handle;
|
package/.vercel/output/functions/![-]/catchall.func/.svelte-kit/output/server/chunks/server.js
CHANGED
|
@@ -484,15 +484,16 @@ var uid = 1;
|
|
|
484
484
|
var Batch = class Batch {
|
|
485
485
|
id = uid++;
|
|
486
486
|
/**
|
|
487
|
-
* The current values of any
|
|
487
|
+
* The current values of any signals that are updated in this batch.
|
|
488
|
+
* Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment)
|
|
488
489
|
* They keys of this map are identical to `this.#previous`
|
|
489
|
-
* @type {Map<
|
|
490
|
+
* @type {Map<Value, [any, boolean]>}
|
|
490
491
|
*/
|
|
491
492
|
current = /* @__PURE__ */ new Map();
|
|
492
493
|
/**
|
|
493
|
-
* The values of any sources that are updated in this batch _before_ those updates took place.
|
|
494
|
+
* The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place.
|
|
494
495
|
* They keys of this map are identical to `this.#current`
|
|
495
|
-
* @type {Map<
|
|
496
|
+
* @type {Map<Value, any>}
|
|
496
497
|
*/
|
|
497
498
|
previous = /* @__PURE__ */ new Map();
|
|
498
499
|
/**
|
|
@@ -507,13 +508,15 @@ var Batch = class Batch {
|
|
|
507
508
|
*/
|
|
508
509
|
#discard_callbacks = /* @__PURE__ */ new Set();
|
|
509
510
|
/**
|
|
510
|
-
*
|
|
511
|
+
* Async effects that are currently in flight
|
|
512
|
+
* @type {Map<Effect, number>}
|
|
511
513
|
*/
|
|
512
|
-
#pending =
|
|
514
|
+
#pending = /* @__PURE__ */ new Map();
|
|
513
515
|
/**
|
|
514
|
-
*
|
|
516
|
+
* Async effects that are currently in flight, _not_ inside a pending boundary
|
|
517
|
+
* @type {Map<Effect, number>}
|
|
515
518
|
*/
|
|
516
|
-
#blocking_pending =
|
|
519
|
+
#blocking_pending = /* @__PURE__ */ new Map();
|
|
517
520
|
/**
|
|
518
521
|
* A deferred that resolves when the batch is committed, used with `settled()`
|
|
519
522
|
* TODO replace with Promise.withResolvers once supported widely enough
|
|
@@ -545,8 +548,25 @@ var Batch = class Batch {
|
|
|
545
548
|
#skipped_branches = /* @__PURE__ */ new Map();
|
|
546
549
|
is_fork = false;
|
|
547
550
|
#decrement_queued = false;
|
|
551
|
+
/** @type {Set<Batch>} */
|
|
552
|
+
#blockers = /* @__PURE__ */ new Set();
|
|
548
553
|
#is_deferred() {
|
|
549
|
-
return this.is_fork || this.#blocking_pending > 0;
|
|
554
|
+
return this.is_fork || this.#blocking_pending.size > 0;
|
|
555
|
+
}
|
|
556
|
+
#is_blocked() {
|
|
557
|
+
for (const batch of this.#blockers) for (const effect of batch.#blocking_pending.keys()) {
|
|
558
|
+
var skipped = false;
|
|
559
|
+
var e = effect;
|
|
560
|
+
while (e.parent !== null) {
|
|
561
|
+
if (this.#skipped_branches.has(e)) {
|
|
562
|
+
skipped = true;
|
|
563
|
+
break;
|
|
564
|
+
}
|
|
565
|
+
e = e.parent;
|
|
566
|
+
}
|
|
567
|
+
if (!skipped) return true;
|
|
568
|
+
}
|
|
569
|
+
return false;
|
|
550
570
|
}
|
|
551
571
|
/**
|
|
552
572
|
* Add an effect to the #skipped_branches map and reset its children
|
|
@@ -618,12 +638,12 @@ var Batch = class Batch {
|
|
|
618
638
|
}
|
|
619
639
|
collected_effects = null;
|
|
620
640
|
legacy_updates = null;
|
|
621
|
-
if (this.#is_deferred()) {
|
|
641
|
+
if (this.#is_deferred() || this.#is_blocked()) {
|
|
622
642
|
this.#defer_effects(render_effects);
|
|
623
643
|
this.#defer_effects(effects);
|
|
624
644
|
for (const [e, t] of this.#skipped_branches) reset_branch(e, t);
|
|
625
645
|
} else {
|
|
626
|
-
if (this.#pending === 0) batches.delete(this);
|
|
646
|
+
if (this.#pending.size === 0) batches.delete(this);
|
|
627
647
|
this.#dirty_effects.clear();
|
|
628
648
|
this.#maybe_dirty_effects.clear();
|
|
629
649
|
for (const fn of this.#commit_callbacks) fn(this);
|
|
@@ -689,13 +709,14 @@ var Batch = class Batch {
|
|
|
689
709
|
/**
|
|
690
710
|
* Associate a change to a given source with the current
|
|
691
711
|
* batch, noting its previous and current values
|
|
692
|
-
* @param {
|
|
712
|
+
* @param {Value} source
|
|
693
713
|
* @param {any} old_value
|
|
714
|
+
* @param {boolean} [is_derived]
|
|
694
715
|
*/
|
|
695
|
-
capture(source, old_value) {
|
|
716
|
+
capture(source, old_value, is_derived = false) {
|
|
696
717
|
if (old_value !== UNINITIALIZED && !this.previous.has(source)) this.previous.set(source, old_value);
|
|
697
718
|
if ((source.f & 8388608) === 0) {
|
|
698
|
-
this.current.set(source, source.v);
|
|
719
|
+
this.current.set(source, [source.v, is_derived]);
|
|
699
720
|
batch_values?.set(source, source.v);
|
|
700
721
|
}
|
|
701
722
|
}
|
|
@@ -732,9 +753,12 @@ var Batch = class Batch {
|
|
|
732
753
|
var is_earlier = batch.id < this.id;
|
|
733
754
|
/** @type {Source[]} */
|
|
734
755
|
var sources = [];
|
|
735
|
-
for (const [source, value] of this.current) {
|
|
736
|
-
if (batch.current.has(source))
|
|
737
|
-
|
|
756
|
+
for (const [source, [value, is_derived]] of this.current) {
|
|
757
|
+
if (batch.current.has(source)) {
|
|
758
|
+
var batch_value = batch.current.get(source)[0];
|
|
759
|
+
if (is_earlier && value !== batch_value) batch.current.set(source, [value, is_derived]);
|
|
760
|
+
else continue;
|
|
761
|
+
}
|
|
738
762
|
sources.push(source);
|
|
739
763
|
}
|
|
740
764
|
var others = [...batch.current.keys()].filter((s) => !this.current.has(s));
|
|
@@ -755,22 +779,40 @@ var Batch = class Batch {
|
|
|
755
779
|
batch.deactivate();
|
|
756
780
|
}
|
|
757
781
|
}
|
|
782
|
+
for (const batch of batches) if (batch.#blockers.has(this)) {
|
|
783
|
+
batch.#blockers.delete(this);
|
|
784
|
+
if (batch.#blockers.size === 0 && !batch.#is_deferred()) {
|
|
785
|
+
batch.activate();
|
|
786
|
+
batch.#process();
|
|
787
|
+
}
|
|
788
|
+
}
|
|
758
789
|
}
|
|
759
790
|
/**
|
|
760
|
-
*
|
|
761
791
|
* @param {boolean} blocking
|
|
792
|
+
* @param {Effect} effect
|
|
762
793
|
*/
|
|
763
|
-
increment(blocking) {
|
|
764
|
-
this.#pending
|
|
765
|
-
|
|
794
|
+
increment(blocking, effect) {
|
|
795
|
+
let pending_count = this.#pending.get(effect) ?? 0;
|
|
796
|
+
this.#pending.set(effect, pending_count + 1);
|
|
797
|
+
if (blocking) {
|
|
798
|
+
let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
|
|
799
|
+
this.#blocking_pending.set(effect, blocking_pending_count + 1);
|
|
800
|
+
}
|
|
766
801
|
}
|
|
767
802
|
/**
|
|
768
803
|
* @param {boolean} blocking
|
|
804
|
+
* @param {Effect} effect
|
|
769
805
|
* @param {boolean} skip - whether to skip updates (because this is triggered by a stale reaction)
|
|
770
806
|
*/
|
|
771
|
-
decrement(blocking, skip) {
|
|
772
|
-
this.#pending
|
|
773
|
-
if (
|
|
807
|
+
decrement(blocking, effect, skip) {
|
|
808
|
+
let pending_count = this.#pending.get(effect) ?? 0;
|
|
809
|
+
if (pending_count === 1) this.#pending.delete(effect);
|
|
810
|
+
else this.#pending.set(effect, pending_count - 1);
|
|
811
|
+
if (blocking) {
|
|
812
|
+
let blocking_pending_count = this.#blocking_pending.get(effect) ?? 0;
|
|
813
|
+
if (blocking_pending_count === 1) this.#blocking_pending.delete(effect);
|
|
814
|
+
else this.#blocking_pending.set(effect, blocking_pending_count - 1);
|
|
815
|
+
}
|
|
774
816
|
if (this.#decrement_queued || skip) return;
|
|
775
817
|
this.#decrement_queued = true;
|
|
776
818
|
queue_micro_task(() => {
|
|
@@ -817,10 +859,19 @@ var Batch = class Batch {
|
|
|
817
859
|
batch_values = null;
|
|
818
860
|
return;
|
|
819
861
|
}
|
|
820
|
-
batch_values = new Map(
|
|
862
|
+
batch_values = /* @__PURE__ */ new Map();
|
|
863
|
+
for (const [source, [value]] of this.current) batch_values.set(source, value);
|
|
821
864
|
for (const batch of batches) {
|
|
822
865
|
if (batch === this || batch.is_fork) continue;
|
|
823
|
-
|
|
866
|
+
var intersects = false;
|
|
867
|
+
var differs = false;
|
|
868
|
+
if (batch.id < this.id) for (const [source, [, is_derived]] of batch.current) {
|
|
869
|
+
if (is_derived) continue;
|
|
870
|
+
intersects ||= this.current.has(source);
|
|
871
|
+
differs ||= !this.current.has(source);
|
|
872
|
+
}
|
|
873
|
+
if (intersects && differs) this.#blockers.add(batch);
|
|
874
|
+
else for (const [source, previous] of batch.previous) if (!batch_values.has(source)) batch_values.set(source, previous);
|
|
824
875
|
}
|
|
825
876
|
}
|
|
826
877
|
/**
|
|
@@ -1453,7 +1504,7 @@ function update_derived(derived) {
|
|
|
1453
1504
|
derived.wv = increment_write_version();
|
|
1454
1505
|
if (!current_batch?.is_fork || derived.deps === null) {
|
|
1455
1506
|
derived.v = value;
|
|
1456
|
-
current_batch?.capture(derived, old_value);
|
|
1507
|
+
current_batch?.capture(derived, old_value, true);
|
|
1457
1508
|
if (derived.deps === null) {
|
|
1458
1509
|
set_signal_status(derived, CLEAN);
|
|
1459
1510
|
return;
|
|
@@ -2071,7 +2122,7 @@ function destroy_effect(effect, remove_dom = true) {
|
|
|
2071
2122
|
effect.f |= DESTROYED;
|
|
2072
2123
|
var parent = effect.parent;
|
|
2073
2124
|
if (parent !== null && parent.first !== null) unlink_effect(effect);
|
|
2074
|
-
effect.next = effect.prev = effect.teardown = effect.ctx = effect.deps = effect.fn = effect.nodes = effect.ac = null;
|
|
2125
|
+
effect.next = effect.prev = effect.teardown = effect.ctx = effect.deps = effect.fn = effect.nodes = effect.ac = effect.b = null;
|
|
2075
2126
|
}
|
|
2076
2127
|
/**
|
|
2077
2128
|
*
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
//#region src/lib/server/trader_data.js
|
|
2
|
+
var PERIOD_TO_SEC = {
|
|
3
|
+
"5m": 300,
|
|
4
|
+
"1h": 3600,
|
|
5
|
+
"1d": 86400,
|
|
6
|
+
"1w": 604800
|
|
7
|
+
};
|
|
8
|
+
var COINBASE_MAX_WINDOW_BARS = 290;
|
|
9
|
+
var TRADER_MARKETS = [
|
|
10
|
+
{
|
|
11
|
+
key: "btc_usd",
|
|
12
|
+
label: "BTC / USD",
|
|
13
|
+
description: "Coinbase execution charts plus an Aster weekly context chart."
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
key: "doge_usd",
|
|
17
|
+
label: "DOGE / USD",
|
|
18
|
+
description: "DOGE spot structure across fast, medium, and higher timeframes."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: "doge_btc",
|
|
22
|
+
label: "DOGE / BTC",
|
|
23
|
+
description: "Relative-strength anchor chart for sizing ideas."
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
var TRADER_CHART_SPECS = [
|
|
27
|
+
{
|
|
28
|
+
id: "btc_usd_coinbase_5m",
|
|
29
|
+
market_key: "btc_usd",
|
|
30
|
+
pair_label: "BTC / USD",
|
|
31
|
+
title: "BTC / USD 5m",
|
|
32
|
+
source_key: "coinbase",
|
|
33
|
+
source_label: "Coinbase",
|
|
34
|
+
source_symbol: "BTC-USD",
|
|
35
|
+
period: "5m",
|
|
36
|
+
target_bars: 350
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "btc_usd_coinbase_1h",
|
|
40
|
+
market_key: "btc_usd",
|
|
41
|
+
pair_label: "BTC / USD",
|
|
42
|
+
title: "BTC / USD 1h",
|
|
43
|
+
source_key: "coinbase",
|
|
44
|
+
source_label: "Coinbase",
|
|
45
|
+
source_symbol: "BTC-USD",
|
|
46
|
+
period: "1h",
|
|
47
|
+
target_bars: 350
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "btc_usd_coinbase_1d",
|
|
51
|
+
market_key: "btc_usd",
|
|
52
|
+
pair_label: "BTC / USD",
|
|
53
|
+
title: "BTC / USD 1d",
|
|
54
|
+
source_key: "coinbase",
|
|
55
|
+
source_label: "Coinbase",
|
|
56
|
+
source_symbol: "BTC-USD",
|
|
57
|
+
period: "1d",
|
|
58
|
+
target_bars: 350
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "btc_usd_aster_1w",
|
|
62
|
+
market_key: "btc_usd",
|
|
63
|
+
pair_label: "BTC / USD",
|
|
64
|
+
title: "BTC / USD 1w",
|
|
65
|
+
source_key: "aster",
|
|
66
|
+
source_label: "Aster",
|
|
67
|
+
source_symbol: "BTCUSDT",
|
|
68
|
+
period: "1w",
|
|
69
|
+
target_bars: 240,
|
|
70
|
+
source_note: "Weekly context uses Aster perpetual BTCUSDT candles."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "doge_usd_coinbase_5m",
|
|
74
|
+
market_key: "doge_usd",
|
|
75
|
+
pair_label: "DOGE / USD",
|
|
76
|
+
title: "DOGE / USD 5m",
|
|
77
|
+
source_key: "coinbase",
|
|
78
|
+
source_label: "Coinbase",
|
|
79
|
+
source_symbol: "DOGE-USD",
|
|
80
|
+
period: "5m",
|
|
81
|
+
target_bars: 350
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: "doge_usd_coinbase_1h",
|
|
85
|
+
market_key: "doge_usd",
|
|
86
|
+
pair_label: "DOGE / USD",
|
|
87
|
+
title: "DOGE / USD 1h",
|
|
88
|
+
source_key: "coinbase",
|
|
89
|
+
source_label: "Coinbase",
|
|
90
|
+
source_symbol: "DOGE-USD",
|
|
91
|
+
period: "1h",
|
|
92
|
+
target_bars: 350
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
id: "doge_usd_coinbase_1d",
|
|
96
|
+
market_key: "doge_usd",
|
|
97
|
+
pair_label: "DOGE / USD",
|
|
98
|
+
title: "DOGE / USD 1d",
|
|
99
|
+
source_key: "coinbase",
|
|
100
|
+
source_label: "Coinbase",
|
|
101
|
+
source_symbol: "DOGE-USD",
|
|
102
|
+
period: "1d",
|
|
103
|
+
target_bars: 350
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "doge_usd_aster_1w",
|
|
107
|
+
market_key: "doge_usd",
|
|
108
|
+
pair_label: "DOGE / USD",
|
|
109
|
+
title: "DOGE / USD 1w",
|
|
110
|
+
source_key: "aster",
|
|
111
|
+
source_label: "Aster",
|
|
112
|
+
source_symbol: "DOGEUSDT",
|
|
113
|
+
period: "1w",
|
|
114
|
+
target_bars: 240,
|
|
115
|
+
source_note: "Weekly context uses Aster perpetual DOGEUSDT candles."
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
id: "doge_btc_coinbase_1d",
|
|
119
|
+
market_key: "doge_btc",
|
|
120
|
+
pair_label: "DOGE / BTC",
|
|
121
|
+
title: "DOGE / BTC 1d",
|
|
122
|
+
source_key: "coinbase",
|
|
123
|
+
source_label: "Coinbase",
|
|
124
|
+
source_symbol: "DOGE-BTC",
|
|
125
|
+
period: "1d",
|
|
126
|
+
target_bars: 900,
|
|
127
|
+
source_note: "Fetched in multiple Coinbase windows to get deeper daily history."
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
function create_fetch_error(response, body) {
|
|
131
|
+
const body_message = typeof body?.message === "string" ? body.message : null;
|
|
132
|
+
const fallback = `Request failed with status ${response.status}`;
|
|
133
|
+
return new Error(body_message || fallback);
|
|
134
|
+
}
|
|
135
|
+
async function fetch_json(fetcher, url) {
|
|
136
|
+
const response = await fetcher(url, { headers: { accept: "application/json" } });
|
|
137
|
+
const body = await response.json();
|
|
138
|
+
if (!response.ok) throw create_fetch_error(response, body);
|
|
139
|
+
if (body?.message && !Array.isArray(body)) throw new Error(body.message);
|
|
140
|
+
return body;
|
|
141
|
+
}
|
|
142
|
+
function dedupe_klines(klines) {
|
|
143
|
+
const by_open_time = /* @__PURE__ */ new Map();
|
|
144
|
+
for (let kline of klines || []) {
|
|
145
|
+
if (!Number.isFinite(kline?.open_time)) continue;
|
|
146
|
+
by_open_time.set(kline.open_time, kline);
|
|
147
|
+
}
|
|
148
|
+
return [...by_open_time.values()].sort((a, b) => a.open_time - b.open_time);
|
|
149
|
+
}
|
|
150
|
+
function normalize_coinbase_klines(raw_klines) {
|
|
151
|
+
if (!Array.isArray(raw_klines)) throw new Error("Coinbase candles response was not an array.");
|
|
152
|
+
return dedupe_klines(raw_klines.map((kline) => {
|
|
153
|
+
return {
|
|
154
|
+
open_time: Number(kline?.[0]),
|
|
155
|
+
l: Number(kline?.[1]),
|
|
156
|
+
h: Number(kline?.[2]),
|
|
157
|
+
o: Number(kline?.[3]),
|
|
158
|
+
c: Number(kline?.[4]),
|
|
159
|
+
v: Number(kline?.[5])
|
|
160
|
+
};
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
function normalize_aster_klines(raw_klines) {
|
|
164
|
+
if (!Array.isArray(raw_klines)) throw new Error("Aster klines response was not an array.");
|
|
165
|
+
return dedupe_klines(raw_klines.map((kline) => {
|
|
166
|
+
return {
|
|
167
|
+
open_time: Math.floor(Number(kline?.[0]) / 1e3),
|
|
168
|
+
o: Number(kline?.[1]),
|
|
169
|
+
h: Number(kline?.[2]),
|
|
170
|
+
l: Number(kline?.[3]),
|
|
171
|
+
c: Number(kline?.[4]),
|
|
172
|
+
v: Number(kline?.[5])
|
|
173
|
+
};
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
async function fetch_coinbase_recent_klines(fetcher, product_id, period) {
|
|
177
|
+
return normalize_coinbase_klines(await fetch_json(fetcher, `https://api.exchange.coinbase.com/products/${product_id}/candles?granularity=${PERIOD_TO_SEC[period]}`));
|
|
178
|
+
}
|
|
179
|
+
async function fetch_coinbase_paged_klines(fetcher, product_id, period, target_bars) {
|
|
180
|
+
const granularity_sec = PERIOD_TO_SEC[period];
|
|
181
|
+
let remaining_bars = target_bars;
|
|
182
|
+
let end_time_ms = Date.now();
|
|
183
|
+
let combined_klines = [];
|
|
184
|
+
let safety = 0;
|
|
185
|
+
while (remaining_bars > 0 && safety < 12) {
|
|
186
|
+
const bars_this_call = Math.min(remaining_bars, COINBASE_MAX_WINDOW_BARS);
|
|
187
|
+
const window_ms = bars_this_call * granularity_sec * 1e3;
|
|
188
|
+
const start_time_iso = new Date(end_time_ms - window_ms).toISOString();
|
|
189
|
+
const end_time_iso = new Date(end_time_ms).toISOString();
|
|
190
|
+
const next_klines = normalize_coinbase_klines(await fetch_json(fetcher, `https://api.exchange.coinbase.com/products/${product_id}/candles?${new URLSearchParams({
|
|
191
|
+
granularity: String(granularity_sec),
|
|
192
|
+
start: start_time_iso,
|
|
193
|
+
end: end_time_iso
|
|
194
|
+
}).toString()}`));
|
|
195
|
+
if (next_klines.length === 0) break;
|
|
196
|
+
combined_klines = dedupe_klines([...next_klines, ...combined_klines]);
|
|
197
|
+
remaining_bars = target_bars - combined_klines.length;
|
|
198
|
+
end_time_ms = (next_klines[0].open_time - granularity_sec) * 1e3;
|
|
199
|
+
safety += 1;
|
|
200
|
+
if (next_klines.length < bars_this_call * .75) break;
|
|
201
|
+
}
|
|
202
|
+
return combined_klines.slice(-target_bars);
|
|
203
|
+
}
|
|
204
|
+
async function fetch_coinbase_klines(fetcher, product_id, period, target_bars = 350) {
|
|
205
|
+
if ((target_bars ?? 0) > 350) return fetch_coinbase_paged_klines(fetcher, product_id, period, target_bars);
|
|
206
|
+
return (await fetch_coinbase_recent_klines(fetcher, product_id, period)).slice(-target_bars);
|
|
207
|
+
}
|
|
208
|
+
async function fetch_aster_klines(fetcher, symbol, period, target_bars = 240) {
|
|
209
|
+
return normalize_aster_klines(await fetch_json(fetcher, `https://fapi.asterdex.com/fapi/v1/klines?${new URLSearchParams({
|
|
210
|
+
symbol,
|
|
211
|
+
interval: period,
|
|
212
|
+
limit: String(target_bars)
|
|
213
|
+
}).toString()}`));
|
|
214
|
+
}
|
|
215
|
+
async function fetch_chart_klines(fetcher, chart_spec) {
|
|
216
|
+
if (chart_spec.source_key === "coinbase") return fetch_coinbase_klines(fetcher, chart_spec.source_symbol, chart_spec.period, chart_spec.target_bars);
|
|
217
|
+
if (chart_spec.source_key === "aster") return fetch_aster_klines(fetcher, chart_spec.source_symbol, chart_spec.period, chart_spec.target_bars);
|
|
218
|
+
throw new Error(`Unsupported chart source: ${chart_spec.source_key}`);
|
|
219
|
+
}
|
|
220
|
+
function get_chart_result_summary(chart_spec, klines) {
|
|
221
|
+
return {
|
|
222
|
+
...chart_spec,
|
|
223
|
+
status: "ready",
|
|
224
|
+
error: null,
|
|
225
|
+
klines,
|
|
226
|
+
trendlines: [],
|
|
227
|
+
bar_count: klines.length,
|
|
228
|
+
first_open_time: klines?.[0]?.open_time ?? null,
|
|
229
|
+
last_open_time: klines?.[klines.length - 1]?.open_time ?? null
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function get_chart_error_summary(chart_spec, error) {
|
|
233
|
+
return {
|
|
234
|
+
...chart_spec,
|
|
235
|
+
status: "error",
|
|
236
|
+
error: error?.message ?? "Failed to load chart data.",
|
|
237
|
+
klines: [],
|
|
238
|
+
trendlines: [],
|
|
239
|
+
bar_count: 0,
|
|
240
|
+
first_open_time: null,
|
|
241
|
+
last_open_time: null
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
function build_markets(chart_results) {
|
|
245
|
+
return TRADER_MARKETS.map((market) => {
|
|
246
|
+
return {
|
|
247
|
+
...market,
|
|
248
|
+
charts: chart_results.filter((chart_result) => chart_result.market_key === market.key)
|
|
249
|
+
};
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function load_trader_data(fetcher = fetch) {
|
|
253
|
+
const chart_results = await Promise.all(TRADER_CHART_SPECS.map(async (chart_spec) => {
|
|
254
|
+
try {
|
|
255
|
+
return get_chart_result_summary(chart_spec, await fetch_chart_klines(fetcher, chart_spec));
|
|
256
|
+
} catch (error) {
|
|
257
|
+
return get_chart_error_summary(chart_spec, error);
|
|
258
|
+
}
|
|
259
|
+
}));
|
|
260
|
+
return {
|
|
261
|
+
title: "Trader Lab",
|
|
262
|
+
loaded_at_iso: (/* @__PURE__ */ new Date()).toISOString(),
|
|
263
|
+
markets: build_markets(chart_results),
|
|
264
|
+
strategy_seed: {
|
|
265
|
+
total_budget_usd: 1e5,
|
|
266
|
+
leverage_allowed: true,
|
|
267
|
+
rebalance_cadence: "hourly",
|
|
268
|
+
top_trendlines_per_chart: 15,
|
|
269
|
+
notional_by_period_usd: {
|
|
270
|
+
"5m": 1e3,
|
|
271
|
+
"1h": 5e3,
|
|
272
|
+
"1d": 1e4,
|
|
273
|
+
"1w": 15e3
|
|
274
|
+
},
|
|
275
|
+
sizing_signal_chart_id: "doge_btc_coinbase_1d"
|
|
276
|
+
},
|
|
277
|
+
notes: [
|
|
278
|
+
"Step 1 focuses on loading and charting the main BTC, DOGE, and DOGE/BTC structures.",
|
|
279
|
+
"Trendline generation and backtesting hooks are intentionally left for the next pass.",
|
|
280
|
+
"Aster weekly charts use USDT perpetual symbols because that is the available market format there."
|
|
281
|
+
],
|
|
282
|
+
errors: chart_results.filter((chart_result) => chart_result.status === "error").map((chart_result) => ({
|
|
283
|
+
id: chart_result.id,
|
|
284
|
+
title: chart_result.title,
|
|
285
|
+
error: chart_result.error
|
|
286
|
+
}))
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/routes/trader/+page.server.js
|
|
291
|
+
async function load({ fetch }) {
|
|
292
|
+
return { trader: await load_trader_data(fetch) };
|
|
293
|
+
}
|
|
294
|
+
//#endregion
|
|
295
|
+
export { load };
|