@breakside/jskit 2026.1.0 → 2026.2.1

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 (53) hide show
  1. package/Frameworks/DOM.jsframework/Info.json +2 -2
  2. package/Frameworks/DOM.jsframework/io.breakside.JSKit.DOM-bundle.js +2 -2
  3. package/Frameworks/FontKit.jsframework/Info.json +2 -2
  4. package/Frameworks/FontKit.jsframework/io.breakside.JSKit.FontKit-bundle.js +2 -2
  5. package/Frameworks/Foundation.jsframework/Info.json +2 -2
  6. package/Frameworks/Foundation.jsframework/JS/JSBundle+HTML.js +12 -2
  7. package/Frameworks/Foundation.jsframework/JS/JSFile.js +1 -1
  8. package/Frameworks/Foundation.jsframework/JS/JSFileManager+HTML.js +3 -0
  9. package/Frameworks/Foundation.jsframework/JS/JSTextLayoutManager.js +2 -2
  10. package/Frameworks/Foundation.jsframework/io.breakside.JSKit.Foundation-bundle.js +2 -2
  11. package/Frameworks/SecurityKit.jsframework/Info.json +2 -2
  12. package/Frameworks/SecurityKit.jsframework/io.breakside.JSKit.SecurityKit-bundle.js +2 -2
  13. package/Info.json +2 -2
  14. package/Node/io.breakside.jskit-bundle.js +2 -2
  15. package/Root/Frameworks/APIKit/Info.yaml +1 -1
  16. package/Root/Frameworks/APIKitTesting/Info.yaml +1 -1
  17. package/Root/Frameworks/AuthKit/Info.yaml +1 -1
  18. package/Root/Frameworks/CSSOM/Info.yaml +1 -1
  19. package/Root/Frameworks/ChartKit/Info.yaml +1 -1
  20. package/Root/Frameworks/ConferenceKit/Info.yaml +1 -1
  21. package/Root/Frameworks/DBKit/Info.yaml +1 -1
  22. package/Root/Frameworks/DOM/Info.yaml +1 -1
  23. package/Root/Frameworks/Dispatch/Info.yaml +1 -1
  24. package/Root/Frameworks/FontKit/Info.yaml +1 -1
  25. package/Root/Frameworks/Foundation/Info.yaml +1 -1
  26. package/Root/Frameworks/Foundation/JSBundle+HTML.js +12 -2
  27. package/Root/Frameworks/Foundation/JSFile.js +1 -1
  28. package/Root/Frameworks/Foundation/JSFileManager+HTML.js +3 -0
  29. package/Root/Frameworks/Foundation/JSTextLayoutManager.js +2 -2
  30. package/Root/Frameworks/ImageKit/Info.yaml +1 -1
  31. package/Root/Frameworks/MediaKit/Info.yaml +1 -1
  32. package/Root/Frameworks/MediaKitUI/Info.yaml +1 -1
  33. package/Root/Frameworks/NotificationKit/Info.yaml +1 -1
  34. package/Root/Frameworks/PDFKit/Info.yaml +1 -1
  35. package/Root/Frameworks/QRKit/Info.yaml +1 -1
  36. package/Root/Frameworks/SearchKit/Info.yaml +1 -1
  37. package/Root/Frameworks/SecurityKit/Info.yaml +1 -1
  38. package/Root/Frameworks/ServerKit/Info.yaml +1 -1
  39. package/Root/Frameworks/ServerKitTesting/Info.yaml +1 -1
  40. package/Root/Frameworks/TestKit/Info.yaml +1 -1
  41. package/Root/Frameworks/UIKit/Info.yaml +1 -1
  42. package/Root/Frameworks/UIKit/UIAnimation.js +1 -1
  43. package/Root/Frameworks/UIKit/UICollectionViewCell.js +10 -1
  44. package/Root/Frameworks/UIKit/UIHTMLApplication.js +8 -1
  45. package/Root/Frameworks/UIKit/UIHTMLContentEditableTextInputManager.js +14 -3
  46. package/Root/Frameworks/UIKit/UIHTMLTextRun.js +9 -5
  47. package/Root/Frameworks/UIKit/UIMenu.js +55 -0
  48. package/Root/Frameworks/UIKit/UIMenuView.js +18 -2
  49. package/Root/Frameworks/UIKit/UIPopupWindow.js +8 -0
  50. package/Root/Frameworks/UIKit/UIWindowServer.js +3 -0
  51. package/Root/Frameworks/UIKitTesting/Info.yaml +1 -1
  52. package/Root/Templates/html/${PROJECT_NAME}/www/HTMLAppBootstrapper.js +3 -0
  53. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.DOM",
