Skip to content

Commit 7df15c8

Browse files
committed
Widen sortTasksUnderHeading + getStringArrayValue for array invariance (19 -> 18)
jgclark.RepeatExtensions could not call dwertheimer.TaskSorting's sortTasksUnderHeading without a suppression, for two independent reasons the call site had documented: - `_noteOverride: TNote | typeof Editor | null` -> `CoreNoteFields | null`. The body only does `_noteOverride || Editor.note`, so CoreNoteFields covers both cases it accepts. - `_sortOrder: ?(string | Array<mixed>)` -> `?(string | $ReadOnlyArray<mixed>)`. Flow arrays are invariant, so an Array<string> is not an Array<mixed>; $ReadOnlyArray is covariant. That second change pushed the same invariance one level down into helpers/dataManipulation.js getStringArrayValue, which had the identical problem (and already carried an `(defaultValue: any)` cast acknowledging it). Widened its input to $ReadOnlyArray too. getArrayValue below it was deliberately NOT widened: it returns its input as-is, so making it read-only would change its return type and ripple through every caller. Instead getStringArrayValue copies the array before passing it down -- free in practice, since the .map() on the next line already allocates. flow check: 6 (unchanged). jest: 198 suites / 4,621 tests.
1 parent aa8e882 commit 7df15c8

4 files changed

Lines changed: 158 additions & 7 deletions

File tree

‎.hyperlayout.bak-20260730-222314‎

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
{
2+
"COMMENT": "https://github.com/timolins/hyperlayout",
3+
"e-desc": "Everything",
4+
"e": [
5+
[
6+
[
7+
"npm run autowatch",
8+
"./node_modules/.bin/jest ./**/*.test.js --silent --watchAll"
9+
],
10+
""
11+
]
12+
],
13+
"t-desc": "Templating",
14+
"t": [
15+
[
16+
[
17+
"npm run autowatch np.Templating np.MeetingNotes -- --minify",
18+
"jest np.Templating/__tests__/**/*.test.js"
19+
],
20+
""
21+
]
22+
],
23+
"c-desc": "EventAutomations with coverage report",
24+
"c": [
25+
[
26+
"npm run autowatch dwertheimer.EventAutomations",
27+
"jest --watchAll dwertheimer.EventAutomations/**/*.test.js",
28+
"open file:///Users/dwertheimer/Developer/Noteplan/plugins-main-repo/coverage/lcov-report/dwertheimer.EventAutomations/src/NPTimeblocking.js.html && tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep JSLog"
29+
]
30+
],
31+
"v-desc": "FaVorites",
32+
"v": [
33+
[
34+
"node '/Users/dwertheimer/Developer/np-plugins-current/dwertheimer.Favorites/src/support/performRollup.node.js' --watch",
35+
"npm run autowatch dwertheimer.Favorites -COMPACT",
36+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=dwertheimer.Favorites/favorites_browser_output.html"
37+
],
38+
[
39+
"nplog"
40+
]
41+
],
42+
"r-desc": "React dev - TaskAutomations",
43+
"r": [
44+
[
45+
"npm run autowatch dwertheimer.TaskAutomations np.Shared",
46+
"node '/Users/dwertheimer/Developer/np-plugins-current/dwertheimer.TaskAutomations/src/react/support/performRollup.node.js' --watch",
47+
"node '/Users/dwertheimer/Developer/np-plugins-current/np.Shared/src/react/support/performRollup.node.js' --watch",
48+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=dwertheimer.TaskAutomations/reactLocal.html",
49+
"jest **/*.test.js --reporters jest-silent-reporter --reporters ./jest.customSummaryReporter.js"
50+
],
51+
[
52+
"open \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\"; tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep 'JSLog' | grep -v 'WebView Log'",
53+
"tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep 'JSLog' | grep 'WebView Log'"
54+
]
55+
],
56+
"p-desc": "test-plugin-scratch",
57+
"p": [
58+
[
59+
"npm run autowatch dwertheimer.test-plugin-scratch",
60+
"cursor '/Users/dwertheimer/Developer/np-plugins-current/dwertheimer.test-plugin-scratch/src/testPluginScratch.js'"
61+
],
62+
[
63+
"open \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\"; tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep 'JSLog' | grep -v 'WebView Log'",
64+
"tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep 'JSLog' | grep 'WebView Log'"
65+
]
66+
],
67+
"d-desc": "Dashboard",
68+
"d": [
69+
[
70+
"node '/Users/dwertheimer/Developer/np-plugins-current/np.Shared/src/react/support/performRollup.node.js' --watch",
71+
"node '/Users/dwertheimer/Developer/np-plugins-current/jgclark.Dashboard/src/react/support/performRollup.node.js' --watch",
72+
"npm run autowatch jgclark.Dashboard np.Shared -COMPACT"
73+
],
74+
[
75+
"jestall",
76+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=jgclark.Dashboard/dashboard-react.html"
77+
],
78+
[
79+
"nplog"
80+
]
81+
],
82+
"s-desc": "np.Shared",
83+
"s": [
84+
[
85+
"node '/Users/dwertheimer/Developer/np-plugins-current/np.Shared/src/react/support/performRollup.node.js' --watch",
86+
"npm run autowatch np.Shared -COMPACT"
87+
],
88+
[
89+
"jestall",
90+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=np.Shared/form_output.html"
91+
],
92+
[
93+
"nplog"
94+
]
95+
],
96+
"f-desc": "Forms",
97+
"f": [
98+
[
99+
"node '/Users/dwertheimer/Developer/np-plugins-current/np.Shared/src/react/support/performRollup.node.js' --watch",
100+
"node '/Users/dwertheimer/Developer/np-plugins-current/dwertheimer.Forms/src/support/performRollup.node.js' --watch",
101+
"npm run autowatch dwertheimer.Forms np.Shared -COMPACT",
102+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=dwertheimer.Forms"
103+
],
104+
[
105+
"nplog"
106+
]
107+
],
108+
"l-desc": "Dialog Testing",
109+
"l": [
110+
[
111+
"node '/Users/dwertheimer/Developer/np-plugins-current/np.Shared/src/react/support/performRollup.node.js' --watch",
112+
"npm run autowatch np.Shared np.Templating"
113+
],
114+
[
115+
"cd '/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/Plugins';live-server --open=np.Shared/form_output.html"
116+
],
117+
[
118+
"nplog"
119+
]
120+
],
121+
"a-desc": "Event Automations",
122+
"a": [
123+
[
124+
[
125+
"npm run autowatch dwertheimer.EventAutomations",
126+
"./node_modules/.bin/jest ./helpers/**/*.test.js ./dwertheimer.EventAutomations/**/*.test.js --silent --watchAll"
127+
],
128+
[
129+
"tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep JSLog",
130+
""
131+
]
132+
]
133+
],
134+
"x-desc": "Quad split, TBD items",
135+
"x": [
136+
[
137+
[
138+
"echo 'nra'",
139+
"echo 'jest'"
140+
],
141+
[
142+
"open \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\"; tail -f \"/Users/dwertheimer/Library/Containers/co.noteplan.NotePlan3/Data/Library/Application Support/co.noteplan.NotePlan3/np-out.log\" | grep JSLog",
143+
"echo 'shell'"
144+
]
145+
]
146+
]
147+
}

