astro-tractstack 2.0.0-rc.66 → 2.0.0-rc.68

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/LICENSE CHANGED
@@ -1,102 +1,13 @@
1
- # Functional Source License, Version 1.1, MIT Future License
1
+ MIT License
2
2
 
3
- ## Abbreviation
3
+ Copyright (c) 2025 At Risk Media
4
4
 
5
- FSL-1.1-MIT
6
-
7
- ## Notice
8
-
9
- Copyright 2025 At Risk Media
10
-
11
- ## Terms and Conditions
12
-
13
- ### Licensor ("We")
14
-
15
- The party offering the Software under these Terms and Conditions.
16
-
17
- ### The Software
18
-
19
- The "Software" is each version of the software that we make available under
20
- these Terms and Conditions, as indicated by our inclusion of these Terms and
21
- Conditions with the Software.
22
-
23
- ### License Grant
24
-
25
- Subject to your compliance with this License Grant and the Patents,
26
- Redistribution and Trademark clauses below, we hereby grant you the right to
27
- use, copy, modify, create derivative works, publicly perform, publicly display
28
- and redistribute the Software for any Permitted Purpose identified below.
29
-
30
- ### Permitted Purpose
31
-
32
- A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
- means making the Software available to others in a commercial product or
34
- service that:
35
-
36
- 1. substitutes for the Software;
37
-
38
- 2. substitutes for any other product or service we offer using the Software
39
- that exists as of the date we make the Software available; or
40
-
41
- 3. offers the same or substantially similar functionality as the Software.
42
-
43
- Permitted Purposes specifically include using the Software:
44
-
45
- 1. for your internal use and access;
46
-
47
- 2. for non-commercial education;
48
-
49
- 3. for non-commercial research; and
50
-
51
- 4. in connection with professional services that you provide to a licensee
52
- using the Software in accordance with these Terms and Conditions.
53
-
54
- ### Patents
55
-
56
- To the extent your use for a Permitted Purpose would necessarily infringe our
57
- patents, the license grant above includes a license under our patents. If you
58
- make a claim against any party that the Software infringes or contributes to
59
- the infringement of any patent, then your patent license to the Software ends
60
- immediately.
61
-
62
- ### Redistribution
63
-
64
- The Terms and Conditions apply to all copies, modifications and derivatives of
65
- the Software.
66
-
67
- If you redistribute any copies, modifications or derivatives of the Software,
68
- you must include a copy of or a link to these Terms and Conditions and not
69
- remove any copyright notices provided in or with the Software.
70
-
71
- ### Disclaimer
72
-
73
- THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
- IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
- PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
-
77
- IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
- SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
- EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
-
81
- ### Trademarks
82
-
83
- Except for displaying the License Details and identifying us as the origin of
84
- the Software, you have no right under these Terms and Conditions to use our
85
- trademarks, trade names, service marks or product names.
86
-
87
- ## Grant of Future License
88
-
89
- We hereby irrevocably grant you an additional license to use the Software under
90
- the MIT license that is effective on the second anniversary of the date we make
91
- the Software available. On or after that date, you may use the Software under
92
- the MIT license, in which case the following will apply:
93
-
94
- Permission is hereby granted, free of charge, to any person obtaining a copy of
95
- this software and associated documentation files (the "Software"), to deal in
96
- the Software without restriction, including without limitation the rights to
97
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98
- of the Software, and to permit persons to whom the Software is furnished to do
99
- so, subject to the following conditions:
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
100
11
 
101
12
  The above copyright notice and this permission notice shall be included in all
102
13
  copies or substantial portions of the Software.
package/README.md CHANGED
@@ -80,7 +80,7 @@ cd ~/t8k/src/my-tractstack
80
80
  pnpm dev