4
- "JSBundleVersion": "2026.1.0",
4
+ "JSBundleVersion": "2026.2.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "DOM+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
12
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
13
13
  }
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.DOM",
6
- "JSBundleVersion": "2026.1.0",
6
+ "JSBundleVersion": "2026.2.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.DOM'] = {
11
11
  "node": "DOM+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
14
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
15
15
  },
16
16
  "Resources": [],
17
17
  "ResourceLookup": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.FontKit",
4
- "JSBundleVersion": "2026.1.0",
4
+ "JSBundleVersion": "2026.2.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
8
8
  "html": "FontKit+HTML.js"
9
9
  },
10
10
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
11
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
11
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
12
12
  }
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.JSKit.FontKit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.FontKit",
6
- "JSBundleVersion": "2026.1.0",
6
+ "JSBundleVersion": "2026.2.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
10
10
  "html": "FontKit+HTML.js"
11
11
  },
12
12
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
13
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
13
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
14
14
  },
15
15
  "Resources": [],
16
16
  "ResourceLookup": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.Foundation",
4
- "JSBundleVersion": "2026.1.0",
4
+ "JSBundleVersion": "2026.2.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "Foundation+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
12
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
13
13
  }
@@ -19,6 +19,10 @@
19
19
  // #import "JSURLResponse.js"
20
20
  'use strict';
21
21
 
