Skip to content

Commit d0c6632

Browse files
authored
LPM fixes, Let + minor changes (#401)
* Fixed LPM and added Let library * minor fixes. Added Let * Update package.json * fix requests * version warnings
1 parent 2ebb6d0 commit d0c6632

File tree

8 files changed

+91
-36
lines changed

8 files changed

+91
-36
lines changed

Common/LPM/LPM.wl

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ convertVersion[any_PacletObject] := convertVersion[any["Version"]]
2323
inspectPackages[dir_String, cbk_] := Module[{
2424
packages
2525
},
26-
packages = Get /@ FileNames["PacletInfo.wl", {dir}, {2}];
26+
packages = Get /@ DeleteDuplicatesBy[FileNames["PacletInfo.wl" | "PacletInfo.m", {dir}, {2}], DirectoryName];
2727

2828
With[{found = SortBy[PacletFind[#["Name"] ], convertVersion]},
2929

@@ -56,8 +56,6 @@ PacletRepositories[list_List, OptionsPattern[]] := Module[{projectDir, info, rep
5656
CreateDirectory[projectDir, CreateIntermediateDirectories->True];
5757
If[!FileExistsQ[projectDir], Echo["LPM >> Cannot create project directory by path "<>projectDir<>" !!!"]; Abort[] ];
5858
];
59-
60-
Echo["LPM >> project directory >> "<>projectDir];
6159

6260

6361
If[FileExistsQ[FileNameJoin[{projectDir, ".wl_timestamp"}] ] && !OptionValue["ForceUpdates"],
@@ -66,27 +64,26 @@ PacletRepositories[list_List, OptionsPattern[]] := Module[{projectDir, info, rep
6664
skipUpdates = True;
6765

6866
];
69-
Echo[StringJoin["LPM >> updated last time >> ", time // TextString] ];
7067
]
7168
];
7269

7370
(* PASSIVE mode :: skips all checks and just loads wl_package folder *)
7471
If[skipUpdates,
7572
inspectPackages[FileNameJoin[{projectDir, "wl_packages"}], OptionValue["ConflictResolutionFunction"] ];
76-
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ FileNames["PacletInfo.wl", {#}, {2}]& @ FileNameJoin[{projectDir, "wl_packages"}];
73+
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ DeleteDuplicatesBy[FileNames["PacletInfo.wl" | "PacletInfo.m", {#}, {2}], DirectoryName]& @ FileNameJoin[{projectDir, "wl_packages"}];
7774
Return[Null, Module];
7875
];
7976

80-
Echo["LPM >> fetching packages info..."];
77+
Echo["LPM >> fetching packages info"];
8178

8279
If[FailureQ[ URLFetch["https://github.com"] ],
8380
If[!electronConfirmed,
84-
Echo["LPM >> ERROR! no internet connection to github.com!"];
81+
Echo["LPM >> ERROR! no connection to github.com!"];
8582

8683
If[!MissingQ[cache],
8784
Echo["LPM >> using stored data"];
8885
inspectPackages[FileNameJoin[{projectDir, "wl_packages"}], OptionValue["ConflictResolutionFunction"] ];
89-
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ FileNames["PacletInfo.wl", {#}, {2}]& @ FileNameJoin[{projectDir, "wl_packages"}];
86+
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ DeleteDuplicatesBy[FileNames["PacletInfo.wl" | "PacletInfo.m", {#}, {2}], DirectoryName]& @ FileNameJoin[{projectDir, "wl_packages"}];
9087
Return[Null, Module];
9188
,
9289
Echo["LPM >> ERROR! no cache found ;()"];
@@ -184,7 +181,7 @@ PacletRepositories[list_List, OptionsPattern[]] := Module[{projectDir, info, rep
184181

185182
(* finally load dirs *)
186183
inspectPackages[FileNameJoin[{projectDir, "wl_packages"}], OptionValue["ConflictResolutionFunction"] ];
187-
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ FileNames["PacletInfo.wl", {#}, {2}]& @ FileNameJoin[{projectDir, "wl_packages"}];
184+
Map[pacletDirectoryLoad] @ Map[DirectoryName] @ DeleteDuplicatesBy[FileNames["PacletInfo.wl" | "PacletInfo.m", {#}, {2}], DirectoryName]& @ FileNameJoin[{projectDir, "wl_packages"}];
188185
]
189186

190187
Options[PacletRepositories] = {"Directory"->None, "Passive"->False, "ForceUpdates" -> False, "AutomaticUpdates"->True, "MaxVersionDiff" -> None, "UpdateInterval" -> Quantity[14, "Days"], "ConflictResolutionFunction" -> Function[{conflicting, true},
@@ -212,7 +209,7 @@ convertVersion[str_String] := ToExpression[StringReplace[str, "." -> ""]]
212209
CheckUpdates[a_Association, Rule[Github, _]] := Module[{package, new, now},
213210
(* fetch any *)
214211
package = FetchInfo[a];
215-
If[!AssociationQ[package], Echo["LPM >> cannot check the github! skipping..."]; Return[False, Module]];
212+
If[!AssociationQ[package], Echo["LPM >> cannot check. Skipping..."]; Return[False, Module]];
216213

217214
(* a feature on how we can detect on what we are looking at *)
218215
If[KeyExistsQ[package, "tag_name"],
@@ -246,14 +243,14 @@ FetchInfo[a_Association, Rule[Github, url_String]] := Module[{new, data},
246243
(* extracting from given url *)
247244
new = StringCases[url, RegularExpression[".com\\/(.*).git"]->"$1"]//First // Quiet;
248245
If[!StringQ[new], new = StringCases[url, RegularExpression[".com\\/(.*)"]->"$1"]//First];
249-
Echo["LPM >> fetching releases info for "<>new<>" on a Github..."];
246+
Echo["LPM >> fetching releases info for "<>new<>" on Github..."];
250247

251248
(* here we FETCH GITHUB API RESPONCE and use releases metadata *)
252249
data = urlImport["https://api.github.com/repos/"<>new<>"releases/latest", "JSON"] // Association // Quiet;
253250

254251
(* if there is NO RELEASES *)
255252
If[!StringQ[data["zipball_url"]],
256-
Print["Releases are not available for now... taking a master branch"];
253+
Print["Releases are not available. Taking a master branch"];
257254
(* TAKE MASTER Branch *)
258255
Return[FetchInfo[a, Rule[Github, Rule[url, "master"]]]];
259256
];
@@ -268,19 +265,25 @@ Module[{new, data},
268265
(* extracting from given url *)
269266
new = StringCases[url, RegularExpression[".com\\/(.*).git"]->"$1"]//First // Quiet;
270267
If[!StringQ[new], new = StringCases[url, RegularExpression[".com\\/(.*)"]->"$1"]//First];
271-
Echo["LPM >> fetching info for "<>new<>" on a Github..."];
268+
Echo["LPM >> fetching info for "<>new<>" on Github..."];
272269

273270
(* here we FETCH PACLETINFO.WL file and use its metadata *)
274-
data = Check[urlGet["https://raw.githubusercontent.com/"<>new<>"/"<>ToLowerCase[branch]<>"/PacletInfo.wl"], $Failed];
275-
271+
data = urlGet["https://raw.githubusercontent.com/"<>new<>"/"<>ToLowerCase[branch]<>"/PacletInfo.wl"] // Quiet;
272+
If[!MatchQ[ToString[Head[data] ], "PacletObject" | "Paclet"],
273+
data = urlGet["https://raw.githubusercontent.com/"<>new<>"/"<>ToLowerCase[branch]<>"/PacletInfo.m"];
274+
];
275+
276276
(* if failed. we just STOP *)
277-
If[FailureQ[data],
277+
278+
If[!MatchQ[ToString[Head[data] ], "PacletObject" | "Paclet"], (* some issue with contexts *)
279+
Echo["Failed"];
280+
Echo[ToString[data, InputForm] ];
278281
Echo["LPM >> ERROR cannot get "<>new<>"!"];
279282
Echo["LPM >> Aborting"];
280283
Abort[];
281284
];
282285

283-
Join[a, data//First, <|"git-url"->new|>]
286+
Join[a, Switch[ToString[Head[data] ], "PacletObject", data//First, "Paclet", Association @ KeyValueMap[Function[{k,v}, ToString[k]->v], Association @@ data] ], <|"git-url"->new|>]
284287
]
285288

286289
(* general function *)
@@ -303,31 +306,31 @@ InstallPaclet[dir_String][a_Association, Rule[Github, url_String]] := Module[{di
303306

304307
(* in a case of update, directory will probably be there.. cleaning it! *)
305308
If[FileExistsQ[dirName],
306-
Echo["LPM >> package folder "<>dirName<>" already exists!"];
309+
Echo["LPM >> package folder already exists!"];
307310
Echo["LPM >> purging..."];
308311
DeleteDirectory[dirName, DeleteContents -> True];
309312
];
310313

311314
(* download release *)
312-
Echo["LPM >> fetching a release..."];
315+
Echo["LPM >> fetching a release"];
313316
urlDownload[a["zipball_url"], FileNameJoin[{dir, "___temp.zip"}]];
314317

315318
(* extract to temporary directory and copy *)
316-
Echo["LPM >> extracting..."];
319+
Echo["LPM >> extracting"];
317320
ExtractArchive[FileNameJoin[{dir, "___temp.zip"}], FileNameJoin[{dir, "___temp"}]];
318321
DeleteFile[FileNameJoin[{dir, "___temp.zip"}]];
319322

320323
(* locate PacletInfo, if it is not there, this is very bad. *)
321-
pacletPath = FileNames["PacletInfo.wl", FileNameJoin[{dir, "___temp"}], 2] // First;
324+
pacletPath = FileNames["PacletInfo.wl" | "PacletInfo.m", FileNameJoin[{dir, "___temp"}], 2] // First;
322325

323326
If[!FileExistsQ[pacletPath], Echo["LPM >> FAILED!!! to fetch by "<>ToString[pacletPath]]; Abort[]];
324327
pacletPath = DirectoryName[pacletPath];
325328

326-
Echo[StringTemplate["LPM >> copying... from `` to ``"][pacletPath, dirName]];
329+
Echo[StringTemplate["LPM >> copying from `` to ``"][pacletPath, dirName]];
327330

328331
CopyDirectory[pacletPath, dirName];
329332
DeleteDirectory[FileNameJoin[{dir, "___temp"}], DeleteContents -> True];
330-
Print["LPM >> finished!"];
333+
Print["LPM >> finished"];
331334

332335
a
333336
]
@@ -341,7 +344,7 @@ InstallPaclet[dir_String][a_Association, Rule[Github, Rule[url_String, branch_St
341344
If[MissingQ[a["git-url"]], Echo["LPM >> ERROR!!! not git-url was found"]; Abort[]];
342345

343346
(* construct name of the folder *)
344-
dirName = FileNameJoin[{dirName, StringReplace[a["Name"], "/"->"_"]}];
347+
dirName = FileNameJoin[{dirName, StringReplace[Lookup[a, "Name", a[Name] ], "/"->"_"]}];
345348

346349
If[FileExistsQ[dirName],
347350
Echo["LPM >> package folder "<>dirName<>" already exists!"];
@@ -353,20 +356,20 @@ InstallPaclet[dir_String][a_Association, Rule[Github, Rule[url_String, branch_St
353356
Echo["LPM >> fetching a zip archive from the master branch..."];
354357
urlDownload["https://github.com/"<>a["git-url"]<>"/zipball/"<>ToLowerCase[branch], FileNameJoin[{dir, "___temp.zip"}]];
355358

356-
Echo["LPM >> extracting..."];
359+
Echo["LPM >> extracting"];
357360
ExtractArchive[FileNameJoin[{dir, "___temp.zip"}], FileNameJoin[{dir, "___temp"}]];
358361
DeleteFile[FileNameJoin[{dir, "___temp.zip"}]];
359362

360-
pacletPath = FileNames["PacletInfo.wl", FileNameJoin[{dir, "___temp"}], 2] // First;
363+
pacletPath = FileNames["PacletInfo.wl" | "PacletInfo.m", FileNameJoin[{dir, "___temp"}], 2] // First;
361364

362365
If[!FileExistsQ[pacletPath], Echo["LPM >> FAILED!!! to fetch by "<>ToString[pacletPath]]; Abort[]];
363366
pacletPath = DirectoryName[pacletPath];
364367

365-
Echo[StringTemplate["LPM >> copying... from `` to ``"][pacletPath, dirName]];
368+
Echo[StringTemplate["LPM >> copying from `` to ``"][pacletPath, dirName]];
366369

367370
CopyDirectory[pacletPath, dirName];
368371
DeleteDirectory[FileNameJoin[{dir, "___temp"}], DeleteContents -> True];
369-
Print["LPM >> finished!"];
372+
Print["LPM >> finished"];
370373

371374
a
372375
]

Frontend/Downloader.wl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,31 @@ BeginPackage["CoffeeLiqueur`Notebook`HTTPDownLoader`", {
2626
handler["GET"][request_] := With[{path = URLDecode[request["Query", "path"] ], rangesString = Lookup[request["Headers"], "Range", False]},
2727
Echo["Downloader >> Get request"];
2828

29+
If[!FileExistsQ[path],
30+
Echo["File: "<>path<>" does not exist"];
31+
<|
32+
"Code" -> 404,
33+
"Headers" -> <|
34+
"Content-Length" -> 0,
35+
"Connection"-> "Keep-Alive"
36+
|>
37+
|> // Return;
38+
];
39+
2940
If[rangesString === False,
30-
Return[ImportFile[path, "Base"->Nothing] ]
41+
42+
With[{file = ReadByteArray[path]},
43+
<|
44+
"Body" -> file,
45+
"Code" -> 200,
46+
"Headers" -> <|
47+
"Content-Type" -> GetMIMEType[path],
48+
"Content-Length" -> Length[file],
49+
"Connection"-> "Keep-Alive",
50+
"Keep-Alive" -> "timeout=5, max=1000"
51+
|>
52+
|> // Return;
53+
];
3154
];
3255

3356
With[{

Kernel/Extensions.wl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Table[
3939
, {i, Select[Packages // Keys, (Packages[#, "enabled"] && KeyExistsQ[Packages[#, "wljs-meta"], param])&]}] // Flatten;
4040

4141

42-
Repositories[list_List, OptionsPattern[] ] := Module[{projectDir, info, repos, cache, updated, removed, new, current, updatable, skipUpdates = False, versionControl, maxVersionDiff = OptionValue["MaxVersionDiff"]},
42+
Repositories[list_List, OptionsPattern[] ] := Module[{projectDir, info, repos, cache, updated, removed, new, current, updatable, automaticUpdates = OptionValue["AutomaticUpdates"], skipUpdates = False, versionControl, maxVersionDiff = OptionValue["MaxVersionDiff"]},
4343
(* making key-values pairs *)
4444
repos = (#-><|"key"->#|>)&/@list // Association;
4545

@@ -155,7 +155,10 @@ Repositories[list_List, OptionsPattern[] ] := Module[{projectDir, info, repos, c
155155
new = InstallPaclet[projectDir] /@ new;
156156

157157
(* what must be updated *)
158-
updatable = Select[current, CheckUpdates];
158+
updatable = If[automaticUpdates, Select[current, CheckUpdates],
159+
Echo["WLJS Extensions >> Automatic updates were disabled by default since 2.5.6"];
160+
{}
161+
];
159162
(* will be updated *)
160163
updated = ((#->repos[#])&/@ Keys[updatable]) // Association;
161164

@@ -212,7 +215,7 @@ Repositories[list_List, OptionsPattern[] ] := Module[{projectDir, info, repos, c
212215
$packages = sortPackages[$packages];
213216
]
214217

215-
Options[Repositories] = {"Directory"->Directory[], "ForceUpdates" -> False, "MaxVersionDiff" -> None, "UpdateInterval" -> Quantity[4, "Days"]}
218+
Options[Repositories] = {"Directory"->Directory[], "ForceUpdates" -> False, "MaxVersionDiff" -> None, "UpdateInterval" -> Quantity[4, "Days"], "AutomaticUpdates"->True}
216219

217220
sortPackages[assoc_Association] := With[{},
218221
Map[

Kernel/LocalKernel.wl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,8 @@ start[k_LocalKernelObject] := Module[{link},
273273
LinkWrite[link, EnterTextPacket["<<JerryI`Misc`WLJS`Transport`"] ];
274274
LinkWrite[link, EnterTextPacket["<<KirillBelov`CSockets`EventsExtension`"] ];
275275
LinkWrite[link, EnterTextPacket["<<KirillBelov`LTP`Events`"] ];
276+
LinkWrite[link, EnterTextPacket["<<LetWL`"] ];
277+
276278

277279
(* unknown bug, doesn't work in initialization ... *)
278280
LinkWrite[link, EnterTextPacket["Unprotect[Interpretation, InterpretationBox]"] ];
@@ -312,6 +314,10 @@ checkState[k_LocalKernelObject] := Module[{},
312314
EventFire[k, "Error", "Timeout"];
313315
]
314316

317+
(* [NOTE] You may easily overload the evaluation que on Windows machines *)
318+
(* It will stall during LinkWrite *)
319+
(* Mostly affects the initial start, then works without issues *)
320+
315321
LocalKernelObject /: GenericKernel`SubmitTransaction[k_LocalKernelObject, t_] := With[{ev = t["Evaluator"], s = Transaction`Serialize[t]},
316322
LinkWrite[k["Link"], EnterExpressionPacket[ Internal`Kernel`Apply[ ev, s ] ] // Unevaluated ]
317323
]
@@ -324,6 +330,10 @@ GenericKernel`Stdout[k_LocalKernelObject][any_] := k["LTPSocket"][any]
324330

325331
SetAttributes[GenericKernel`Async, HoldRest]
326332

333+
(* [NOTE] You may easily overload the evaluation que on Windows machines *)
334+
(* It will stall during LinkWrite *)
335+
(* Mostly affects the initial start, then works without issues *)
336+
327337
LocalKernelObject /: GenericKernel`Init[k_LocalKernelObject, expr_, OptionsPattern[] ] := With[{once = OptionValue["Once"], tracker = OptionValue["TrackingProgress"]},
328338
If[!once,
329339
With[{

Scripts/bundle.wls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ PacletRepositories[{
4848
Github -> "https://github.com/JerryI/WebSocketHandler" -> "master",
4949
Github -> "https://github.com/JerryI/CSocketListener" -> "master",
5050
Github -> "https://github.com/JerryI/wl-wlx" -> "master",
51-
Github -> "https://github.com/JerryI/wl-misc" -> "main"
51+
Github -> "https://github.com/JerryI/wl-misc" -> "main",
52+
Github -> "https://github.com/lshifr/LetWL" -> "master"
5253
}, "Directory" -> Directory[], "MaxVersionDiff"-> 3 ]
5354

5455

Scripts/start.wls

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ PacletRepositories[{
1818
Github -> "https://github.com/JerryI/WebSocketHandler" -> "master",
1919
Github -> "https://github.com/JerryI/CSocketListener" -> "master",
2020
Github -> "https://github.com/JerryI/wl-wlx" -> "master",
21-
Github -> "https://github.com/JerryI/wl-misc" -> "main"
21+
Github -> "https://github.com/JerryI/wl-misc" -> "main",
22+
Github -> "https://github.com/lshifr/LetWL" -> "master"
2223
}, "Directory" -> Directory[], "MaxVersionDiff"-> 1, "AutomaticUpdates"-> False ]
2324

2425
(* web-server *)
@@ -32,6 +33,8 @@ Needs["KirillBelov`HTTPHandler`Extensions`"]
3233
Needs["KirillBelov`WebSocketHandler`"]
3334
Needs["KirillBelov`LTP`"]
3435

36+
Needs["LetWL`"]
37+
3538

3639
Needs["CoffeeLiqueur`Notebook`Utils`"];
3740

@@ -129,6 +132,17 @@ With[{appJSON = Import[FileNameJoin[{Directory[], "package.json"}], "RawJSON"]},
129132
Echo["System`$Env"];
130133
Echo[ToString[$Env, InputForm] ];
131134

135+
versionToNumber[ver_String] := FromDigits[ToExpression@StringSplit[ver, "."], 1000];
136+
137+
If[versionToNumber[$VersionNumber] > versionToNumber["14.2"],
138+
Echo["Warning: your Wolfram Kernel version is higher, that tested with WLJS Notebook. We do not guarantee it will work"];
139+
];
140+
141+
If[versionToNumber[$VersionNumber] < versionToNumber["13.1"],
142+
Echo["Error: your Wolfram Kernel version is lower than 13.1. WLJS App won't work. We are sorry"];
143+
Echo["You can always download a freeware Wolfram Engine"];
144+
Exit[-1];
145+
];
132146

133147
MergeDirectories[source_String, target_String] := (
134148
Echo[StringTemplate["Copy directory `` to ``"][source, target]];

Scripts/update.wls

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ PacletRepositories[{
2020
Github -> "https://github.com/JerryI/WebSocketHandler" -> "master",
2121
Github -> "https://github.com/JerryI/CSocketListener" -> "master",
2222
Github -> "https://github.com/JerryI/wl-wlx" -> "master",
23-
Github -> "https://github.com/JerryI/wl-misc" -> "main"
23+
Github -> "https://github.com/JerryI/wl-misc" -> "main",
24+
Github -> "https://github.com/lshifr/LetWL" -> "master"
2425
}, "Directory" -> Directory[], "MaxVersionDiff"-> 1 ]
2526

2627

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "wljs-notebook",
3-
"version": "2.7.5",
3+
"version": "2.7.6",
44
"recommended-client-version": "2.6.3",
55
"description": "Dynamic Notebook Environment for Wolfram Language written in Javascript",
66
"author": {

0 commit comments

Comments
 (0)