81
81
  ```
82
82
 
83
- Visit https://127.0.0.1:4321 to access your site and activate your Story Keep (CMS).
83
+ Visit <https://127.0.0.1:4321> to access your site and activate your Story Keep (CMS).
84
84
 
85
85
  ## Installation Types
86
86
 
@@ -283,14 +283,16 @@ sudo ~/t8k/src/tractstack-go/pkg/scripts/t8k-uninstall.sh
283
283
 
284
284
  ## Support & Documentation
285
285
 
286
- - **Documentation**: https://tractstack.org
287
- - **GitHub Issues**: https://github.com/AtRiskMedia/tractstack-go/issues
288
- - **Email Support**: hello@tractstack.com
286
+ - **Documentation**: <https://tractstack.org>
287
+ - **GitHub Issues**: <https://github.com/AtRiskMedia/tractstack-go/issues>
288
+ - **Email Support**: <hello@tractstack.com>
289
289
  - **Community**: Join discussions about adaptive web experiences
290
290
 
291
291
  ## License
292
292
 
293
- **Functional Source License (FSL)** - Commercial use encouraged!
293
+ The frontend Astro integration is available via the MIT license.
294
+
295
+ The backend epistemic hypermedia server is available via the **Functional Source License (FSL)** - Commercial use encouraged!
294
296
 
295
297
  The only restriction is no re-selling TractStack as-a-service. Perfect for:
296
298
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-tractstack",
3
- "version": "2.0.0-rc.66",
3
+ "version": "2.0.0-rc.68",
4
4
  "description": "Astro integration for TractStack - redeeming the web from boring experiences",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -34,7 +34,7 @@
34
34
  "go"
35
35
  ],
36
36
  "author": "AtRiskMedia",
37
- "license": "FSL-1.1-MIT",
37
+ "license": "MIT",
38
38
  "repository": {
39
39
  "type": "git",
40
40
  "url": "git+https://github.com/AtRiskMedia/astro-tractstack.git"
@@ -327,7 +327,7 @@ function processStoryfragmentUpdate(update, config) {
327
327
  `Target pane element for scrolling not found: #pane-${update.gotoPaneId}`
328
328
  );
329
329
  }
330
- }, 150);
330
+ }, 350);
331
331
  }
332
332
  }
333
333
 