22
+ (function(){
23
+
24
+ var logger = JSLog("foundation", "bundle");
25
+
22
26
  JSBundle.definePropertiesFromExtensions({
23
27
  getResourceData: function(metadata, completion, target){
24
28
  if (!completion){
@@ -27,7 +31,11 @@ JSBundle.definePropertiesFromExtensions({
27
31
  var session = JSURLSession.shared;
28
32
  var url = JSURL.initWithString(metadata.htmlURL);
29
33
  var task = session.dataTaskWithURL(url, function(error){
30
- if (error !== null || task.response.statusClass != JSURLResponse.StatusClass.success){
34
+ if (error !== null){
35
+ logger.error("error getting resource data (%{public}): %{error}", url.encodedString, error);
36
+ completion.call(target, null);
37
+ }else if (task.response.statusClass != JSURLResponse.StatusClass.success){
38
+ logger.error("unable to fetch resource data (%{public}): HTTP %d", url.encodedString, task.response.statusCode);
31
39
  completion.call(target, null);
32
40
  }else{
33
41
  completion.call(target, task.response.data);
@@ -36,4 +44,6 @@ JSBundle.definePropertiesFromExtensions({
36
44
  task.resume();
37
45
  return completion.promise;
38
46
  }
39
- });
47
+ });
48
+
49
+ })();
@@ -73,7 +73,7 @@ JSFile.unregisterContentTypeForFileExtension = function(contentType, fileExtensi
73
73
  };
74
74
 
75
75
  JSFile.contentTypeForFileExtension = function(fileExtension){
76
- return JSFile.contentTypesByFileExtension[fileExtension] || null;
76
+ return JSFile.contentTypesByFileExtension[fileExtension.toLowerCase()] || null;
77
77
  };
78
78
 
79
79
  JSClass("JSDataFile", JSFile, {
@@ -93,6 +93,9 @@ JSClass("JSHTMLFileManager", JSFileManager, {
93
93
  };
94
94
  request.onsuccess = function JSFileManager_open_onsuccess(e){
95
95
  manager._db = e.target.result;
96
+ manager._db.onclose = function JSFileManager_db_onclose(e){
97
+ logger.warn("database closed by browser");
98
+ };
96
99
  if (oldVersion === 1){
97
100
  var v1url = manager._rootURL.appendingPathComponents(["Containers", "io.breakside.JSKit.Foundation.JSFileManager"], true);
98
101
  var v2url = manager.persistentContainerURL;
@@ -490,7 +490,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
490
490
  line: {
491
491
  get: function(){
492
492
  var container = this.container;
493
- if (container !== null){
493
+ if (container !== null && container.textFrame !== null){
494
494
  return container.textFrame.lines[this._lineIndex];
495
495
  }
496
496
  return null;
@@ -500,7 +500,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
500
500
  rect: {
501
501
  get: function(){
502
502
  var container = this.container;
503
- if (container !== null){
503
+ if (container !== null && container.textFrame !== null){
504
504
  var line = container.textFrame.lines[this._lineIndex];
505
505
  var rect = JSRect(line.origin, line.size);
506
506
  return this._layoutManager.convertRectFromTextContainer(rect, container);
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.Foundation",
6
- "JSBundleVersion": "2026.1.0",
6
+ "JSBundleVersion": "2026.2.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.Foundation'] = {
11
11
  "node": "Foundation+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
14
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
15
15
  },
16
16
  "Resources": [
17
17
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "JSBundleType": "framework",
3
3
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
4
- "JSBundleVersion": "2026.1.0",
4
+ "JSBundleVersion": "2026.2.1",
5
5
  "JSDevelopmentLanguage": "en",
6
6
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
7
7
  "JSBundleEnvironments": {
@@ -9,5 +9,5 @@
9
9
  "node": "SecurityKit+Node.js"
10
10
  },
11
11
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
12
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
12
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
13
13
  }
@@ -3,7 +3,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "framework",
5
5
  "JSBundleIdentifier": "io.breakside.JSKit.SecurityKit",
6
- "JSBundleVersion": "2026.1.0",
6
+ "JSBundleVersion": "2026.2.1",
7
7
  "JSDevelopmentLanguage": "en",
8
8
  "JSCopyright": "Copyright © 2020 Breakside Inc.",
9
9
  "JSBundleEnvironments": {
@@ -11,7 +11,7 @@ JSBundle.bundles['io.breakside.JSKit.SecurityKit'] = {
11
11
  "node": "SecurityKit+Node.js"
12
12
  },
13
13
  "JSLicenseNotice": "Licensed under the Breakside Public License, Version 1.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nIf a copy of the License was not distributed with this file, you may\nobtain a copy at\n\n http://breakside.io/licenses/LICENSE-1.0.txt\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n",
14
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
14
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
15
15
  },
16
16
  "Resources": [],
17
17
  "ResourceLookup": {
package/Info.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "JSBundleType": "node",
3
3
  "JSBundleIdentifier": "io.breakside.jskit",
4
- "JSBundleVersion": "2026.1.0",
4
+ "JSBundleVersion": "2026.2.1",
5
5
  "JSExecutableName": "jskit",
6
6
  "NPMOrganization": "breakside",
7
7
  "JSResources": [
8
8
  "Tests/HTMLTestRunner.js",
9
9
  "Tests/NodeTestRunner.js"
10
10
  ],
11
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
11
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
12
12
  }
@@ -3,14 +3,14 @@ JSBundle.bundles['io.breakside.jskit'] = {
3
3
  "Info": {
4
4
  "JSBundleType": "node",
5
5
  "JSBundleIdentifier": "io.breakside.jskit",
6
- "JSBundleVersion": "2026.1.0",
6
+ "JSBundleVersion": "2026.2.1",
7
7
  "JSExecutableName": "jskit",
8
8
  "NPMOrganization": "breakside",
9
9
  "JSResources": [
10
10
  "Tests/HTMLTestRunner.js",
11
11
  "Tests/NodeTestRunner.js"
12
12
  ],
13
- "GitRevision": "2345355a065b38aeedad172cfe7c337d1d3f297b"
13
+ "GitRevision": "a5d9a8ccacabe466afd5d0db9fba33bba7941a6a"
14
14
  },
15
15
  "Resources": [
16
16
  {
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSIncludeDirectories:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.APIKitTesting
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.AuthKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.CSSOM
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ChartKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  # JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ConferenceKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DBKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.DOM
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Dispatch
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSCopyright: Copyright © 2020 Breakside Inc.
5
5
  JSBundleEnvironments:
6
6
  html: Dispatch+HTML.js
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.FontKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.Foundation
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -19,6 +19,10 @@
19
19
  // #import "JSURLResponse.js"
20
20
  'use strict';
21
21
 
22
+ (function(){
23
+
24
+ var logger = JSLog("foundation", "bundle");
25
+
22
26
  JSBundle.definePropertiesFromExtensions({
23
27
  getResourceData: function(metadata, completion, target){
24
28
  if (!completion){
@@ -27,7 +31,11 @@ JSBundle.definePropertiesFromExtensions({
27
31
  var session = JSURLSession.shared;
28
32
  var url = JSURL.initWithString(metadata.htmlURL);
29
33
  var task = session.dataTaskWithURL(url, function(error){
30
- if (error !== null || task.response.statusClass != JSURLResponse.StatusClass.success){
34
+ if (error !== null){
35
+ logger.error("error getting resource data (%{public}): %{error}", url.encodedString, error);
36
+ completion.call(target, null);
37
+ }else if (task.response.statusClass != JSURLResponse.StatusClass.success){
38
+ logger.error("unable to fetch resource data (%{public}): HTTP %d", url.encodedString, task.response.statusCode);
31
39
  completion.call(target, null);
32
40
  }else{
33
41
  completion.call(target, task.response.data);
@@ -36,4 +44,6 @@ JSBundle.definePropertiesFromExtensions({
36
44
  task.resume();
37
45
  return completion.promise;
38
46
  }
39
- });
47
+ });
48
+
49
+ })();
@@ -73,7 +73,7 @@ JSFile.unregisterContentTypeForFileExtension = function(contentType, fileExtensi
73
73
  };
74
74
 
75
75
  JSFile.contentTypeForFileExtension = function(fileExtension){
76
- return JSFile.contentTypesByFileExtension[fileExtension] || null;
76
+ return JSFile.contentTypesByFileExtension[fileExtension.toLowerCase()] || null;
77
77
  };
78
78
 
79
79
  JSClass("JSDataFile", JSFile, {
@@ -93,6 +93,9 @@ JSClass("JSHTMLFileManager", JSFileManager, {
93
93
  };
94
94
  request.onsuccess = function JSFileManager_open_onsuccess(e){
95
95
  manager._db = e.target.result;
96
+ manager._db.onclose = function JSFileManager_db_onclose(e){
97
+ logger.warn("database closed by browser");
98
+ };
96
99
  if (oldVersion === 1){
97
100
  var v1url = manager._rootURL.appendingPathComponents(["Containers", "io.breakside.JSKit.Foundation.JSFileManager"], true);
98
101
  var v2url = manager.persistentContainerURL;
@@ -490,7 +490,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
490
490
  line: {
491
491
  get: function(){
492
492
  var container = this.container;
493
- if (container !== null){
493
+ if (container !== null && container.textFrame !== null){
494
494
  return container.textFrame.lines[this._lineIndex];
495
495
  }
496
496
  return null;
@@ -500,7 +500,7 @@ Object.defineProperties(JSTextLayoutManagerLineEnumerator.prototype, {
500
500
  rect: {
501
501
  get: function(){
502
502
  var container = this.container;
503
- if (container !== null){
503
+ if (container !== null && container.textFrame !== null){
504
504
  var line = container.textFrame.lines[this._lineIndex];
505
505
  var rect = JSRect(line.origin, line.size);
506
506
  return this._layoutManager.convertRectFromTextContainer(rect, container);
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ImageKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.MediaKitUI
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.NotificationKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2021 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.PDFKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.QRKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SearchKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.SecurityKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.ServerKitTesting
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.TestKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKit
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSBundleEnvironments:
@@ -121,7 +121,7 @@ UIAnimation.defaultInterpolationValueToPairWithValue = function(value){
121
121
  return JSRect.Zero;
122
122
  }
123
123
  if (value instanceof JSAffineTransform){
124
- return JSAffineTransform.Zero;
124
+ return JSAffineTransform.Identity;
125
125
  }
126
126
  if (value.isKindOfClass && value.isKindOfClass(JSColor)){
127
127
  return value.colorWithAlpha(0);
@@ -132,7 +132,16 @@ JSClass("UICollectionViewCell", UICollectionReusableView, {
132
132
  },
133
133
 
134
134
  mouseEntered: function(event){
135
- var shouldSelect = (!this.collectionView || !this.collectionView.delegate || !this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath || this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath(this.collectionView, this.collectionView.indexPathOfCell(this)));
135
+ if (!this.collectionView){
136
+ return;
137
+ }
138
+ if (this.collectionView._needsReload){
139
+ return;
140
+ }
141
+ if (this.collectionView._edit !== null){
142
+ return;
143
+ }
144
+ var shouldSelect = (!this.collectionView.delegate || !this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath || this.collectionView.delegate.collectionViewShouldSelectCellAtIndexPath(this.collectionView, this.collectionView.indexPathOfCell(this)));
136
145
  if (shouldSelect){
137
146
  this.over = true;
138
147
  }
@@ -73,12 +73,19 @@ JSClass("UIHTMLApplication", UIApplication, {
73
73
  if (options === undefined){
74
74
  options = {};
75
75
  }
76
- if (options.replacingApplication || url.scheme === "mailto" || url.scheme === "tel"){
76
+ if (options.replacingApplication){
77
77
  var application = this;
78
78
  var open = function(){
79
+ application.domWindow.addEventListener("visibilitychange", function(e){
80
+ if (application.domWindow.document.visibilityState === "visible"){
81
+ application.domWindow.location.reload();
82
+ }
83
+ });
79
84
  application.domWindow.location.href = url.encodedString;
80
85
  };
81
86
  this.stop(open);
87
+ }else if (url.scheme === "mailto" || url.scheme === "tel"){
88
+ this.domWindow.location.href = url.encodedString;
82
89
  }else{
83
90
  try{
84
91
  var child = this.domWindow.open(url.encodedString);
@@ -165,7 +165,14 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
165
165
  if (anchor.offset < 0 || focus.offset < 0){
166
166
  throw new Error("negative dom offset");
167
167
  }
168
- domSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
168
+ try{
169
+ domSelection.setBaseAndExtent(anchor.node, anchor.offset, focus.node, focus.offset);
170
+ }catch (e){
171
+ logger.debug("selection: @%d +%d", selection.range.location, selection.range.length);
172
+ logger.debug("anchor: %{public} @%d", anchor.toString(), anchor.offset);
173
+ logger.debug("focus: %{public} @%d", focus.toString(), focus.offset);
174
+ logger.error("failed to update html selection: %{error}", e);
175
+ }
169
176
  // logger.debug("setting dom selection: %d->%d", anchor.offset, focus.offset);
170
177
  if (domSelection.anchorNode){
171
178
  // logger.debug(" selection anchor: %{public} @ %d", domSelection.anchorNode.nodeValue, domSelection.anchorOffset);
@@ -463,8 +470,12 @@ JSClass('UIHTMLContentEditableTextInputManager', UITextInputManager, {
463
470
  if (this.shouldPreventSpaceInput || e.data !== " "){
464
471
  e.preventDefault();
465
472
  }
466
- this.textInputClient.insertText(e.data);
467
- this.scheduleDocumentSelectionUpdate();
473
+ if (e.data === null){
474
+ logger.warn("received null data for insertText, ignoring");
475
+ }else{
476
+ this.textInputClient.insertText(e.data);
477
+ this.scheduleDocumentSelectionUpdate();
478
+ }
468
479
  break;
469
480
  case "insertLineBreak":
470
481
  e.preventDefault();
@@ -203,9 +203,9 @@ JSClass("UIHTMLTextRun", JSTextRun, {
203
203
  var rect;
204
204
  var localIndex = index - this.range.location;
205
205
  localIndex *= this._maskFactor;
206
- var iterator = sharedElementForSizing.firstChild.nodeValue.userPerceivedCharacterIterator(localIndex);
207
- sharedDomRange.setStart(sharedElementForSizing.firstChild, iterator.range.location);
208
- sharedDomRange.setEnd(sharedElementForSizing.firstChild, iterator.range.end);
206
+ var iterator = sharedTextNodeForSizing.nodeValue.userPerceivedCharacterIterator(localIndex);
207
+ sharedDomRange.setStart(sharedTextNodeForSizing, iterator.range.location);
208
+ sharedDomRange.setEnd(sharedTextNodeForSizing, iterator.range.end);
209
209
  var clientRect = this._pickCorrectClientRectFromRects(sharedDomRange.getClientRects());
210
210
  if (clientRect === undefined){
211
211
  return JSRect(0, 0, 0, this.size.height);
@@ -217,7 +217,6 @@ JSClass("UIHTMLTextRun", JSTextRun, {
217
217
  updateSharedElementForSizing: function(){
218
218
  if (sharedElementForSizing === null){
219
219
  sharedElementForSizing = this.element.ownerDocument.createElement("span");
220
- sharedElementForSizing.appendChild(sharedElementForSizing.ownerDocument.createTextNode(""));
221
220
  sharedElementForSizing.style.visibility = "hidden";
222
221
  sharedElementForSizing.style.position = "absolute";
223
222
  sharedElementForSizing.style.zIndex = -100;
@@ -225,8 +224,12 @@ JSClass("UIHTMLTextRun", JSTextRun, {
225
224
  sharedElementForSizing.style.whiteSpace = "pre";
226
225
  sharedElementForSizing.ownerDocument.body.appendChild(sharedElementForSizing);
227
226
  }
227
+ if (sharedTextNodeForSizing === null){
228
+ sharedTextNodeForSizing = sharedElementForSizing.ownerDocument.createTextNode("");
229
+ sharedElementForSizing.appendChild(sharedTextNodeForSizing);
230
+ }
228
231
  sharedElementForSizing.style.font = this.element.style.font;
229
- sharedElementForSizing.firstChild.nodeValue = this.textNode.nodeValue;
232
+ sharedTextNodeForSizing.nodeValue = this.textNode.nodeValue;
230
233
  },
231
234
 
232
235
  _pickCorrectClientRectFromRects: function(rects){
@@ -288,5 +291,6 @@ JSClass("UIHTMLTextRun", JSTextRun, {
288
291
  });
289
292
 
290
293
  var sharedElementForSizing = null;
294
+ var sharedTextNodeForSizing = null;
291
295
 
292
296
  })();
@@ -143,6 +143,7 @@ JSClass("UIMenu", JSObject, {
143
143
  for (var i = index + 1, l = this._items.length; i < l; ++i){
144
144
  this._items[i].index = i;
145
145
  }
146
+ this._styler.invalidateMenuPresentation(this);
146
147
  },
147
148
 
148
149
  // MARK: - Removing Items
@@ -168,11 +169,15 @@ JSClass("UIMenu", JSObject, {
168
169
  if (item.tag in this._itemsByTag){
169
170
  delete this._itemsByTag[item.tag];
170
171
  }
172
+ if (item === this._highlightedItem){
173
+ this._highlightedItem = null;
174
+ }
171
175
  item.menu = null;
172
176
  this._items.splice(index, 1);
173
177
  for (var i = index, l = this._items.length; i < l; ++i){
174
178
  this._items[i].index = i;
175
179
  }
180
+ this._styler.invalidateMenuPresentation(this);
176
181
  },
177
182
 
178
183
  removeAllItems: function(){
@@ -186,6 +191,8 @@ JSClass("UIMenu", JSObject, {
186
191
  }
187
192
  this._itemsByTag = {};
188
193
  this._items = [];
194
+ this._highlightedItem = null;
195
+ this._styler.invalidateMenuPresentation(this);
189
196
  },
190
197
 
191
198
  // MARK: - Supermenu
@@ -433,6 +440,9 @@ JSClass("UIMenuStyler", JSObject, {
433
440
  dismissMenu: function(menu, animated, completion, target){
434
441
  },
435
442
 
443
+ invalidateMenuPresentation: function(menu){
444
+ },
445
+
436
446
  getItemTitleOffset: function(menu){
437
447
  return JSPoint.Zero;
438
448
  },
@@ -844,6 +854,51 @@ JSClass("UIMenuWindowStyler", UIMenuStyler, {
844
854
  }
845
855
  },
846
856
 
857
+ invalidateMenuPresentation: function(menu){
858
+ var window = menu.stylerProperties.window || null;
859
+ if (window !== null && window.screen !== null){
860
+ menu.updateEnabled();
861
+ window.update();
862
+
863
+ var screenMetrics = this.metricsForScreen(window.screen);
864
+ var size = JSSize(window.frame.size);
865
+
866
+ // Ensure we're at least the minimum width
867
+ // (although max width will take precedence)
868
+ if (size.width < menu._minimumWidth){
869
+ size.width = menu._minimumWidth;
870
+ }
871
+
872
+ // Limit width to the max screen width
873
+ if (size.width > screenMetrics.maximumWidth){
874
+ size.width = screenMetrics.maximumWidth;
875
+ }
876
+
877
+ // Set our origin so the origin of the target item matches the given location
878
+ var origin = JSPoint(window.frame.origin);
879
+
880
+ // Adjust our x position if we've overflowed
881
+ var over = origin.x + size.width - screenMetrics.safeFrame.origin.x - screenMetrics.safeFrame.size.width;
882
+ if (over > 0){
883
+ origin.x -= over;
884
+ }
885
+ if (origin.x < screenMetrics.safeFrame.origin.x){
886
+ origin.x = screenMetrics.safeFrame.origin.x;
887
+ }
888
+
889
+ var offset = JSPoint.Zero;
890
+
891
+ // If we extend beyond the bottom, adjust our height
892
+ over = origin.y + size.height - screenMetrics.safeFrame.origin.y - screenMetrics.safeFrame.size.height;
893
+ if (over > 0){
894
+ size.height -= over;
895
+ }
896
+
897
+ window.frame = JSRect(origin, size);
898
+ window.layoutIfNeeded();
899
+ }
900
+ },
901
+
847
902
  metricsForScreen: function(screen){
848
903
  var safeFrame = screen.availableFrame.rectWithInsets(4, 7);
849
904
  if (screen.traitCollection.horizontalSizeClass === UIUserInterface.SizeClass.compact){
@@ -132,16 +132,26 @@ JSClass("UIMenuWindow", UIWindow, {
132
132
  var itemView;
133
133
  var menuSize = JSSize.Zero;
134
134
  var i, l;
135
+ this._itemIndexesByItemViewId = {};
136
+ this._itemViewIndexesByItemId = {};
135
137
  // TODO: optimize by only drawing those views that fill the screen
136
138
  // We don't need to know the true height because we aren't showing a
137
139
  // scroll bar, only indicators that there is more.
138
140
  // Although, a UI that uses very long menus is poorly designed, so this
139
141
  // is a low priority
142
+ var itemViewIndex = 0;
140
143
  for (i = 0, l = this._menu.items.length; i < l; ++i){
141
144
  item = this._menu.items[i];
142
145
  if (!item.hidden){
143
- this._itemViewIndexesByItemId[item.objectID] = this.menuView.itemViews.length;
144
- itemView = this.menuView.addViewForItem(item);
146
+ this._itemViewIndexesByItemId[item.objectID] = itemViewIndex;
147
+ if (i < this.menuView.itemViews.length){
148
+ itemView = this.menuView.itemViews[i];
149
+ if (itemView instanceof UIMenuItemView){
150
+ itemView.setItem(item);
151
+ }
152
+ }else{
153
+ itemView = this.menuView.addViewForItem(item);
154
+ }
145
155
  itemView.sizeToFit();
146
156
  if (!item.alternate){
147
157
  menuSize.height += itemView.frame.size.height;
@@ -150,8 +160,14 @@ JSClass("UIMenuWindow", UIWindow, {
150
160
  menuSize.width = itemView.frame.size.width;
151
161
  }
152
162
  this._itemIndexesByItemViewId[itemView.objectID] = i;
163
+ ++itemViewIndex;
153
164
  }
154
165
  }
166
+ for (var j = this.menuView.itemViews.length - 1; j >= itemViewIndex; --j){
167
+ itemView = this.menuView.itemViews[j];
168
+ itemView.removeFromSuperview();
169
+ this.menuView.itemViews.pop();
170
+ }
155
171
  this.menuView.bounds = JSRect(JSPoint.Zero, menuSize);
156
172
  this.menuView.layoutIfNeeded();
157
173
  this.layoutIfNeeded();
@@ -119,6 +119,10 @@ JSClass("UIPopupWindow", UIWindow, {
119
119
  if (animated === undefined){
120
120
  animated = true;
121
121
  }
122
+ if (view.window === null || view.window.screen === null){
123
+ JSNotificationCenter.shared.post("UIWindowWillClose", this);
124
+ return;
125
+ }
122
126
  var sourceBounds = view.bounds;
123
127
  if (view.sourceRectForPopupWindow){
124
128
  sourceBounds = view.sourceRectForPopupWindow(this);
@@ -408,6 +412,10 @@ JSClass("UIPopupWindow", UIWindow, {
408
412
  if (animated === undefined){
409
413
  animated = true;
410
414
  }
415
+ if (view.window === null || view.window.screen === null){
416
+ JSNotificationCenter.shared.post("UIWindowWillClose", this);
417
+ return;
418
+ }
411
419
  var sourceFrame = view.convertRectToScreen(view.bounds);
412
420
  var safeFrame = view.window.screen.availableFrame.rectWithInsets(20);
413
421
 
@@ -860,6 +860,9 @@ JSClass("UIWindowServer", JSObject, {
860
860
  _windowResizeWidthOutside: 4,
861
861
 
862
862
  windowResizeHitTest: function(window, location){
863
+ if (location === null){
864
+ return UIWindowServer.ResizeOperation.none;
865
+ }
863
866
  if (!window._canResizeWidth && !window._canResizeHeight){
864
867
  return UIWindowServer.ResizeOperation.none;
865
868
  }
@@ -1,6 +1,6 @@
1
1
  JSBundleType: framework
2
2
  JSBundleIdentifier: io.breakside.JSKit.UIKitTesting
3
- JSBundleVersion: 2026.1.0
3
+ JSBundleVersion: 2026.2.1
4
4
  JSDevelopmentLanguage: en
5
5
  JSCopyright: Copyright © 2020 Breakside Inc.
6
6
  JSLicenseNotice: |
@@ -252,6 +252,9 @@ HTMLAppBootstrapper.prototype = {
252
252
  script.type = 'text/javascript';
253
253
  script.async = async;
254
254
  script.addEventListener('load', function HTMLAppBootstrapper_scriptLoad(e){
255
+ if (!bootstrapper.loadingScripts[src]){
256
+ return;
257
+ }
255
258
  if (bootstrapper.loadingScripts[src].compileError !== null){
256
259
  errorCallback(bootstrapper.loadingScripts[src].compileError);
257
260
  delete bootstrapper.loadingScripts[src];
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "node": ">=10.10.0"
13
13
  },
14
14
  "name": "@breakside/jskit",
15
- "version": "2026.1.0",
15
+ "version": "2026.2.1",
16
16
  "license": "SEE LICENSE IN LICENSE.txt",
17
17
  "files": [
18
18
  "*"