{"ScriptPreparationCode":"\r\nfunction LoopObservable() {\r\n\tconst listeners = new Set();\r\n\tthis.on = fn =\u003E listeners.add(fn);\r\n\tthis.off = fn =\u003E listeners.delete(fn);\r\n\tthis.clear = () =\u003E listeners.clear();\r\n\t\r\n\t// This has bad failure modes.\r\n\tthis.send = function(...message) {\r\n\t\tfor (let fn of listeners)\r\n\t\t\tfn(...message);\r\n\t};\r\n};\r\n\r\nfunction EventTargetObservable() {\r\n\t// Name is arbitrary because we\u0027re using a dedicated object. Use a shorter\r\n\t// name for shorter lookup.\r\n\tconst NAME = \u0027.\u0027;\r\n\tconst __ = document.createTextNode(null);\r\n\t\r\n\tthis.on = function(handler) {\r\n\t\t__.addEventListener(NAME, event =\u003E {\r\n\t\t\thandler(event.detail);\r\n\t\t});\r\n\t};\r\n\t\r\n\tthis.off = function(handler) {\r\n\t\t__.removeEventListener(NAME, handler);\r\n\t};\r\n\t\r\n\tthis.send = function(detail) {\r\n\t\t__.dispatchEvent(new CustomEvent(NAME, {detail}));\r\n\t};\r\n}\r\n\r\nfunction run_test(observable, handlers = 3, calls = 1000) {\r\n\tfor (let i = 0; i \u003C handlers; i\u002B\u002B)\r\n\t\tobservable.on(message =\u003E console.log(i, message));\r\n\t\r\n\tfor (let i = 0; i \u003C calls; i\u002B\u002B)\r\n\t\tobservable.send({type: \u0022hello\u0022, i});\r\n}\r\n","TestCases":[{"Name":"loop observable","Code":"run_test(new LoopObservable());","IsDeferred":false},{"Name":"EventTarget observable","Code":"run_test(new EventTargetObservable());","IsDeferred":false}]}