@@ -361,6 +361,7 @@ function initializeCurrentView() {
361
361
 
362
362
  function resetViewState() {
363
363
  log('Resetting view state before new page preparation.');
364
+ flushPendingPaneEvents();
364
365
  isPageInitialized = false;
365
366
  paneViewTimes.clear();
366
367
  }
@@ -385,8 +386,13 @@ if (!window.tractstackViewLifecycleListenersAttached) {
385
386
 
386
387
  let beliefValue;
387
388
  if (target.type === 'checkbox') {
388
- // TEMPORARY HARDCODING: Use YES/NO for all toggles.
389
- beliefValue = target.checked ? 'BELIEVES_YES' : 'BELIEVES_NO';
389
+ const onVerb = target.getAttribute('data-verb');
390
+ const offVerb = target.getAttribute('data-off-verb');
391
+ if (onVerb && offVerb) {
392
+ beliefValue = target.checked ? onVerb : offVerb;
393
+ } else {
394
+ beliefValue = target.checked ? 'BELIEVES_YES' : 'BELIEVES_NO';
395
+ }
390
396
  } else {
391
397
  beliefValue = target.value;
392
398
  }
@@ -414,6 +414,7 @@ const EpinetWrapper = ({
414
414
  <EpinetDurationSelector
415
415
  fullContentMap={fullContentMap}
416
416
  isLoading={isLoading || status === 'loading'}
417
+ hourlyNodeActivity={$epinetCustomFilters.hourlyNodeActivity}
417
418
  />
418
419
  </div>
419
420
  </ErrorBoundary>
@@ -931,6 +931,12 @@ export default function SaveModal({
931
931
  >
932
932
  Keep Editing
933
933
  </button>
934
+ <a
935
+ href="/storykeep/content"
936
+ className={`rounded bg-black px-4 py-2 text-white transition-colors hover:bg-white hover:text-black`}
937
+ >
938
+ Dashboard
939
+ </a>
934
940
  </>
935
941
  )}
936
942
  {stage === 'ERROR' && (
@@ -12,28 +12,27 @@ export default function ToggleWidget({ node, onUpdate }: ToggleWidgetProps) {
12
12
  const [beliefs, setBeliefs] = useState<BeliefNode[]>([]);
13
13
  const [selectedBeliefTag, setSelectedBeliefTag] = useState<string>('');
14
14
  const [currentPrompt, setCurrentPrompt] = useState<string>('');
15
+ const [currentScale, setCurrentScale] = useState<string>('');
15
16
  const [isInitialized, setIsInitialized] = useState(false);
16
17
 
17
- // Get parameter metadata from the widgetMeta constant
18
18
  const widgetInfo = widgetMeta.toggle;
19
19
 
20
20
  const params = node.codeHookParams || [];
21
21
  const beliefTag = String(params[0] || '');
22
22
  const prompt = String(params[1] || '');
23
+ const scale = String(params[2] || '');
23
24
 
24
- // Check if beliefTag is the placeholder value
25
25
  const isPlaceholder = beliefTag === 'BeliefTag';
26
26
 
27
- // Update local state when props change
28
27
  useEffect(() => {
29
28
  if (!isPlaceholder && beliefTag) {
30
29
  setSelectedBeliefTag(beliefTag);
31
30
  }
32
31
  setCurrentPrompt(prompt);
32
+ setCurrentScale(scale);
33
33
  setIsInitialized(true);
34
- }, [beliefTag, prompt, isPlaceholder]);
34
+ }, [beliefTag, prompt, scale, isPlaceholder]);
35
35
 
36
- // Fetch beliefs using new Go backend pattern
37
36
  useEffect(() => {
38
37
  const fetchData = async () => {
39
38
  try {
@@ -41,7 +40,6 @@ export default function ToggleWidget({ node, onUpdate }: ToggleWidgetProps) {
41
40
  import.meta.env.PUBLIC_GO_BACKEND || 'http://localhost:8080';
42
41
  const tenantId = import.meta.env.PUBLIC_TENANTID || 'default';
43
42
 
44
- // Step 1: Get all belief IDs
45
43
  const idsResponse = await fetch(`${goBackend}/api/v1/nodes/beliefs`, {
46
44
  headers: {
47
45
  'X-Tenant-ID': tenantId,
@@ -60,7 +58,6 @@ export default function ToggleWidget({ node, onUpdate }: ToggleWidgetProps) {
60
58
  return;
61
59
  }
62
60
 
63
- // Step 2: Get belief data by IDs
64
61
  const beliefsResponse = await fetch(
65
62
  `${goBackend}/api/v1/nodes/beliefs`,
66
63
  {
@@ -92,34 +89,30 @@ export default function ToggleWidget({ node, onUpdate }: ToggleWidgetProps) {
92
89
  const handleBeliefChange = (selectedValue: string) => {
93
90
  if (!isInitialized) return;
94
91
  setSelectedBeliefTag(selectedValue);
95
- onUpdate([selectedValue, currentPrompt]);
92
+ const selectedBelief = beliefs.find((b) => b.slug === selectedValue);
93
+ const newScale = selectedBelief ? selectedBelief.scale || '' : '';
94
+ setCurrentScale(newScale);
95
+ onUpdate([selectedValue, currentPrompt, newScale]);
96
96
  };
97
97
 
98
98
  const handlePromptChange = (value: string) => {
99
99
  if (!isInitialized) return;
100
- // Sanitize the input value (remove newlines and pipe characters)
101
100
  const sanitizedValue = value.replace(/[\n\r|]/g, '');
102
101
  setCurrentPrompt(sanitizedValue);
103
-
104
- // Use the actual selected tag (from state) or the original belief tag as fallback
105
102
  const tagToUse = selectedBeliefTag || (isPlaceholder ? '' : beliefTag);
106
- onUpdate([tagToUse, sanitizedValue]);
103
+ onUpdate([tagToUse, sanitizedValue, currentScale]);
107
104
  };
108
105
 
109
- // Show beliefs that can be selected for the toggle
110
106
  const filteredBeliefs = beliefs.filter(
111
107
  (b) => b.scale === 'yn' || b.scale === 'tf'
112
108
  );
113
109
 
114
- // Find the selected belief (if any)
115
110
  const selectedBelief = beliefs.find(
116
111
  (b) => b.slug === (selectedBeliefTag || (isPlaceholder ? '' : beliefTag))
117
112
  );
118
113
 
119
- // Determine if we have a real selection - either from state or props
120
114
  const hasRealSelection = !!selectedBelief || (!isPlaceholder && !!beliefTag);
121
115
 
122
- // Calculate the current value to show in the select dropdown
123
116
  const selectValue = selectedBeliefTag || (isPlaceholder ? '' : beliefTag);
124
117
 
125
118
  return (