@datalayer/core 0.0.3 → 0.0.4

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 (330) hide show
  1. package/README.md +114 -3
  2. package/lib/App.css +2 -2
  3. package/lib/App.d.ts +1 -1
  4. package/lib/App.js +9 -9
  5. package/lib/__tests__/index.test.js +5 -5
  6. package/lib/api/DatalayerApi.d.ts +1 -1
  7. package/lib/api/DatalayerApi.js +3 -3
  8. package/lib/api/index.d.ts +3 -3
  9. package/lib/api/index.js +3 -3
  10. package/lib/api/runtimes/actions.js +22 -23
  11. package/lib/api/runtimes/settings.js +3 -3
  12. package/lib/api/runtimes/snapshots.d.ts +1 -1
  13. package/lib/api/runtimes/snapshots.js +8 -8
  14. package/lib/api/runtimes/utils.js +1 -4
  15. package/lib/collaboration/DatalayerCollaboration.d.ts +9 -0
  16. package/lib/collaboration/DatalayerCollaboration.js +28 -0
  17. package/lib/collaboration/DatalayerCollaborationProvider.d.ts +54 -0
  18. package/lib/collaboration/DatalayerCollaborationProvider.js +162 -0
  19. package/lib/collaboration/index.d.ts +2 -0
  20. package/lib/collaboration/index.js +6 -0
  21. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  22. package/lib/components/avatars/BoringAvatar.js +2 -2
  23. package/lib/components/avatars/UserProfileAvatar.js +2 -9
  24. package/lib/components/banners/NoAutomationBanner.js +4 -4
  25. package/lib/components/buttons/DownloadCSVButton.js +1 -1
  26. package/lib/components/buttons/UploadButton.js +1 -1
  27. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  28. package/lib/components/checkout/StripeCheckout.js +6 -6
  29. package/lib/components/confetti/ConfettiSuccess.js +1 -1
  30. package/lib/components/context/OrganizationSelect.js +5 -5
  31. package/lib/components/context/SpaceSelect.js +7 -7
  32. package/lib/components/display/AvatarSkeleton.js +1 -1
  33. package/lib/components/display/CenteredSpinner.js +4 -4
  34. package/lib/components/display/CodePreview.js +4 -4
  35. package/lib/components/display/DatalayerBox.js +13 -14
  36. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  37. package/lib/components/display/HorizontalCenter.js +1 -1
  38. package/lib/components/display/JupyterDialog.js +17 -15
  39. package/lib/components/display/NavLink.d.ts +4 -2
  40. package/lib/components/display/NavLink.js +6 -4
  41. package/lib/components/display/NotebookSkeleton.js +2 -2
  42. package/lib/components/display/Placeholder.js +1 -1
  43. package/lib/components/display/ToTopBranded.js +1 -1
  44. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  45. package/lib/components/echarts/EChartsReact.js +1 -1
  46. package/lib/components/flashes/FlashClosable.js +11 -11
  47. package/lib/components/flashes/FlashDisclaimer.js +2 -3
  48. package/lib/components/flashes/FlashGuest.js +3 -4
  49. package/lib/components/flashes/FlashSurveys.js +3 -4
  50. package/lib/components/flashes/FlashUnauthorized.js +2 -2
  51. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  52. package/lib/components/flashes/surveys/Survey2025_1.js +62 -85
  53. package/lib/components/iam/ExternalTokenSilentLogin.js +6 -4
  54. package/lib/components/icons/ArtifactIcon.d.ts +2 -2
  55. package/lib/components/icons/ArtifactIcon.js +39 -39
  56. package/lib/components/labels/VisibilityLabel.js +2 -5
  57. package/lib/components/landings/StepBlock.d.ts +1 -1
  58. package/lib/components/landings/StepBlock.js +1 -1
  59. package/lib/components/navbar/NavigationVisbilityObserver.js +2 -2
  60. package/lib/components/navbar/SubdomainNavBar.js +45 -23
  61. package/lib/components/navbar/SubdomainNavBar.module.css +33 -14
  62. package/lib/components/nbgrader/NbGradesDetails.d.ts +1 -1
  63. package/lib/components/nbgrader/NbGradesDetails.js +5 -8
  64. package/lib/components/notebooks/JupyterNotebook.js +5 -5
  65. package/lib/components/notebooks/JupyterNotebookToolbar.js +3 -3
  66. package/lib/components/primer/Helper.d.ts +1 -1
  67. package/lib/components/primer/Helper.js +5 -3
  68. package/lib/components/primer/Portals.d.ts +1 -1
  69. package/lib/components/primer/Portals.js +2 -2
  70. package/lib/components/primer/Styles.js +1 -1
  71. package/lib/components/progress/ConsumptionBar.js +2 -2
  72. package/lib/components/progress/CreditsIndicator.d.ts +1 -1
  73. package/lib/components/progress/CreditsIndicator.js +4 -7
  74. package/lib/components/progress/ProgressRing.js +2 -2
  75. package/lib/components/runtimes/RuntimeCellVariables.js +9 -9
  76. package/lib/components/runtimes/RuntimeCellVariablesDialog.js +3 -3
  77. package/lib/components/runtimes/RuntimeLauncherDialog.js +30 -34
  78. package/lib/components/runtimes/RuntimePickerBase.js +42 -31
  79. package/lib/components/runtimes/RuntimePickerCell.js +9 -12
  80. package/lib/components/runtimes/RuntimePickerNotebook.js +44 -44
  81. package/lib/components/runtimes/RuntimeReservationControl.js +10 -15
  82. package/lib/components/runtimes/RuntimeSimplePicker.js +9 -12
  83. package/lib/components/runtimes/RuntimeUtils.js +22 -12
  84. package/lib/components/runtimes/RuntimeVariables.js +7 -7
  85. package/lib/components/screenshot/ScreenCapture.js +9 -13
  86. package/lib/components/screenshot/ScreenCaptureButton.d.ts +1 -1
  87. package/lib/components/screenshot/ScreenCaptureButton.js +14 -8
  88. package/lib/components/snapshots/RuntimeSnapshotMenu.js +19 -17
  89. package/lib/components/snippets/SnippetDialog.js +5 -5
  90. package/lib/components/storage/ContentsBrowser.js +63 -56
  91. package/lib/components/storage/ContentsItems.js +10 -8
  92. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  93. package/lib/components/students/StudentItemStatus.js +35 -16
  94. package/lib/components/subnav/SubNav.d.ts +1 -1
  95. package/lib/components/subnav/SubNav.js +30 -15
  96. package/lib/components/subnav/SubNav.module.css +55 -21
  97. package/lib/components/tables/DataTable.js +1 -4
  98. package/lib/components/text-reveal/TextRevealAnimation.js +7 -2
  99. package/lib/components/text-reveal/TextRevealAnimation.module.css +4 -2
  100. package/lib/components/tokens/SpaceVariantToken.d.ts +1 -1
  101. package/lib/components/tokens/SpaceVariantToken.js +5 -5
  102. package/lib/components/toolbars/AssignmentEditorToolbar.js +1 -3
  103. package/lib/components/users/PeerIndicator.d.ts +1 -1
  104. package/lib/components/users/PeerIndicator.js +5 -5
  105. package/lib/config/Configuration.d.ts +48 -0
  106. package/lib/config/Configuration.js +42 -0
  107. package/lib/config/integrations/Loom.js +3 -3
  108. package/lib/examples/CellExample.d.ts +2 -2
  109. package/lib/examples/CellExample.js +34 -3
  110. package/lib/examples/DatalayerNotebookExample.d.ts +16 -0
  111. package/lib/examples/DatalayerNotebookExample.js +75 -0
  112. package/lib/examples/NativeNavigationExample.d.ts +8 -0
  113. package/lib/examples/NativeNavigationExample.js +97 -0
  114. package/lib/examples/NotebookExample.d.ts +1 -3
  115. package/lib/examples/NotebookExample.js +9 -7
  116. package/lib/examples/NotebookMutationsKernel.d.ts +2 -0
  117. package/lib/examples/NotebookMutationsKernel.js +115 -0
  118. package/lib/examples/NotebookMutationsServiceManager.d.ts +2 -0
  119. package/lib/examples/NotebookMutationsServiceManager.js +107 -0
  120. package/lib/examples/ReactRouterExample.d.ts +6 -0
  121. package/lib/examples/ReactRouterExample.js +175 -0
  122. package/lib/examples/example-selector.d.ts +22 -0
  123. package/lib/examples/example-selector.js +45 -0
  124. package/lib/examples/index.d.ts +2 -0
  125. package/lib/examples/index.js +6 -0
  126. package/lib/examples/main.js +153 -0
  127. package/lib/examples/notebooks/IPyWidgetsExample.ipynb.json +101 -0
  128. package/lib/examples/notebooks/IPyWidgetsExampleWithState.ipynb.json +112 -0
  129. package/lib/examples/{NotebookExample1.ipynb.json → notebooks/Lite.ipynb.json} +45 -53
  130. package/lib/examples/notebooks/Matplotlib.ipynb.json +137 -0
  131. package/lib/examples/notebooks/NotebookExample1.ipynb.json +126 -0
  132. package/lib/examples/notebooks/NotebookExample2.ipynb.json +48 -0
  133. package/lib/examples/notebooks/NotebookOutputs.ipynb.json +49 -0
  134. package/lib/examples/notebooks/NotebookToCExample.ipynb.json +102 -0
  135. package/lib/examples/notebooks/OutputIPyWidgetsExample.d.ts +145 -0
  136. package/lib/examples/notebooks/OutputIPyWidgetsExample.js +153 -0
  137. package/lib/examples/notebooks/PyGWalker.ipynb.json +55 -0
  138. package/lib/hooks/assets/OutputshotPlaceholders.d.ts +10 -10
  139. package/lib/hooks/assets/OutputshotPlaceholders.js +10 -10
  140. package/lib/hooks/index.d.ts +29 -28
  141. package/lib/hooks/index.js +29 -28
  142. package/lib/hooks/layouts/LayoutBackdrop.js +3 -6
  143. package/lib/hooks/layouts/LayoutScreenshot.css +1 -1
  144. package/lib/hooks/layouts/LayoutScreenshot.js +6 -6
  145. package/lib/hooks/useAIAgents.d.ts +1 -1
  146. package/lib/hooks/useAIAgents.js +6 -6
  147. package/lib/hooks/useAuthorization.js +4 -4
  148. package/lib/hooks/useBackdrop.js +7 -7
  149. package/lib/hooks/useBackdropJupyterLab.d.ts +1 -1
  150. package/lib/hooks/useBackdropJupyterLab.js +4 -4
  151. package/lib/hooks/useCache.d.ts +6 -2
  152. package/lib/hooks/useCache.js +233 -179
  153. package/lib/hooks/useCellOutputshot.js +3 -6
  154. package/lib/hooks/useContainsFocus.js +2 -1
  155. package/lib/hooks/useDatalayer.js +5 -3
  156. package/lib/hooks/useError.d.ts +1 -1
  157. package/lib/hooks/useError.js +2 -2
  158. package/lib/hooks/useExternalScript.js +4 -4
  159. package/lib/hooks/useFocusTrap.js +2 -1
  160. package/lib/hooks/useIAM.js +4 -5
  161. package/lib/hooks/useId.js +3 -3
  162. package/lib/hooks/useJupyterLabTheme.js +3 -1
  163. package/lib/hooks/useLocation.d.ts +22 -0
  164. package/lib/hooks/useLocation.js +149 -0
  165. package/lib/hooks/useLocationHandles.d.ts +2 -2
  166. package/lib/hooks/useLocationHandles.js +6 -4
  167. package/lib/hooks/useNavigate.d.ts +5 -1
  168. package/lib/hooks/useNavigate.js +62 -7
  169. package/lib/hooks/useNotebookAIAgent.js +3 -1
  170. package/lib/hooks/useParams.d.ts +5 -0
  171. package/lib/hooks/useParams.js +152 -0
  172. package/lib/hooks/useRuntimes.js +2 -2
  173. package/lib/hooks/useScreenshot.js +5 -5
  174. package/lib/hooks/useToast.js +15 -13
  175. package/lib/hooks/useUpload.js +9 -9
  176. package/lib/hooks/useUser.js +1 -1
  177. package/lib/index.css +1 -1
  178. package/lib/index.d.ts +6 -3
  179. package/lib/index.js +7 -3
  180. package/lib/mocks/components/FlashMock.js +4 -4
  181. package/lib/mocks/hooks/rests/rests.js +15 -18
  182. package/lib/mocks/hooks/useDatalayerMock.d.ts +2 -2
  183. package/lib/mocks/hooks/useDatalayerMock.js +7 -7
  184. package/lib/mocks/models/CodeBlockMock.js +1 -1
  185. package/lib/mocks/models/CodelineMock.js +1 -1
  186. package/lib/mocks/models/CourseMock.d.ts +1 -1
  187. package/lib/mocks/models/CourseMock.js +10 -10
  188. package/lib/mocks/models/InviteMock.d.ts +1 -1
  189. package/lib/mocks/models/InviteMock.js +21 -6
  190. package/lib/mocks/models/JupyterLabUserMock.js +2 -2
  191. package/lib/mocks/models/OrganisationMock.d.ts +1 -1
  192. package/lib/mocks/models/OrganisationMock.js +11 -7
  193. package/lib/mocks/models/SchoolMock.d.ts +1 -1
  194. package/lib/mocks/models/SchoolMock.js +6 -6
  195. package/lib/mocks/models/SpaceMock.d.ts +1 -1
  196. package/lib/mocks/models/SpaceMock.js +9 -9
  197. package/lib/mocks/models/TeamMock.d.ts +1 -1
  198. package/lib/mocks/models/TeamMock.js +6 -6
  199. package/lib/mocks/models/UserMock.d.ts +1 -1
  200. package/lib/mocks/models/UserMock.js +4 -6
  201. package/lib/mocks/views/ActionMenuMock.js +1 -1
  202. package/lib/mocks/views/ChartMock.js +3 -3
  203. package/lib/mocks/views/ChartMockOptions.js +24 -24
  204. package/lib/mocks/views/DashboardMock.js +74 -74
  205. package/lib/mocks/views/FormMock.js +1 -1
  206. package/lib/mocks/views/TableMock.js +1 -1
  207. package/lib/models/Account.d.ts +2 -2
  208. package/lib/models/Assignment.d.ts +2 -2
  209. package/lib/models/Cell.d.ts +1 -1
  210. package/lib/models/CodeBlock.d.ts +1 -1
  211. package/lib/models/CodefeedBlocks.d.ts +2 -2
  212. package/lib/models/Contact.d.ts +1 -1
  213. package/lib/models/Contact.js +14 -14
  214. package/lib/models/ContactIAMProvider.js +2 -2
  215. package/lib/models/Course.d.ts +7 -7
  216. package/lib/models/Dataset.d.ts +1 -1
  217. package/lib/models/Dean.d.ts +1 -1
  218. package/lib/models/Document.d.ts +1 -1
  219. package/lib/models/Environment.d.ts +2 -2
  220. package/lib/models/Exercise.d.ts +1 -1
  221. package/lib/models/IAMProviderLinked.js +1 -1
  222. package/lib/models/Instructor.d.ts +1 -1
  223. package/lib/models/Invite.d.ts +2 -2
  224. package/lib/models/Invite.js +1 -1
  225. package/lib/models/Item.d.ts +5 -5
  226. package/lib/models/LandingRoles.js +18 -18
  227. package/lib/models/Lesson.d.ts +1 -1
  228. package/lib/models/Member.d.ts +1 -1
  229. package/lib/models/Notebook.d.ts +1 -1
  230. package/lib/models/Organization.d.ts +4 -4
  231. package/lib/models/Organization.js +2 -2
  232. package/lib/models/OrganizationMember.d.ts +2 -2
  233. package/lib/models/Page.js +4 -2
  234. package/lib/models/PageTag.d.ts +1 -1
  235. package/lib/models/PageTag.js +56 -9
  236. package/lib/models/Profile.d.ts +1 -1
  237. package/lib/models/RolesOrganization.d.ts +1 -1
  238. package/lib/models/RolesOrganization.js +4 -12
  239. package/lib/models/RolesPlatform.d.ts +1 -1
  240. package/lib/models/RolesPlatform.js +12 -34
  241. package/lib/models/RolesTeam.d.ts +1 -1
  242. package/lib/models/RolesTeam.js +3 -10
  243. package/lib/models/Runtime.js +4 -4
  244. package/lib/models/RuntimeSnapshot.js +1 -1
  245. package/lib/models/School.d.ts +4 -4
  246. package/lib/models/Space.d.ts +5 -5
  247. package/lib/models/Space.js +3 -3
  248. package/lib/models/SpaceItem.d.ts +8 -8
  249. package/lib/models/SpaceMember.d.ts +2 -2
  250. package/lib/models/Student.d.ts +2 -2
  251. package/lib/models/StudentItem.d.ts +3 -3
  252. package/lib/models/Team.d.ts +3 -3
  253. package/lib/models/Team.js +2 -2
  254. package/lib/models/TeamMember.d.ts +2 -2
  255. package/lib/models/URN.js +1 -1
  256. package/lib/models/User.d.ts +2 -2
  257. package/lib/models/User.js +5 -3
  258. package/lib/models/UserOnboarding.d.ts +1 -1
  259. package/lib/models/UserOnboarding.js +7 -7
  260. package/lib/models/UserSettings.js +2 -2
  261. package/lib/models/index.d.ts +2 -2
  262. package/lib/models/index.js +2 -2
  263. package/lib/navigation/adapters/native.d.ts +11 -0
  264. package/lib/navigation/adapters/native.js +48 -0
  265. package/lib/navigation/adapters/nextjs.d.ts +9 -0
  266. package/lib/navigation/adapters/nextjs.js +35 -0
  267. package/lib/navigation/adapters/react-router.d.ts +4 -0
  268. package/lib/navigation/adapters/react-router.js +12 -0
  269. package/lib/navigation/components.d.ts +20 -0
  270. package/lib/navigation/components.js +36 -0
  271. package/lib/navigation/index.d.ts +4 -0
  272. package/lib/navigation/index.js +12 -0
  273. package/lib/routes/index.d.ts +1 -1
  274. package/lib/routes/index.js +1 -1
  275. package/lib/services/DatalayerServiceManager.d.ts +22 -0
  276. package/lib/services/DatalayerServiceManager.js +79 -0
  277. package/lib/services/index.d.ts +4 -0
  278. package/lib/services/index.js +7 -0
  279. package/lib/services/reconnectToRuntime.d.ts +32 -0
  280. package/lib/services/reconnectToRuntime.js +59 -0
  281. package/lib/state/State.d.ts +1 -1
  282. package/lib/state/State.js +1 -1
  283. package/lib/state/index.d.ts +1 -1
  284. package/lib/state/index.js +1 -1
  285. package/lib/state/storage/IAMStorage.js +14 -2
  286. package/lib/state/storage/index.d.ts +1 -1
  287. package/lib/state/storage/index.js +1 -1
  288. package/lib/state/substates/AIAgentState.js +4 -2
  289. package/lib/state/substates/CellState.js +6 -5
  290. package/lib/state/substates/CoreState.d.ts +1 -1
  291. package/lib/state/substates/CoreState.js +23 -15
  292. package/lib/state/substates/DatasourceState.js +1 -1
  293. package/lib/state/substates/IAMState.d.ts +4 -0
  294. package/lib/state/substates/IAMState.js +75 -56
  295. package/lib/state/substates/JupyterLabState.js +1 -1
  296. package/lib/state/substates/LayoutState.d.ts +2 -2
  297. package/lib/state/substates/LayoutState.js +41 -28
  298. package/lib/state/substates/OrganizationState.js +1 -1
  299. package/lib/state/substates/RuntimesState.js +6 -5
  300. package/lib/state/substates/SpaceState.js +1 -1
  301. package/lib/state/substates/SurveysState.js +4 -4
  302. package/lib/state/substates/TeamState.js +1 -1
  303. package/lib/test-setup.js +25 -3
  304. package/lib/theme/DatalayerTheme.js +1 -1
  305. package/lib/theme/DatalayerThemeProvider.js +17 -14
  306. package/lib/theme/Palette.js +1 -1
  307. package/lib/utils/Avatar.js +2 -2
  308. package/lib/utils/Browser.js +6 -6
  309. package/lib/utils/Cells.d.ts +1 -1
  310. package/lib/utils/Cookie.js +1 -1
  311. package/lib/utils/Date.js +2 -2
  312. package/lib/utils/Download.js +5 -3
  313. package/lib/utils/DownloadFile.js +4 -2
  314. package/lib/utils/Env.js +2 -1
  315. package/lib/utils/Lazy.d.ts +1 -1
  316. package/lib/utils/Lazy.js +2 -2
  317. package/lib/utils/Name.js +10 -8
  318. package/lib/utils/Notebook.d.ts +1 -1
  319. package/lib/utils/Notebook.js +3 -3
  320. package/lib/utils/Number.js +13 -9
  321. package/lib/utils/Plots.js +4 -4
  322. package/lib/utils/Screenshot.js +1 -1
  323. package/lib/utils/Sleep.js +1 -1
  324. package/lib/utils/Snapshot.js +2 -2
  325. package/lib/utils/String.js +2 -2
  326. package/lib/utils/Uri.js +1 -1
  327. package/lib/utils/WithSuspense.js +3 -6
  328. package/package.json +41 -5
  329. package/lib/__tests__/App.test.js +0 -17
  330. /package/lib/{__tests__/App.test.d.ts → examples/main.d.ts} +0 -0
