the-moby-effect
Version:
Moby/Docker API client built using effect-ts
149 lines (148 loc) • 9.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.responseIsMultiplexedResponse = exports.multiplexedToStream = exports.multiplexedToSink = exports.multiplexedFromStreamWith = exports.multiplexedFromStream = exports.multiplexedFromSink = exports.makeMultiplexedSocket = exports.makeMultiplexedChannel = exports.isMultiplexedSocket = exports.isMultiplexedChannel = exports.demuxMultiplexedToSingleSink = exports.demuxMultiplexedToSeparateSinks = exports.demuxMultiplexedFolderSink = exports.asMultiplexedChannel = exports.aggregate = exports.MultiplexedSocketTypeId = exports.MultiplexedSchema = exports.MultiplexedHeaderType = exports.MultiplexedContentType = exports.MultiplexedChannelTypeId = void 0;
var Socket = _interopRequireWildcard(require("@effect/platform/Socket"));
var Channel = _interopRequireWildcard(require("effect/Channel"));
var Chunk = _interopRequireWildcard(require("effect/Chunk"));
var Duration = _interopRequireWildcard(require("effect/Duration"));
var Effect = _interopRequireWildcard(require("effect/Effect"));
var Function = _interopRequireWildcard(require("effect/Function"));
var Pipeable = _interopRequireWildcard(require("effect/Pipeable"));
var Predicate = _interopRequireWildcard(require("effect/Predicate"));
var Schedule = _interopRequireWildcard(require("effect/Schedule"));
var Schema = _interopRequireWildcard(require("effect/Schema"));
var Sink = _interopRequireWildcard(require("effect/Sink"));
var Stream = _interopRequireWildcard(require("effect/Stream"));
var Tuple = _interopRequireWildcard(require("effect/Tuple"));
var internalCompressed = _interopRequireWildcard(require("./compressed.js"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/** @internal */
const MultiplexedContentType = exports.MultiplexedContentType = "application/vnd.docker.multiplexed-stream";
/** @internal */
const MultiplexedSocketTypeId = exports.MultiplexedSocketTypeId = /*#__PURE__*/Symbol.for("the-moby-effect/demux/MultiplexedSocket");
/** @internal */
const MultiplexedChannelTypeId = exports.MultiplexedChannelTypeId = /*#__PURE__*/Symbol.for("the-moby-effect/demux/MultiplexedChannel");
/** @internal */
const makeMultiplexedSocket = underlying => ({
underlying,
"content-type": MultiplexedContentType,
[MultiplexedSocketTypeId]: MultiplexedSocketTypeId,
pipe() {
return Pipeable.pipeArguments(this, arguments);
}
});
/** @internal */
exports.makeMultiplexedSocket = makeMultiplexedSocket;
const makeMultiplexedChannel = underlying => ({
underlying,
"content-type": MultiplexedContentType,
[MultiplexedChannelTypeId]: MultiplexedChannelTypeId,
pipe() {
return Pipeable.pipeArguments(this, arguments);
}
});
/** @internal */
exports.makeMultiplexedChannel = makeMultiplexedChannel;
const isMultiplexedSocket = u => Predicate.hasProperty(u, MultiplexedSocketTypeId);
/** @internal */
exports.isMultiplexedSocket = isMultiplexedSocket;
const isMultiplexedChannel = u => Predicate.hasProperty(u, MultiplexedChannelTypeId);
/** @internal */
exports.isMultiplexedChannel = isMultiplexedChannel;
const responseIsMultiplexedResponse = response => response.headers["content-type"] === MultiplexedContentType;
/** @internal */
exports.responseIsMultiplexedResponse = responseIsMultiplexedResponse;
var MultiplexedHeaderType;
(function (MultiplexedHeaderType) {
MultiplexedHeaderType[MultiplexedHeaderType["Stdin"] = 0] = "Stdin";
MultiplexedHeaderType[MultiplexedHeaderType["Stdout"] = 1] = "Stdout";
MultiplexedHeaderType[MultiplexedHeaderType["Stderr"] = 2] = "Stderr";
})(MultiplexedHeaderType || (exports.MultiplexedHeaderType = MultiplexedHeaderType = {}));
/** @internal */
const MultiplexedSchema = exports.MultiplexedSchema = /*#__PURE__*/Schema.Tuple(/*#__PURE__*/Schema.Enums(MultiplexedHeaderType), Schema.Uint8Array);
/** @internal */
const asMultiplexedChannel = input => isMultiplexedSocket(input) ? makeMultiplexedChannel(Socket.toChannel(input.underlying)) : input;
/** @internal */
exports.asMultiplexedChannel = asMultiplexedChannel;
const multiplexedToStream = input => Channel.toStream(asMultiplexedChannel(input).underlying);
/** @internal */
exports.multiplexedToStream = multiplexedToStream;
const multiplexedToSink = input => Channel.toSink(asMultiplexedChannel(input).underlying);
/** @internal */
exports.multiplexedToSink = multiplexedToSink;
const multiplexedFromStreamWith = () => input => makeMultiplexedChannel(Stream.toChannel(input));
/** @internal */
exports.multiplexedFromStreamWith = multiplexedFromStreamWith;
const multiplexedFromStream = input => multiplexedFromStreamWith()(input);
/** @internal */
exports.multiplexedFromStream = multiplexedFromStream;
const multiplexedFromSink = input => makeMultiplexedChannel(Sink.toChannel(input));
/** @internal */
exports.multiplexedFromSink = multiplexedFromSink;
const demuxMultiplexedFolderSink = exports.demuxMultiplexedFolderSink = /*#__PURE__*/Sink.fold({
headerBytesRead: 0,
messageBytesRead: 0,
headerBuffer: /*#__PURE__*/Chunk.empty(),
messageBuffer: /*#__PURE__*/Chunk.empty(),
messageSize: undefined,
messageType: undefined
}, ({
messageBytesRead,
messageSize
}) => messageSize === undefined || messageBytesRead < messageSize, (accumulator, input) => {
// If we have not read the entire header yet
if (accumulator.headerBytesRead < 8) {
return {
...accumulator,
headerBytesRead: accumulator.headerBytesRead + 1,
headerBuffer: Chunk.append(accumulator.headerBuffer, input)
};
}
// Lazily evaluate the header and message size
const uint8Array = () => new Uint8Array(Chunk.toReadonlyArray(accumulator.headerBuffer));
const type = () => accumulator.messageType ?? new DataView(uint8Array().buffer).getUint8(0);
const size = () => accumulator.messageSize ?? new DataView(uint8Array().buffer).getUint32(4);
// We can parse the header when we've read all 8 bytes and haven't parsed it yet
const needToParseHeader = accumulator.headerBytesRead === 8 && Predicate.isUndefined(accumulator.messageType) && Predicate.isUndefined(accumulator.messageSize);
// Otherwise, if we have read the entire header but not parsed it yet
const parsedHeader = needToParseHeader ? {
messageType: type(),
messageSize: size()
} : {};
return {
...accumulator,
...parsedHeader,
messageBytesRead: accumulator.messageBytesRead + 1,
messageBuffer: Chunk.append(accumulator.messageBuffer, input)
};
});
/** @internal */
const aggregate = multiplexedStream => Function.pipe(multiplexedStream, Stream.mapConcat(Function.identity), Stream.aggregateWithin(demuxMultiplexedFolderSink, Schedule.fixed(Duration.infinity)), Stream.map(({
messageBuffer,
messageType
}) => Tuple.make(messageType, Chunk.toReadonlyArray(messageBuffer))), Stream.flatMap(Schema.decodeUnknown(MultiplexedSchema)));
/** @internal */
exports.aggregate = aggregate;
const demuxMultiplexedToSingleSink = exports.demuxMultiplexedToSingleSink = /*#__PURE__*/Function.dual(arguments_ => isMultiplexedSocket(arguments_[0]) || isMultiplexedChannel(arguments_[0]), (socket, source, sink, options) => {
const {
underlying
} = asMultiplexedChannel(socket);
const textDecoder = new TextDecoder(options?.encoding);
const toStrings = Tuple.mapSecond(bytes => textDecoder.decode(bytes, {
stream: true
}));
return Function.pipe(source, Stream.pipeThroughChannelOrFail(underlying), aggregate, Stream.map(toStrings), Stream.run(sink));
});
/** @internal */
const demuxMultiplexedToSeparateSinks = exports.demuxMultiplexedToSeparateSinks = /*#__PURE__*/Function.dual(arguments_ => isMultiplexedSocket(arguments_[0]) || isMultiplexedChannel(arguments_[0]), (socket, source, sink1, sink2, options) => Function.pipe(source, Stream.pipeThroughChannelOrFail(asMultiplexedChannel(socket).underlying), aggregate, Stream.partition(([messageType]) => messageType === MultiplexedHeaderType.Stderr, {
bufferSize: options?.bufferSize
}), Effect.map(Tuple.mapBoth({
onFirst: Function.flow(Stream.map(Tuple.getSecond), Stream.decodeText(options?.encoding), Stream.run(sink1)),
onSecond: Function.flow(Stream.map(Tuple.getSecond), Stream.decodeText(options?.encoding), Stream.run(sink2))
})), Effect.map(Effect.allWith({
concurrency: 2
})), Effect.flatten, Effect.map(internalCompressed.compressDemuxOutput), Effect.scoped));
//# sourceMappingURL=multiplexed.js.map