jupyterlab-ipyflow 0.0.87 → 0.0.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -48,17 +48,17 @@ const extension = {
48
48
  });
49
49
  }
50
50
  };
51
- const staleClass = 'stale-cell';
52
- const freshClass = 'fresh-cell';
53
- const refresherClass = 'refresher-cell';
54
- const refresherInputClass = 'refresher-input-cell';
55
- const linkedStaleClass = 'linked-stale';
56
- const linkedRefresherClass = 'linked-refresher';
51
+ const waitingClass = 'waiting-cell';
52
+ const readyClass = 'ready-cell';
53
+ const readyMakingClass = 'ready-making-cell';
54
+ const readyMakingInputClass = 'ready-making-input-cell';
55
+ const linkedWaitingClass = 'linked-waiting';
56
+ const linkedReadyMakerClass = 'linked-ready-maker';
57
57
  let dirtyCells = new Set();
58
- let staleCells = new Set();
59
- let freshCells = new Set();
60
- let staleLinks = {};
61
- let refresherLinks = {};
58
+ let waitingCells = new Set();
59
+ let readyCells = new Set();
60
+ let waiterLinks = {};
61
+ let readyMakerLinks = {};
62
62
  let activeCell = null;
63
63
  let activeCellId = null;
64
64
  let cellsById = {};
@@ -66,10 +66,15 @@ let orderIdxById = {};
66
66
  let cellPendingExecution = null;
67
67
  let lastExecutionMode = null;
68
68
  let lastExecutionHighlightsEnabled = null;
69
- let executedReactiveFreshCells = new Set();
70
- let newFreshCells = new Set();
69
+ let executedReactiveReadyCells = new Set();
70
+ let newReadyCells = new Set();
71
71
  let forcedReactiveCells = new Set();
72
72
  const cleanup = new Event('cleanup');