@@ -5,8 +5,8 @@
5
5
  import { Poll } from '@lumino/polling';
6
6
  import { useStore } from 'zustand';
7
7
  import { createStore } from 'zustand/vanilla';
8
- import { ANONYMOUS_USER_TOKEN, ANONYMOUS_USER, asUser, IAMProvidersSpecs } from '../../models';
9
- import { getStoredToken, getStoredUser, loadRefreshTokenFromCookie, storeToken, storeUser } from '../storage';
8
+ import { ANONYMOUS_USER_TOKEN, ANONYMOUS_USER, asUser, IAMProvidersSpecs, } from '../../models';
9
+ import { getStoredToken, getStoredUser, loadRefreshTokenFromCookie, storeToken, storeUser, } from '../storage';
10
10
  import { requestDatalayerAPI } from '../../api';
11
11
  import { getCookie, setCookie, deleteCookie } from '../../utils';
12
12
  import { coreStore } from './CoreState';
@@ -24,16 +24,19 @@ export const iamStore = createStore((set, get) => {
24
24
  iamRunUrl: coreStore.getState().configuration?.iamRunUrl,
25
25
  iamProvidersAuthorizationURL: {},
26
26
  version: '',
27
+ isLoginInProgress: false,
27
28
  addIAMProviderAuthorizationURL: (provider, authorizationURL) => {
28
29
  set(state => ({
29
30
  iamProvidersAuthorizationURL: {
30
31
  ...state.iamProvidersAuthorizationURL,
31
32
  [provider]: authorizationURL,
32
- }
33
+ },
33
34
  }));
34
35
  },
35
36
  login: async (token) => {
36
37
  const { refreshUserByToken, iamRunUrl, logout } = get();
38
+ // Set flag to prevent interference from automatic token refresh
39
+ set({ isLoginInProgress: true });
37
40
  try {
38
41
  const resp = await requestDatalayerAPI({
39
42
  url: `${iamRunUrl}/api/iam/v1/login`,
@@ -41,7 +44,7 @@ export const iamStore = createStore((set, get) => {
41
44
  body: { token },
42
45
  });
43
46
  if (resp.success && resp.token) {
44
- refreshUserByToken(resp.token);
47
+ await refreshUserByToken(resp.token);
45
48
  }
46
49
  else {
47
50
  throw new Error('Invalid Token.');
@@ -49,12 +52,16 @@ export const iamStore = createStore((set, get) => {
49
52
  }
50
53
  catch (error) {
51
54
  console.debug('Failed to login.', error);
52
- if (error.name === 'RunResponseError' && error.response.status === 401) {
55
+ if (error.name === 'RunResponseError' &&
56
+ error.response.status === 401) {
53
57
  console.debug('Received 401 error - Logging out.');
54
58
  logout();
55
59
  }
56
60
  throw error;
57
61
  }
62
+ finally {
63
+ set({ isLoginInProgress: false });
64
+ }
58
65
  },
59
66
  logout: () => {
60
67
  storeUser();
@@ -97,7 +104,7 @@ export const iamStore = createStore((set, get) => {
97
104
  user: {
98
105
  ...state.user,
99
106
  ...user,
100
- }
107
+ },
101
108
  };
102
109
  /*
103
110
  if (state.user?.email && !updatedState.user.email) {
@@ -115,9 +122,9 @@ export const iamStore = createStore((set, get) => {
115
122
  token,
116
123
  headers: externalToken
117
124
  ? {
118
- 'X-External-Token': externalToken
125
+ 'X-External-Token': externalToken,
119
126
  }
120
- : undefined
127
+ : undefined,
121
128
  });
122
129
  const { credits, reservations: creditsReservations = [] } = creditsRaw;
123
130
  let available = credits.quota !== null
@@ -126,7 +133,7 @@ export const iamStore = createStore((set, get) => {
126
133
  available -= creditsReservations.reduce((consumed, reservation) => consumed + reservation.credits, 0);
127
134
  set({
128
135
  credits: { ...credits, available: Math.max(0, available) },
129
- creditsReservations: creditsReservations
136
+ creditsReservations: creditsReservations,
130
137
  });
131
138
  }
132
139
  catch (error) {
@@ -162,7 +169,7 @@ export const iamStore = createStore((set, get) => {
162
169
  }
163
170
  },
164
171
  refreshUserByToken: async (token) => {
165
- const { iamRunUrl, logout } = get();
172
+ const { iamRunUrl, logout, isLoginInProgress } = get();
166
173
  try {
167
174
  const data = await requestDatalayerAPI({
168
175
  url: `${iamRunUrl}/api/iam/v1/whoami`,
@@ -188,16 +195,21 @@ export const iamStore = createStore((set, get) => {
188
195
  else {
189
196
  console.debug('Failed to fetch user identity.', error);
190
197
  }
191
- logout();
198
+ // Only logout if we're not in the middle of a login attempt
199
+ if (!isLoginInProgress) {
200
+ logout();
201
+ }
192
202
  }
193
203
  },
194
- setExternalToken: (externalToken) => set((state) => { return { externalToken }; }),
204
+ setExternalToken: (externalToken) => set((state) => {
205
+ return { externalToken };
206
+ }),
195
207
  setLogin: (user, token) => set((state) => {
196
208
  storeUser(user);
197
209
  storeToken(token);
198
210
  return {
199
211
  user,
200
- token
212
+ token,
201
213
  };
202
214
  }),
203
215
  setVersion: version => {
@@ -218,52 +230,57 @@ const creditsPoll = new Poll({
218
230
  frequency: {
219
231
  interval: 60 * 1000,
220
232
  backoff: true,
221
- max: 600 * 1000
233
+ max: 600 * 1000,
222
234
  },
223
- standby: () => (iamStore.getState().user?.id ? 'when-hidden' : true)
235
+ standby: () => (iamStore.getState().user?.id ? 'when-hidden' : true),
224
236
  });
225
237
  // Initialize the IAM store with the stored token if it is valid.
226
- iamStore
227
- .getState()
228
- .refreshUserByTokenStored()
229
- .catch(reason => {
230
- console.error('Failed to refresh to validate the stored token.', reason);
231
- })
232
- .finally(() => {
233
- const { externalToken, iamRunUrl, checkIAMToken, token } = iamStore.getState();
234
- // If the stored token is invalid and an external token exists, try authenticating with it.
235
- if (!token && externalToken) {
236
- console.debug('Can not login with token - Trying with the external token.');
237
- requestDatalayerAPI({
238
- url: `${iamRunUrl}/api/iam/v1/login`,
239
- method: 'POST',
240
- body: { token: externalToken }
241
- })
242
- .then(response => {
243
- if (response.token) {
244
- checkIAMToken(response.token);
245
- }
246
- })
247
- .catch(reason => {
248
- console.debug('Can not login with token.', token, reason);
249
- });
250
- }
251
- if (token) {
252
- console.log('Logged in with token and external token.');
253
- }
254
- else {
255
- console.debug('Failed to login with token and no external token available.');
256
- }
257
- // Start the credits poll in any case after trying to validate the user token.
258
- creditsPoll.start();
259
- // Force a refresh when the user comeback to the application tab
260
- // Useful for checkout platform redirecting to another tab to add credits.
261
- document.addEventListener('visibilitychange', () => {
262
- if (!document.hidden && iamStore.getState().user?.id) {
263
- creditsPoll.refresh();
238
+ // Delay initialization slightly to allow apps to set up first
239
+ setTimeout(() => {
240
+ iamStore
241
+ .getState()
242
+ .refreshUserByTokenStored()
243
+ .catch(reason => {
244
+ console.error('Failed to refresh to validate the stored token.', reason);
245
+ })
246
+ .finally(() => {
247
+ const { externalToken, iamRunUrl, checkIAMToken, token } = iamStore.getState();
248
+ // If the stored token is invalid and an external token exists, try authenticating with it.
249
+ if (!token && externalToken) {
250
+ console.debug('Can not login with token - Trying with the external token.');
251
+ requestDatalayerAPI({
252
+ url: `${iamRunUrl}/api/iam/v1/login`,
253
+ method: 'POST',
254
+ body: { token: externalToken },
255
+ })
256
+ .then(response => {
257
+ if (response.token) {
258
+ checkIAMToken(response.token);
259
+ }
260
+ })
261
+ .catch(reason => {
262
+ console.debug('Can not login with token.', token, reason);
263
+ });
264
+ }
265
+ if (token) {
266
+ console.log('Logged in with token and external token.');
267
+ }
268
+ else {
269
+ console.debug('Failed to login with token and no external token available.');
270
+ }
271
+ // Start the credits poll in any case after trying to validate the user token.
272
+ creditsPoll.start();
273
+ // Force a refresh when the user comeback to the application tab
274
+ // Useful for checkout platform redirecting to another tab to add credits.
275
+ if (typeof document !== 'undefined') {
276
+ document.addEventListener('visibilitychange', () => {
277
+ if (!document.hidden && iamStore.getState().user?.id) {
278
+ creditsPoll.refresh();
279
+ }
280
+ });
264
281
  }
265
282
  });
266
- });
283
+ }, 100); // 100ms delay to allow app initialization
267
284
  // Connect the core store with the iam store.
268
285
  coreStore.subscribe((state, prevState) => {
269
286
  if (state.configuration?.iamRunUrl &&
@@ -273,14 +290,16 @@ coreStore.subscribe((state, prevState) => {
273
290
  iamStore.setState({ iamRunUrl });
274
291
  // Check the token is valid with the new server.
275
292
  if (iamStore.getState().externalToken) {
276
- iamStore.getState()
293
+ iamStore
294
+ .getState()
277
295
  .login(iamStore.getState().externalToken)
278
296
  .catch(reason => {
279
297
  console.error('Failed to refresh the user after updating the IAM RUN URL.', reason);
280
298
  });
281
299
  }
282
300
  else {
283
- iamStore.getState()
301
+ iamStore
302
+ .getState()
284
303
  .refreshUser()
285
304
  .catch(reason => {
286
305
  console.error('Failed to refresh the user after updating the IAM server URL.', reason);
@@ -9,7 +9,7 @@ export const jupyterLabStore = createStore((set, get) => ({
9
9
  setJupyterLabAdapter: (jupyterLabAdapter) => set((state) => ({ jupyterLabAdapter })),
10
10
  plugin: (id) => {
11
11
  return get().jupyterLabAdapter?.plugin(id);
12
- }
12
+ },
13
13
  }));
14
14
  export function useJupyterLabStore(selector) {
15
15
  return useStore(jupyterLabStore, selector);
@@ -1,5 +1,5 @@
1
- import { ReactPortal } from "react";
2
- import { IAnyOrganization, IAnySpace, IAnyTeam, ISpaceItem } from "../../models";
1
+ import { ReactPortal } from 'react';
2
+ import { IAnyOrganization, IAnySpace, IAnyTeam, ISpaceItem } from '../../models';
3
3
  export type BannerDisplayVariant = 'danger' | 'info' | 'success' | 'warning';
4
4
  export type LeftSidebarVariant = 'codefeed' | 'course' | 'empty' | 'guess-account' | 'guess-space' | 'guess-spaces' | 'organization' | 'organization-space' | 'organization-spaces' | 'organizations' | 'public' | 'unchanged' | 'user' | 'user-space' | 'user-spaces';
5
5
  export type BackdropDisplay = {
@@ -17,8 +17,12 @@ export const layoutStore = createStore((set, get) => ({
17
17
  screenCapture: undefined,
18
18
  space: undefined,
19
19
  team: undefined,
20
- hideBackdrop: () => set((state) => ({ backdrop: { open: false, message: undefined } })),
21
- hideScreenshot: () => set((state) => ({ screenshot: { open: false, message: undefined } })),
20
+ hideBackdrop: () => set((state) => ({
21
+ backdrop: { open: false, message: undefined },
22
+ })),
23
+ hideScreenshot: () => set((state) => ({
24
+ screenshot: { open: false, message: undefined },
25
+ })),
22
26
  setBootstrapped: (bootstrapped) => set((state) => ({ bootstrapped })),
23
27
  showBackdrop: (message) => set((state) => ({ backdrop: { open: true, message } })),
24
28
  showScreenshot: (message) => set((state) => ({ screenshot: { open: true, message } })),
@@ -27,46 +31,55 @@ export const layoutStore = createStore((set, get) => ({
27
31
  timestamp: new Date(),
28
32
  message: bannerDisplay.message,
29
33
  variant: bannerDisplay.variant,
30
- }
34
+ },
31
35
  })),
32
36
  setLeftPortal: (leftPortal) => set((state) => ({ leftPortal })),
33
37
  setRightPortal: (rightPortal) => set((state) => ({ rightPortal })),
34
- resetLeftPortal: () => set((state) => ({ leftPortal: state.leftPortal?.pinned ? state.leftPortal : undefined, })),
35
- resetRightPortal: () => set((state) => ({ rightPortal: state.rightPortal?.pinned ? state.rightPortal : undefined, })),
38
+ resetLeftPortal: () => set((state) => ({
39
+ leftPortal: state.leftPortal?.pinned ? state.leftPortal : undefined,
40
+ })),
41
+ resetRightPortal: () => set((state) => ({
42
+ rightPortal: state.rightPortal?.pinned ? state.rightPortal : undefined,
43
+ })),
36
44
  resetForcedLeftPortal: () => set((state) => ({ leftPortal: undefined })),
37
45
  resetForcedRightPortal: () => set((state) => ({ rightPortal: undefined })),
38
46
  setLeftSidebarVariant: (leftSidebarVariant) => set((state) => ({ leftSidebarVariant })),
39
47
  updateLayoutOrganization: (organization) => set((state) => {
40
- return ({
41
- organization: organization ? {
42
- ...state.organization,
43
- ...organization,
44
- }
45
- : undefined
46
- });
48
+ return {
49
+ organization: organization
50
+ ? {
51
+ ...state.organization,
52
+ ...organization,
53
+ }
54
+ : undefined,
55
+ };
47
56
  }),
48
57
  updateLayoutTeam: (team) => set((state) => {
49
- return ({
50
- team: team ? {
51
- ...state.team,
52
- ...team,
53
- }
54
- : undefined
55
- });
58
+ return {
59
+ team: team
60
+ ? {
61
+ ...state.team,
62
+ ...team,
63
+ }
64
+ : undefined,
65
+ };
56
66
  }),
57
67
  updateLayoutSpace: (space) => set((state) => {
58
- return ({
59
- space: space ? {
60
- ...state.space,
61
- ...space,
62
- }
63
- : undefined
64
- });
68
+ return {
69
+ space: space
70
+ ? {
71
+ ...state.space,
72
+ ...space,
73
+ }
74
+ : undefined,
75
+ };
65
76
  }),
66
77
  setItem: (item) => set((state) => ({ item })),
67
- triggerItemsRefresh: () => set((state) => ({ itemsRefreshCount: state.itemsRefreshCount + 1 })),
78
+ triggerItemsRefresh: () => set((state) => ({
79
+ itemsRefreshCount: state.itemsRefreshCount + 1,
80
+ })),
68
81
  setScreenCapture: (screenCapture) => set((state) => ({ screenCapture })),
69
- reset: () => set((state) => ({ bootstrapped: false, })),
82
+ reset: () => set((state) => ({ bootstrapped: false })),
70
83
  }));
71
84
  export function useLayoutStore(selector) {
72
85
  return useStore(layoutStore, selector);
@@ -7,7 +7,7 @@ import { useStore } from 'zustand';
7
7
  export const organizationStore = createStore((set, get) => ({
8
8
  organizations: [],
9
9
  updateOrganizations: (organizations) => set((state) => ({
10
- organizations
10
+ organizations,
11
11
  })),
12
12
  }));
13
13
  export function useOrganizationStore(selector) {
@@ -16,7 +16,7 @@ export const runtimesStore = createStore((set, get) => {
16
16
  return {
17
17
  configuration: {
18
18
  maxNotebookRuntimes: 5,
19
- maxCellRuntimes: 3
19
+ maxCellRuntimes: 3,
20
20
  },
21
21
  setConfiguration: (configuration) => {
22
22
  set(state => JSONExt.deepEqual(state.configuration, configuration)
@@ -127,7 +127,7 @@ export const runtimesStore = createStore((set, get) => {
127
127
  if (version && !get().version) {
128
128
  set(state => ({ version }));
129
129
  }
130
- }
130
+ },
131
131
  };
132
132
  });
133
133
  // Poll remote kernels
@@ -137,12 +137,12 @@ const kernelsPoll = new Poll({
137
137
  frequency: {
138
138
  interval: 61 * 1000,
139
139
  backoff: true,
140
- max: 300 * 1000
140
+ max: 300 * 1000,
141
141
  },
142
142
  name: '@datalayer/jupyter-kernels:KernelsManager#kernels',
143
143
  standby: () => iamStore.getState().token || runtimesStore.getState().runtimesRunUrl
144
144
  ? 'when-hidden'
145
- : true
145
+ : true,
146
146
  });
147
147
  // Force refresh at expiration date if next tick is after it.
148
148
  runtimesStore.subscribe((state, prevState) => {
@@ -160,7 +160,8 @@ runtimesStore.subscribe((state, prevState) => {
160
160
  });
161
161
  coreStore.subscribe((state, prevState) => {
162
162
  if (state.configuration.runtimesRunUrl &&
163
- state.configuration.runtimesRunUrl !== prevState.configuration.runtimesRunUrl) {
163
+ state.configuration.runtimesRunUrl !==
164
+ prevState.configuration.runtimesRunUrl) {
164
165
  const runtimesRunUrl = state.configuration.runtimesRunUrl;
165
166
  console.log(`Updating runtimesRunUrl with new value ${runtimesRunUrl}`);
166
167
  runtimesStore.setState({ runtimesRunUrl });
@@ -7,7 +7,7 @@ import { useStore } from 'zustand';
7
7
  export const spaceStore = createStore((set, get) => ({
8
8
  spaces: [],
9
9
  updateSpaces: (spaces) => set((state) => ({
10
- spaces
10
+ spaces,
11
11
  })),
12
12
  }));
13
13
  export function useSpaceStore(selector) {
@@ -5,7 +5,7 @@
5
5
  import { createStore } from 'zustand/vanilla';
6
6
  import { useStore } from 'zustand';
7
7
  import { requestDatalayerAPI } from '../../api';
8
- import { asSurvey } from '../../models';
8
+ import { asSurvey, } from '../../models';
9
9
  import { coreStore } from './CoreState';
10
10
  import { iamStore } from './IAMState';
11
11
  export const surveysStore = createStore((set, get) => ({
@@ -65,9 +65,9 @@ export const surveysStore = createStore((set, get) => ({
65
65
  set((state) => ({ surveys }));
66
66
  }
67
67
  else {
68
- set((state) => ({ surveys: new Map([
69
- [survey.name, survey]
70
- ]) }));
68
+ set((state) => ({
69
+ surveys: new Map([[survey.name, survey]]),
70
+ }));
71
71
  }
72
72
  }
73
73
  else {
@@ -8,7 +8,7 @@ import { TEAMS_MOCK } from '../../mocks';
8
8
  export const teamStore = createStore((set, get) => ({
9
9
  teams: TEAMS_MOCK,
10
10
  update: (teams) => set((state) => ({
11
- teams
11
+ teams,
12
12
  })),
13
13
  }));
14
14
  export function useTeamStore(selector) {
package/lib/test-setup.js CHANGED
@@ -5,7 +5,7 @@
5
5
  // Test setup for unit tests
6
6
  // Add any global test configuration here
7
7
  // Define webpack globals that are expected by some dependencies
8
- global.__webpack_public_path__ = "";
8
+ global.__webpack_public_path__ = '';
9
9
  // Define other globals that might be needed
10
10
  global.global = globalThis;
11
11
  // Mock DragEvent and other DOM APIs not available in jsdom
@@ -13,7 +13,7 @@ class MockDragEvent extends Event {
13
13
  dataTransfer = null;
14
14
  constructor(type, init) {
15
15
  super(type, init);
16
- this.dataTransfer = (init?.dataTransfer || null);
16
+ this.dataTransfer = init?.dataTransfer || null;
17
17
  }
18
18
  }
19
19
  // Mock DataTransfer if not available
@@ -24,7 +24,9 @@ class MockDataTransfer {
24
24
  items = [];
25
25
  types = [];
26
26
  clearData(format) { }
27
- getData(format) { return ''; }
27
+ getData(format) {
28
+ return '';
29
+ }
28
30
  setData(format, data) { }
29
31
  setDragImage(image, x, y) { }
30
32
  }
@@ -53,5 +55,25 @@ vi.mock('@datalayer/jupyter-react', () => ({
53
55
  serviceManager: null,
54
56
  }),
55
57
  JupyterReactTheme: ({ children }) => children,
58
+ CollaborationProviderBase: class CollaborationProviderBase {
59
+ },
60
+ CollaborationStatus: {
61
+ IDLE: 'idle',
62
+ CONNECTING: 'connecting',
63
+ CONNECTED: 'connected',
64
+ DISCONNECTED: 'disconnected',
65
+ },
56
66
  }));
57
67
  vi.mock('@jupyter/web-components', () => ({}));
68
+ vi.mock('@jupyter/ydoc', () => ({
69
+ YNotebook: class YNotebook {
70
+ },
71
+ }));
72
+ vi.mock('y-websocket', () => ({
73
+ WebsocketProvider: class WebsocketProvider {
74
+ constructor() { }
75
+ connect() { }
76
+ disconnect() { }
77
+ destroy() { }
78
+ },
79
+ }));
@@ -42,7 +42,7 @@ const datalayerThemeDefs = {
42
42
  dark: {
43
43
  colors: {},
44
44
  shadows: {},
45
- }
45
+ },
46
46
  },
47
47
  };
48
48
  const { colorSchemes: primerSchemes, ...primerOthers } = cloneDeep(primerTheme);
@@ -4,7 +4,7 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
6
  import { useEffect, useState } from 'react';
7
- import { BaseStyles, ThemeProvider as PrimerThemeProvider } from '@primer/react';
7
+ import { BaseStyles, ThemeProvider as PrimerThemeProvider, } from '@primer/react';
8
8
  import { loadJupyterConfig, jupyterLabTheme } from '@datalayer/jupyter-react';
9
9
  import { datalayerTheme } from '../theme';
10
10
  import { useRuntimesStore } from '../state';
@@ -28,7 +28,9 @@ export function DatalayerThemeProvider(props) {
28
28
  setColorMode(matches ? 'dark' : 'light');
29
29
  }
30
30
  function updateColorMode(themeManager) {
31
- setColorMode(themeManager.theme && !themeManager.isLight(themeManager.theme) ? 'dark' : 'light');
31
+ setColorMode(themeManager.theme && !themeManager.isLight(themeManager.theme)
32
+ ? 'dark'
33
+ : 'light');
32
34
  }
33
35
  if (inJupyterLab) {
34
36
  // TODO remove the try/catch for JupyterLab > 4.1.
@@ -48,22 +50,23 @@ export function DatalayerThemeProvider(props) {
48
50
  }
49
51
  else {
50
52
  colorSchemeFromMedia({
51
- matches: window.matchMedia('(prefers-color-scheme: dark)').matches
53
+ matches: window.matchMedia('(prefers-color-scheme: dark)').matches,
52
54
  });
53
- window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', colorSchemeFromMedia);
55
+ window
56
+ .matchMedia('(prefers-color-scheme: dark)')
57
+ .addEventListener('change', colorSchemeFromMedia);
54
58
  return () => {
55
- window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', colorSchemeFromMedia);
59
+ window
60
+ .matchMedia('(prefers-color-scheme: dark)')
61
+ .removeEventListener('change', colorSchemeFromMedia);
56
62
  };
57
63
  }
58
64
  }
59
65
  }, [inJupyterLab, jupyterLabAdapter]);
60
- return (inJupyterLab !== undefined ?
61
- _jsx(PrimerThemeProvider, { colorMode: colorMode, theme: inJupyterLab ? jupyterLabTheme : datalayerTheme, ...rest, children: _jsx(BaseStyles, { style: {
62
- backgroundColor: 'var(--bgColor-default)',
63
- color: 'var(--fgColor-default)',
64
- fontSize: 'var(--text-body-size-medium)',
65
- ...baseStyles
66
- }, children: children }) })
67
- :
68
- _jsx(_Fragment, {}));
66
+ return inJupyterLab !== undefined ? (_jsx(PrimerThemeProvider, { colorMode: colorMode, theme: inJupyterLab ? jupyterLabTheme : datalayerTheme, ...rest, children: _jsx(BaseStyles, { style: {
67
+ backgroundColor: 'var(--bgColor-default)',
68
+ color: 'var(--fgColor-default)',
69
+ fontSize: 'var(--text-body-size-medium)',
70
+ ...baseStyles,
71
+ }, children: children }) })) : (_jsx(_Fragment, {}));
69
72
  }
@@ -9,7 +9,7 @@ const JUPYTERLAB_COLLABORATORS_COLORS = {
9
9
  '--jp-collaborator-color4': '#00e4d0',
10
10
  '--jp-collaborator-color5': '#45d4ff',
11
11
  '--jp-collaborator-color6': '#e2b1ff',
12
- '--jp-collaborator-color7': '#ff9de6'
12
+ '--jp-collaborator-color7': '#ff9de6',
13
13
  };
14
14
  export const jpCssToColor = (cssVariableName) => {
15
15
  return JUPYTERLAB_COLLABORATORS_COLORS[cssVariableName.replaceAll('var(', '').replaceAll(')', '')];
@@ -26,8 +26,8 @@ export function stringAvatar(name) {
26
26
  };
27
27
  }
28
28
  export function getAvatarURL(url) {
29
- return url ?
30
- url.startsWith('https://www.gravatar.com/avatar')
29
+ return url
30
+ ? url.startsWith('https://www.gravatar.com/avatar')
31
31
  ? `${url}?v=4&s=200&d=${DEFAULT_AVATAR_URL_ENCODED}` // Use gravatar syntax - sizing works for Gravatar and GitHub
32
32
  : url
33
33
  : DEFAULT_AVATAR_URL; // This fallback should barely be used - hence we allow decoding the URI.
@@ -8,22 +8,22 @@ export const detectBrowser = () => {
8
8
  const userAgent = navigator.userAgent;
9
9
  let browserName;
10
10
  if (userAgent.match(/chrome|chromium|crios/i)) {
11
- browserName = "chrome";
11
+ browserName = 'chrome';
12
12
  }
13
13
  else if (userAgent.match(/firefox|fxios/i)) {
14
- browserName = "firefox";
14
+ browserName = 'firefox';
15
15
  }
16
16
  else if (userAgent.match(/safari/i)) {
17
- browserName = "safari";
17
+ browserName = 'safari';
18
18
  }
19
19
  else if (userAgent.match(/opr\//i)) {
20
- browserName = "opera";
20
+ browserName = 'opera';
21
21
  }
22
22
  else if (userAgent.match(/edg/i)) {
23
- browserName = "edge";
23
+ browserName = 'edge';
24
24
  }
25
25
  else {
26
- browserName = "Unknow browser.";
26
+ browserName = 'Unknow browser.';
27
27
  }
28
28
  return browserName;
29
29
  };
@@ -1,2 +1,2 @@
1
- import { IDataset } from "../models";
1
+ import { IDataset } from '../models';
2
2
  export declare const getDatasetCell: (dataset: IDataset) => string;
@@ -16,7 +16,7 @@ export function getCookie(cname) {
16
16
  return cookie;
17
17
  }
18
18
  // From https://www.w3schools.com/js/js_cookies.asp
19
- const name = cname + "=";
19
+ const name = cname + '=';
20
20
  const decodedCookie = decodeURIComponent(document.cookie);
21
21
  const ca = decodedCookie.split(';');
22
22
  for (let i = 0; i < ca.length; i++) {
package/lib/utils/Date.js CHANGED
@@ -10,11 +10,11 @@ const units = {
10
10
  day: 24 * 60 * 60 * 1000,
11
11
  hour: 60 * 60 * 1000,
12
12
  minute: 60 * 1000,
13
- second: 1000
13
+ second: 1000,
14
14
  };
15
15
  const rtf = new Intl.RelativeTimeFormat(undefined, {
16
16
  numeric: 'auto',
17
- style: 'short'
17
+ style: 'short',
18
18
  });
19
19
  export const getRelativeTime = (d1, d2 = new Date()) => {
20
20
  const elapsed = d1.getTime() - d2.getTime();