Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F969265
index.ts
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
5 KB
Referenced Files
None
Subscribers
None
index.ts
View Options
import
EventEmitter
from
"events"
;
import
{
Readable
}
from
"stream"
;
import
pipeInto
from
"./pipe-into"
;
import
{
Stringifiable
,
stringify
}
from
"./stringify"
;
import
{
HTMLTag
}
from
"./html"
;
import
type
{
Argument
as
ClassNamesArgument
}
from
"classnames"
;
export
{
default
as
streamToString
}
from
"./tostring"
;
export
{
TempstreamJSX
}
from
"./jsx"
;
/* eslint-disable */
declare
global
{
namespace
JSX
{
type
HtmlAttribute
=
|
string
|
boolean
|
ClassNamesArgument
|
Array
<
ClassNamesArgument
>
;
type
HtmlElement
=
HTMLTag
;
interface
IntrinsicElements
extends
IntrinsicElementMap
{}
interface
InstrictPropsInterface
{
[
k
:
string
]
:
HtmlAttribute
|
Promise
<
HtmlAttribute
>
;
}
type
IntrinsicElementMap
=
{
[
K
in
HtmlElement
]
:
InstrictPropsInterface
&
{
children
?:
Templatable
|
Templatable
[];
};
};
type
Element
=
Readable
;
interface
ElementChildrenAttribute
{
children
:
{};
}
}
}
/* eslint-enable */
export
type
MaybePromise
<
T
>
=
T
|
Promise
<
T
>
;
export
type
MaybeArray
<
T
>
=
T
|
Array
<
T
>
;
export
type
MaybePromiseMaybeArray
<
T
>
=
|
T
|
T
[]
|
(
T
|
Promise
<
T
>
)[]
|
Promise
<
T
>
|
Promise
<
Promise
<
T
>
|
T
[]
>
|
Promise
<
T
[]
>
|
Promise
<
T
>
[];
export
type
FlatTemplatable
=
Stringifiable
;
export
type
Templatable
=
MaybePromise
<
MaybeArray
<
MaybePromise
<
FlatTemplatable
>>
>
;
const
ErrorSymbol
=
Symbol
(
"ErrorSymbol"
);
let
unhandledRejectionHandlerSetup
=
false
;
function
setupUnhandledRejection
()
{
if
(
unhandledRejectionHandlerSetup
)
{
return
;
}
console
.
log
(
"Setting up unhandled rejection listener"
);
process
.
on
(
"unhandledRejection"
,
(
error
:
Error
,
promise
:
unknown
)
=>
{
console
.
error
(
"UNHANDLED REJECTION:"
);
console
.
error
(
error
);
console
.
error
(
"FOR PROMISE:"
);
console
.
error
(
promise
);
console
.
error
(
`!! You're using tempstream, which encaurages passing promises to template
strings. This is a delicate operation! Make sure you're not doing this:
\`\`\`
const data_promise = fetchData(); // returns a Promise
await sleep(200); // <== the process sleeps, while the above Promise rejects
return tempstream\`some data: \${data_promise.then(data=>data.name)}\` // <== tempstream automatically sets up error handlers, but it's too late!
\`\`\`
The problem with the above example is that the \`await sleep(200)\` allows the
data_promise to fail before tempstream manages to add .catch handlers to
it. Either add the error handlers yourself, or don't do any \`await\`s inbetween
promises runing in the background and returning the tempstream.
`
);
process
.
exit
(
1
);
});
unhandledRejectionHandlerSetup
=
true
;
}
setupUnhandledRejection
();
export
type
TemplateGenError
=
{
ErrorSymbol
:
symbol
;
error
:
Error
};
let
index
=
0
;
async
function
*
templateGen
(
strings
:
TemplateStringsArray
,
...
params
:
Templatable
[]
)
{
const
n
=
index
++
;
for
(
const
string
of
strings
)
{
yield
string
;
const
param
=
params
.
shift
();
try
{
yield
param
;
}
catch
(
error
:
unknown
)
{
yield
{
ErrorSymbol
,
error
};
}
}
yield
null
;
}
export
class
TempStream
extends
Readable
{
current_promise
:
Promise
<
void
>
|
null
=
null
;
is_finished
=
false
;
has_errors
=
false
;
id
=
Math
.
random
();
emitter
=
new
EventEmitter
();
constructor
(
public
generator
:
ReturnType
<
typeof
templateGen
>
)
{
super
();
}
async
_read
()
{
if
(
this
.
current_promise
||
this
.
is_finished
)
{
return
;
}
this
.
current_promise
=
this
.
generator
.
next
().
then
(
async
(
result
)
=>
{
if
(
result
.
done
&&
!
this
.
is_finished
)
{
this
.
push
(
null
);
this
.
finishStream
(
"success"
);
return
;
}
await
this
.
handleResult
(
result
.
value
);
this
.
current_promise
=
null
;
this
.
_read
();
});
}
async
handleResult
(
value
:
unknown
)
{
if
(
value
===
null
)
{
// do nothing;
}
else
if
(
typeof
value
===
"object"
&&
(
value
as
TemplateGenError
)
?
.
ErrorSymbol
===
ErrorSymbol
)
{
this
.
finishStream
(
"error"
,
(
value
as
TemplateGenError
)
?
.
error
);
}
else
if
(
Array
.
isArray
(
value
))
{
for
(
const
[
index
,
subvalue
]
of
Object
.
entries
(
value
))
{
// eslint-disable-next-line no-await-in-loop
await
this
.
handleResult
(
await
subvalue
);
if
(
parseInt
(
index
)
<
value
.
length
-
1
)
this
.
push
(
""
);
}
}
else
if
(
value
instanceof
Readable
)
{
await
pipeInto
(
value
,
(
data
)
=>
this
.
push
(
data
)).
catch
((
error
)
=>
{
this
.
finishStream
(
"error"
,
error
);
});
}
else
if
(
value
!==
undefined
&&
value
!==
null
&&
typeof
value
!==
"string"
&&
value
.
toString
)
{
await
this
.
handleResult
(
value
.
toString
());
}
else
{
this
.
push
(
value
);
}
}
waitUntilFinished
()
{
return
new
Promise
((
resolve
)
=>
{
if
(
this
.
is_finished
)
{
resolve
(
this
);
}
else
{
this
.
emitter
.
on
(
"finished"
,
()
=>
resolve
(
this
));
}
});
}
finishStream
(
status
:
"error"
|
"success"
,
error
?:
unknown
)
{
if
(
status
===
"error"
)
{
this
.
emit
(
"error"
,
error
);
this
.
emitter
.
emit
(
"promise-error"
,
error
);
this
.
has_errors
=
true
;
}
else
{
this
.
emitter
.
emit
(
"success"
);
}
this
.
emitter
.
emit
(
"success"
);
this
.
emitter
.
emit
(
"finished"
);
this
.
is_finished
=
true
;
this
.
push
(
null
);
// end the stream
}
push
(
data
:
unknown
)
:
boolean
{
if
(
data
instanceof
Buffer
)
{
// console.log("PUSHING", data.toString("utf-8"));
}
else
{
// console.log("PUSHING", data);
}
super
.
push
(
data
);
return
true
;
}
}
export
function
tempstream
(
strings
:
TemplateStringsArray
,
...
params
:
Templatable
[]
)
:
Readable
{
params
.
forEach
((
param
)
=>
{
if
(
param
instanceof
Promise
)
{
param
.
catch
((
e
)
=>
{
console
.
log
(
"Error caught within tempstream main function"
);
console
.
error
(
e
);
});
}
});
return
new
TempStream
(
templateGen
(
strings
,
...
params
));
}
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Fri, Nov 22, 09:39 (8 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
547676
Default Alt Text
index.ts (5 KB)
Attached To
Mode
rSTREAM tempstream
Attached
Detach File
Event Timeline
Log In to Comment