73
+ const resetReactiveState = () => {
74
+ newReadyCells = new Set();
75
+ forcedReactiveCells = new Set();
76
+ executedReactiveReadyCells = new Set();
77
+ };
73
78
  const getJpInputCollapser = (elem) => {
74
79
  if (elem === null || elem === undefined) {
75
80
  return null;
@@ -98,7 +103,7 @@ const attachCleanupListener = (elem, evt, listener) => {
98
103
  elem.addEventListener(evt, listener);
99
104
  elem.addEventListener('cleanup', cleanupListener);
100
105
  };
101
- const addStaleOutputInteraction = (elem, linkedElem, evt, add_or_remove, css) => {
106
+ const addWaitingOutputInteraction = (elem, linkedElem, evt, add_or_remove, css) => {
102
107
  if (elem === null || linkedElem === null) {
103
108
  return;
104
109
  }
@@ -107,11 +112,11 @@ const addStaleOutputInteraction = (elem, linkedElem, evt, add_or_remove, css) =>
107
112
  };
108
113
  attachCleanupListener(elem, evt, listener);
109
114
  };
110
- const addStaleOutputInteractions = (elem, linkedInputClass) => {
111
- addStaleOutputInteraction(getJpInputCollapser(elem), getJpOutputCollapser(elem), 'mouseover', 'add', linkedStaleClass);
112
- addStaleOutputInteraction(getJpInputCollapser(elem), getJpOutputCollapser(elem), 'mouseout', 'remove', linkedStaleClass);
113
- addStaleOutputInteraction(getJpOutputCollapser(elem), getJpInputCollapser(elem), 'mouseover', 'add', linkedInputClass);
114
- addStaleOutputInteraction(getJpOutputCollapser(elem), getJpInputCollapser(elem), 'mouseout', 'remove', linkedInputClass);
115
+ const addWaitingOutputInteractions = (elem, linkedInputClass) => {
116
+ addWaitingOutputInteraction(getJpInputCollapser(elem), getJpOutputCollapser(elem), 'mouseover', 'add', linkedWaitingClass);
117
+ addWaitingOutputInteraction(getJpInputCollapser(elem), getJpOutputCollapser(elem), 'mouseout', 'remove', linkedWaitingClass);
118
+ addWaitingOutputInteraction(getJpOutputCollapser(elem), getJpInputCollapser(elem), 'mouseover', 'add', linkedInputClass);
119
+ addWaitingOutputInteraction(getJpOutputCollapser(elem), getJpInputCollapser(elem), 'mouseout', 'remove', linkedInputClass);
115
120
  };
116
121
  const refreshNodeMapping = (notebook) => {
117
122
  cellsById = {};
@@ -123,34 +128,34 @@ const refreshNodeMapping = (notebook) => {
123
128
  };
124
129
  const clearCellState = (notebook) => {
125
130
  notebook.widgets.forEach((cell, idx) => {
126
- cell.node.classList.remove(staleClass);
127
- cell.node.classList.remove(refresherClass);
128
- cell.node.classList.remove(freshClass);
129
- cell.node.classList.remove(refresherInputClass);
131
+ cell.node.classList.remove(waitingClass);
132
+ cell.node.classList.remove(readyMakingClass);
133
+ cell.node.classList.remove(readyClass);
134
+ cell.node.classList.remove(readyMakingInputClass);
130
135
  // clear any old event listeners
131
136
  const inputCollapser = getJpInputCollapser(cell.node);
132
137
  if (inputCollapser !== null) {
133
- inputCollapser.firstElementChild.classList.remove(linkedStaleClass);
134
- inputCollapser.firstElementChild.classList.remove(linkedRefresherClass);
138
+ inputCollapser.firstElementChild.classList.remove(linkedWaitingClass);
139
+ inputCollapser.firstElementChild.classList.remove(linkedReadyMakerClass);
135
140
  inputCollapser.dispatchEvent(cleanup);
136
141
  }
137
142
  const outputCollapser = getJpOutputCollapser(cell.node);
138
143
  if (outputCollapser !== null) {
139
- outputCollapser.firstElementChild.classList.remove(linkedStaleClass);
140
- outputCollapser.firstElementChild.classList.remove(linkedRefresherClass);
144
+ outputCollapser.firstElementChild.classList.remove(linkedWaitingClass);
145
+ outputCollapser.firstElementChild.classList.remove(linkedReadyMakerClass);
141
146
  outputCollapser.dispatchEvent(cleanup);
142
147
  }
143
148
  });
144
149
  };
145
- const addUnsafeCellInteraction = (elem, linkedElems, cellsById, collapserFun, evt, add_or_remove, staleCells) => {
150
+ const addUnsafeCellInteraction = (elem, linkedElems, cellsById, collapserFun, evt, add_or_remove, waitingCells) => {
146
151
  if (elem === null) {
147
152
  return;
148
153
  }
149
154
  const listener = () => {
150
155
  for (const linkedId of linkedElems) {
151
- let css = linkedRefresherClass;
152
- if (staleCells.has(linkedId)) {
153
- css = linkedStaleClass;
156
+ let css = linkedReadyMakerClass;
157
+ if (waitingCells.has(linkedId)) {
158
+ css = linkedWaitingClass;
154
159
  }
155
160
  const collapser = collapserFun(cellsById[linkedId]);
156
161
  if (collapser === null || collapser.firstElementChild === null) {
@@ -174,17 +179,20 @@ const connectToComm = (session, notebook) => {
174
179
  return;
175
180
  }
176
181
  const order_index_by_cell_id = {};
182
+ const content_by_cell_id = {};
177
183
  notebook.widgets.forEach((itercell, idx) => {
178
184
  order_index_by_cell_id[itercell.model.id] = idx;
185
+ content_by_cell_id[itercell.model.id] = itercell.model.value.text;
179
186
  if (itercell.model.id === cell.id) {
180
- itercell.node.classList.remove(freshClass);
181
- itercell.node.classList.remove(refresherInputClass);
187
+ itercell.node.classList.remove(readyClass);
188
+ itercell.node.classList.remove(readyMakingInputClass);
182
189
  }
183
190
  });
184
191
  const payload = {
185
- type: 'cell_freshness',
192
+ type: 'compute_exec_schedule',
186
193
  executed_cell_id: cell.id,
187
194
  order_index_by_cell_id: order_index_by_cell_id,
195
+ content_by_cell_id: content_by_cell_id,
188
196
  };
189
197
  comm.send(payload).done.then(() => {
190
198
  if (cellPendingExecution !== null) {
@@ -192,12 +200,10 @@ const connectToComm = (session, notebook) => {
192
200
  }
193
201
  else {
194
202
  if (lastExecutionMode === 'reactive') {
195
- freshCells = executedReactiveFreshCells;
203
+ readyCells = executedReactiveReadyCells;
196
204
  updateUI(notebook);
197
205
  }
198
- newFreshCells = new Set();
199
- forcedReactiveCells = new Set();
200
- executedReactiveFreshCells = new Set();
206
+ resetReactiveState();
201
207
  comm.send({
202
208
  type: 'reactivity_cleanup',
203
209
  });
@@ -264,36 +270,36 @@ const connectToComm = (session, notebook) => {
264
270
  ];
265
271
  const updateOneCellUI = (id) => {
266
272
  const elem = cellsById[id];
267
- if (staleCells.has(id)) {
268
- elem.classList.add(staleClass);
269
- elem.classList.add(freshClass);
270
- elem.classList.remove(refresherInputClass);
271
- addStaleOutputInteractions(elem, linkedStaleClass);
273
+ if (waitingCells.has(id)) {
274
+ elem.classList.add(waitingClass);
275
+ elem.classList.add(readyClass);
276
+ elem.classList.remove(readyMakingInputClass);
277
+ addWaitingOutputInteractions(elem, linkedWaitingClass);
272
278
  }
273
- else if (freshCells.has(id)) {
274
- elem.classList.add(refresherInputClass);
279
+ else if (readyCells.has(id)) {
280
+ elem.classList.add(readyMakingInputClass);
275
281
  if (lastExecutionMode === 'normal') {
276
- elem.classList.add(freshClass);
277
- addStaleOutputInteractions(elem, linkedRefresherClass);
282
+ elem.classList.add(readyClass);
283
+ addWaitingOutputInteractions(elem, linkedReadyMakerClass);
278
284
  }
279
285
  }
280
286
  if (lastExecutionMode === 'reactive') {
281
287
  return;
282
288
  }
283
- if (staleLinks.hasOwnProperty(id)) {
289
+ if (waiterLinks.hasOwnProperty(id)) {
284
290
  actionUpdatePairs.forEach(({ action, update }) => {
285
- addUnsafeCellInteraction(getJpInputCollapser(elem), staleLinks[id], cellsById, getJpInputCollapser, action, update, staleCells);
286
- addUnsafeCellInteraction(getJpOutputCollapser(elem), staleLinks[id], cellsById, getJpInputCollapser, action, update, staleCells);
291
+ addUnsafeCellInteraction(getJpInputCollapser(elem), waiterLinks[id], cellsById, getJpInputCollapser, action, update, waitingCells);
292
+ addUnsafeCellInteraction(getJpOutputCollapser(elem), waiterLinks[id], cellsById, getJpInputCollapser, action, update, waitingCells);
287
293
  });
288
294
  }
289
- if (refresherLinks.hasOwnProperty(id)) {
290
- if (!staleCells.has(id)) {
291
- elem.classList.add(refresherClass);
292
- elem.classList.add(freshClass);
295
+ if (readyMakerLinks.hasOwnProperty(id)) {
296
+ if (!waitingCells.has(id)) {
297
+ elem.classList.add(readyMakingClass);
298
+ elem.classList.add(readyClass);
293
299
  }
294
300
  actionUpdatePairs.forEach(({ action, update }) => {
295
- addUnsafeCellInteraction(getJpInputCollapser(elem), refresherLinks[id], cellsById, getJpInputCollapser, action, update, staleCells);
296
- addUnsafeCellInteraction(getJpInputCollapser(elem), refresherLinks[id], cellsById, getJpOutputCollapser, action, update, staleCells);
301
+ addUnsafeCellInteraction(getJpInputCollapser(elem), readyMakerLinks[id], cellsById, getJpInputCollapser, action, update, waitingCells);
302
+ addUnsafeCellInteraction(getJpInputCollapser(elem), readyMakerLinks[id], cellsById, getJpOutputCollapser, action, update, waitingCells);
297
303
  });
298
304
  }
299
305
  };
@@ -315,44 +321,51 @@ const connectToComm = (session, notebook) => {
315
321
  notebook.activeCell.model.stateChanged.connect(onExecution);
316
322
  notifyActiveCell(notebook.activeCell.model);
317
323
  }
318
- else if (msg.content.data['type'] === 'cell_freshness') {
319
- staleCells = new Set(msg.content.data['stale_cells']);
320
- freshCells = new Set(msg.content.data['fresh_cells']);
321
- newFreshCells = new Set([...newFreshCells, ...msg.content.data['new_fresh_cells']]);
324
+ else if (msg.content.data['type'] === 'compute_exec_schedule') {
325
+ waitingCells = new Set(msg.content.data['waiting_cells']);
326
+ readyCells = new Set(msg.content.data['ready_cells']);
327
+ newReadyCells = new Set([...newReadyCells, ...msg.content.data['new_ready_cells']]);
322
328
  forcedReactiveCells = new Set([...forcedReactiveCells, ...msg.content.data['forced_reactive_cells']]);
323
- staleLinks = msg.content.data['stale_links'];
324
- refresherLinks = msg.content.data['refresher_links'];
329
+ waiterLinks = msg.content.data['waiter_links'];
330
+ readyMakerLinks = msg.content.data['ready_maker_links'];
325
331
  cellPendingExecution = null;
326
332
  const exec_mode = msg.content.data['exec_mode'];
327
333
  const flow_order = msg.content.data['flow_order'];
328
334
  const exec_schedule = msg.content.data['exec_schedule'];
329
335
  lastExecutionMode = exec_mode;
330
336
  lastExecutionHighlightsEnabled = msg.content.data['highlights_enabled'];
331
- executedReactiveFreshCells.add(msg.content.data['last_executed_cell_id']);
332
- let found = false;
333
- notebook.widgets.forEach(cell => {
334
- if (found || cell.model.type !== 'code' || executedReactiveFreshCells.has(cell.model.id)) {
335
- return;
337
+ executedReactiveReadyCells.add(msg.content.data['last_executed_cell_id']);
338
+ for (const cell of notebook.widgets) {
339
+ if (cell.model.type !== 'code' || executedReactiveReadyCells.has(cell.model.id)) {
340
+ continue;
336
341
  }
337
- if ((exec_mode === 'reactive' && newFreshCells.has(cell.model.id)) || forcedReactiveCells.has(cell.model.id)) {
338
- const codeCell = cell;
339
- if (cellPendingExecution === null) {
340
- cellPendingExecution = codeCell;
341
- // break early if using one of the order-based semantics
342
- found = (flow_order === 'in_order' || exec_schedule === 'strict');
342
+ if (!forcedReactiveCells.has(cell.model.id)) {
343
+ if (exec_mode !== 'reactive' || !newReadyCells.has(cell.model.id)) {
344
+ continue;
343
345
  }
344
- else if (codeCell.model.executionCount !== null && codeCell.model.executionCount < cellPendingExecution.model.executionCount) {
345
- // otherwise, execute in order of earliest execution counter
346
- cellPendingExecution = codeCell;
346
+ }
347
+ const codeCell = cell;
348
+ if (cellPendingExecution === null) {
349
+ cellPendingExecution = codeCell;
350
+ // break early if using one of the order-based semantics
351
+ if (flow_order === 'in_order' || exec_schedule === 'strict') {
352
+ break;
347
353
  }
348
354
  }
349
- });
355
+ else if (codeCell.model.executionCount == null) {
356
+ // pass
357
+ }
358
+ else if (codeCell.model.executionCount < cellPendingExecution.model.executionCount) {
359
+ // otherwise, execute in order of earliest execution counter
360
+ cellPendingExecution = codeCell;
361
+ }
362
+ }
350
363
  if (cellPendingExecution === null) {
351
- newFreshCells = new Set();
352
- forcedReactiveCells = new Set();
364
+ resetReactiveState();
353
365
  updateUI(notebook);
354
366
  }
355
367
  else {
368
+ onActiveCellChange(notebook, cellPendingExecution);
356
369
  clearCellState(notebook);
357
370
  }
358
371
  }
package/package.json CHANGED
@@ -65,5 +65,5 @@
65
65
  "extension": true,
66
66
  "outputDir": "../../core/ipyflow/resources/labextension/"
67
67
  },
68
- "version": "0.0.87"
68
+ "version": "0.0.90"
69
69
  }
package/style/index.css CHANGED
@@ -1,64 +1,64 @@
1
1
  :root {
2
- --stale-color: rgb(254,0,82);
3
- --refresher-color: rgb(0,197,158);
2
+ --waiting-color: rgb(254,0,82);
3
+ --ready-making-color: rgb(0,197,158);
4
4
  }
5
5
 
6
- .stale-cell .jp-InputCollapser {
7
- border: 1px solid var(--stale-color);
6
+ .waiting-cell .jp-InputCollapser {
7
+ border: 1px solid var(--waiting-color);
8
8
  }
9
9
 
10
- .stale-cell.jp-mod-selected .jp-Collapser-child {
11
- background-color: var(--stale-color);
10
+ .waiting-cell.jp-mod-selected .jp-Collapser-child {
11
+ background-color: var(--waiting-color);
12
12
  }
13
13
 
14
- .stale-cell .jp-Collapser:hover > .jp-Collapser-child {
15
- background-color: var(--stale-color);
14
+ .waiting-cell .jp-Collapser:hover > .jp-Collapser-child {
15
+ background-color: var(--waiting-color);
16
16
  }
17
17
 
18
- .jp-Collapser-child.linked-stale {
19
- background-color: var(--stale-color);
18
+ .jp-Collapser-child.linked-waiting {
19
+ background-color: var(--waiting-color);
20
20
  opacity: 0.6;
21
21
  }
22
22
 
23
- .refresher-cell .jp-InputCollapser {
24
- border: 1px solid var(--refresher-color);
23
+ .ready-making-cell .jp-InputCollapser {
24
+ border: 1px solid var(--ready-making-color);
25
25
  }
26
26
 
27
- .refresher-cell.jp-mod-selected .jp-Collapser-child {
28
- background-color: var(--refresher-color);
27
+ .ready-making-cell.jp-mod-selected .jp-Collapser-child {
28
+ background-color: var(--ready-making-color);
29
29
  }
30
30
 
31
- .refresher-cell .jp-Collapser:hover > .jp-Collapser-child {
32
- background-color: var(--refresher-color);
31
+ .ready-making-cell .jp-Collapser:hover > .jp-Collapser-child {
32
+ background-color: var(--ready-making-color);
33
33
  }
34
34
 
35
- .jp-Collapser-child.linked-refresher {
36
- background-color: var(--refresher-color);
35
+ .jp-Collapser-child.linked-ready-maker {
36
+ background-color: var(--ready-making-color);
37
37
  opacity: 0.6;
38
38
  }
39
39
 
40
40
  /* put input / output cells later since they should take precedence */
41
41
 
42
- .fresh-cell .jp-OutputCollapser {
43
- border: 1px solid var(--stale-color);
42
+ .ready-cell .jp-OutputCollapser {
43
+ border: 1px solid var(--waiting-color);
44
44
  }
45
45
 
46
- .fresh-cell.jp-mod-selected .jp-OutputCollapser .jp-Collapser-child {
47
- background-color: var(--stale-color);
46
+ .ready-cell.jp-mod-selected .jp-OutputCollapser .jp-Collapser-child {
47
+ background-color: var(--waiting-color);
48
48
  }
49
49
 
50
- .fresh-cell .jp-OutputCollapser:hover > .jp-Collapser-child {
51
- background-color: var(--stale-color);
50
+ .ready-cell .jp-OutputCollapser:hover > .jp-Collapser-child {
51
+ background-color: var(--waiting-color);
52
52
  }
53
53
 
54
- .refresher-input-cell .jp-InputCollapser {
55
- border: 1px solid var(--refresher-color);
54
+ .ready-making-input-cell .jp-InputCollapser {
55
+ border: 1px solid var(--ready-making-color);
56
56
  }
57
57
 
58
- .refresher-input-cell.jp-mod-selected .jp-InputCollapser .jp-Collapser-child {
59
- background-color: var(--refresher-color);
58
+ .ready-making-input-cell.jp-mod-selected .jp-InputCollapser .jp-Collapser-child {
59
+ background-color: var(--ready-making-color);
60
60
  }
61
61
 
62
- .refresher-input-cell .jp-InputCollapser:hover > .jp-Collapser-child {
63
- background-color: var(--refresher-color);
62
+ .ready-making-input-cell .jp-InputCollapser:hover > .jp-Collapser-child {
63
+ background-color: var(--ready-making-color);
64
64
  }