Skip to content

Commit 606a3ae

Browse files
committed
docs: update readme
1 parent b955448 commit 606a3ae

File tree

1 file changed

+15
-40
lines changed

1 file changed

+15
-40
lines changed

README.md

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
JS Bin's loop protection implementation as a reusable library.
66

7-
This code protects most cases where user code includes an infinite loop using a `while`, `for` or `do` loop.
7+
This code protects use cases where user code includes an infinite loop using a `while`, `for` or `do` loop.
88

9-
Note that this does *not* solve the [halting problem](http://en.wikipedia.org/wiki/Halting_problem) but simply rewrites JavaScript (without an AST) wrapping loops with a conditional break. This also *does not* protect against recursive loops.
9+
Note that this does *not* solve the [halting problem](http://en.wikipedia.org/wiki/Halting_problem) but simply rewrites JavaScript (using Babel's AST) wrapping loops with a conditional break. This also *does not* protect against recursive loops.
1010

1111
## Example
1212

@@ -22,30 +22,25 @@ console.log('All finished');
2222

2323
## Usage
2424

25-
The loop protection can be used both on the client side and server side. It supports AMD and CommonJS module loading, or can be included as vanilla JavaScript (as it is in JS Bin).
25+
The loop protection is a babel transform, so can be used on the server or in the client.
2626

27+
The previous implementation used an injected library to handle tracking loops - this version does not.
2728

28-
### Public methods
29-
30-
- `loopProtect.hit(number)`: fired when a potential infinite loop is found. Can be overwritten (see example below).
31-
- `loopProtect.alias(string)`: used if loopProtect is aliased to a different variable.
32-
- `loopProtect.debug(bool)`: used for development to trace steps of protection (not included .min file)
33-
34-
### Example implementation
29+
### Example (client) implementation
3530

3631
```js
37-
// we're going to alias the loopProtect object under a different name
38-
// when it runs inside the iframe, so we need to configure the loopProtect
39-
// *before* we process the JavaScript.
40-
loopProtect.alias = 'protect';
32+
import Babel from 'babel-standalone';
33+
import protect from 'loop-protect';
4134

42-
// show the user we found an infinite loop and let the code carry on
43-
loopProtect.hit = function (line) {
44-
alert('Potential infinite loop found on line ' + line);
45-
};
35+
const timeout = 100; // defaults to 100ms
36+
Babel.registerPlugin('loopProtection', protect(timeout));
37+
38+
const transform = source => Babel.transform(source, {
39+
plugins: ['loopProtection'],
40+
}).code;
4641

4742
// rewrite the user's JavaScript to protect loops
48-
var processed = loopProtect(getUserCode());
43+
var processed = transform(getUserCode());
4944

5045
// run in an iframe, and expose the loopProtect variable under a new name
5146
var iframe = getNewFrame();
@@ -58,32 +53,12 @@ var win = iframe.contentWindow;
5853
var doc = win.document;
5954
doc.open();
6055

61-
// this line is why we use `loopProtect.alias = 'protect'`
62-
win.protect = loopProtect;
63-
6456
doc.write('<script>' + processed + '<' + '/script>');
6557
doc.close();
6658

67-
// code now runs, and if there's a loop, loopProtect.hit is called.
59+
// code now runs, and if there's an infinite loop, it's cleanly exited
6860
```
6961

70-
## Abstract
71-
72-
The loop protection method takes a string of JavaScript and manually parses the code manually to find `while`, `for` and `do` loops.
73-
74-
Once these loops are found, a *marker* is inserted before the loop, and a *test* is called as the first job inside the loop. The first time the test is called, it records the time, and if the loop has taken over 100ms then the loop will `break` out and the remaining JavaScript is executed.
75-
76-
### Why not use an AST?
77-
78-
The parsing would be 100% robust if we did use an AST, but the overhead would be at the cost of around 200-300K for the parser.
79-
80-
For it's purpose, this manual loop protection works pretty well. Most people spot their infinite loops whilst they're typing and will fix the code, but if like [JS Bin](http://jsbin.com) you're rendering the output and JavaScript in real-time, you'll need to prevent the browser from hanging. This simple loop protection is one defence against loops.
81-
82-
83-
## TODO / ideas
84-
85-
- If the time between tests is 100ms or more, it's likely we're looking at a loop with an `alert` (or type of blocking call), so perhaps the loop protection can back off?
86-
8762
## Contributors
8863

8964
- Author: [Remy Sharp](https://github.com/remy)

0 commit comments

Comments
 (0)