‎dwertheimer.TaskSorting/src/sortTasks.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,8 +1135,11 @@ export async function sortTasks(
11351135
*/
11361136
export async function sortTasksUnderHeading(
11371137
_heading: string | null,
1138-
_sortOrder: ?(string | Array<mixed>) = null,
1139-
_noteOverride: TNote | typeof Editor | null = null,
1138+
// $ReadOnlyArray so callers can pass an Array<string> (Flow arrays are invariant, so the old
1139+
// Array<mixed> rejected it); CoreNoteFields covers both TNote and TEditor, which is all the body needs.
1140+
_sortOrder: ?(string | $ReadOnlyArray<mixed>) = null,
1141+
_noteOverride: CoreNoteFields | null = null,
1142+
// `null` default (not `true`) so the "Combine Related Task Types?" setting is consulted -- see #770.
11401143
_interleaveTaskTypes: string | boolean | null = null,
11411144
): Promise<void> {
11421145
try {

‎helpers/dataManipulation.js‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,13 +322,17 @@ export function getArrayValue(input: string | Array<mixed>, defaultValue: Array<
322322
* @param {string} separator - Separator to use for string splitting (default: ',')
323323
* @returns {Array<string>} The array value with string elements
324324
*/
325-
export function getStringArrayValue(input: ?(string | Array<mixed>), defaultValue: Array<string> = [], separator: string = ','): Array<string> {
325+
export function getStringArrayValue(input: ?(string | $ReadOnlyArray<mixed>), defaultValue: Array<string> = [], separator: string = ','): Array<string> {
326326
if (input == null) {
327327
return defaultValue
328328
}
329+
// Accepts $ReadOnlyArray so callers can pass an Array<string> (Flow arrays are invariant, so a
330+
// plain Array<mixed> param rejects it). getArrayValue still wants a mutable array and returns its
331+
// input as-is, so copy here -- free in practice, since the .map() below allocates anyway.
332+
const asMutable = Array.isArray(input) ? [...input] : input
329333
// Cast: getArrayValue takes Array<mixed> and only ever returns defaultValue unchanged, but
330334
// arrays are invariant so Array<string> is not accepted as Array<mixed>.
331-
const raw = getArrayValue(input, (defaultValue: any), separator)
335+
const raw = getArrayValue(asMutable, (defaultValue: any), separator)
332336
return raw.map((item) => (typeof item === 'string' ? item : String(item ?? '')))
333337
}
334338

‎jgclark.RepeatExtensions/src/repeatMain.js‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,6 @@ async function runTaskSorterAfterRepeatsImpl(
162162
for (const heading of headingList) {
163163
logInfo('runTaskSorterAfterRepeats', `- Sorting tasks under heading '${heading}'`)
164164
// Two problems, neither fixable from here. (1) sortFields is Array<string>, but dwertheimer.TaskSorting's sortTasksUnderHeading declares
165-
// `_sortOrder: ?(string | Array<mixed>)` - Flow arrays are invariant, so Array<string> is rejected; that param should be
166-
// `?(string | $ReadOnlyArray<string>)`. (2) noteToUse is CoreNoteFields but `_noteOverride` is `TNote | typeof Editor | null`.
167-
// $FlowIgnore[incompatible-call] TNote vs CoreNoteFields, and Array<string> vs Array<mixed>
168165
await sortTasksUnderHeading(heading, sortFields, noteToUse)
169166
}
170167
} else {

0 commit comments

Comments
 (0)