diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f73da7..0eacffa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ > Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) > Love It? [Support It](https://github.com/sponsors/StartAutomating) +## WebSocket 0.1.2 + +* WebSocket now decorates (#34) + * Added a -PSTypeName(s) parameter to Get-WebSocket, so we can extend the output. +* Reusing WebSockets (#35) + * If a WebSocketUri is already open, we will reuse it. +* Explicitly exporting commands (#38) + * This should enable automatic import and enable Find-Command + +--- + ## WebSocket 0.1.1 * WebSocket GitHub Action diff --git a/Commands/Get-WebSocket.ps1 b/Commands/Get-WebSocket.ps1 index 45e28eb..a2635c8 100644 --- a/Commands/Get-WebSocket.ps1 +++ b/Commands/Get-WebSocket.ps1 @@ -85,6 +85,24 @@ function Get-WebSocket { $matches.0 } } + .EXAMPLE + # We can decorate a type returned from a WebSocket, allowing us to add additional properties. + + # For example, let's add a `Tags` property to the `app.bsky.feed.post` type. + $typeName = 'app.bsky.feed.post' + Update-TypeData -TypeName $typeName -MemberName 'Tags' -MemberType ScriptProperty -Value { + @($this.commit.record.facets.features.tag) + } -Force + + # Now, let's get 10kb posts ( this should not take too long ) + $somePosts = + websocket "wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=$typeName" -PSTypeName $typeName -Maximum 10kb -Watch + $somePosts | + ? Tags | + Select -ExpandProperty Tags | + Group | + Sort Count -Descending | + Select -First 10 #> [CmdletBinding(PositionalBinding=$false)] [Alias('WebSocket')] @@ -173,6 +191,12 @@ function Get-WebSocket { [TimeSpan] $TimeOut, + # If provided, will decorate the objects outputted from a websocket job. + # This will only decorate objects converted from JSON. + [Alias('PSTypeNames','Decorate','Decoration')] + [string[]] + $PSTypeName, + # The maximum number of messages to receive before closing the WebSocket. [long] $Maximum, @@ -208,7 +232,7 @@ function Get-WebSocket { if (-not $WebSocketUri.Scheme) { $WebSocketUri = [uri]"wss://$WebSocketUri" - } + } if (-not $BufferSize) { $BufferSize = 16kb @@ -256,6 +280,13 @@ function Get-WebSocket { if ([string]::IsNullOrWhitespace($JS)) { continue } ConvertFrom-Json $JS } + if ($PSTypeName) { + $webSocketMessage.pstypenames.clear() + [Array]::Reverse($PSTypeName) + foreach ($psType in $psTypeName) { + $webSocketMessage.pstypenames.add($psType) + } + } if ($handler) { $psCmd = if ($runspace.LanguageMode -eq 'NoLanguage' -or @@ -293,8 +324,22 @@ function Get-WebSocket { if (-not $name) { $Name = $WebSocketUri } - - Start-ThreadJob -ScriptBlock $SocketJob -Name $Name -InitializationScript $InitializationScript -ArgumentList $Variable + + $existingJob = foreach ($jobWithThisName in (Get-Job -Name $Name)) { + if ( + $jobWithThisName.State -in 'Running','NotStarted' -and + $jobWithThisName.WebSocket -is [Net.WebSockets.ClientWebSocket] + ) { + $jobWithThisName + break + } + } + + if ($existingJob) { + $existingJob + } else { + Start-ThreadJob -ScriptBlock $SocketJob -Name $Name -InitializationScript $InitializationScript -ArgumentList $Variable + } } elseif ($WebSocket) { if (-not $name) { $name = "websocket" diff --git a/README.md b/README.md index 2180a22..3270710 100644 --- a/README.md +++ b/README.md @@ -149,4 +149,9 @@ websocket wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=app. } } ~~~ + #### Get-WebSocket Example 11 + +~~~powershell +# We can decorate a type returned from a WebSocket, allowing us to add additional properties. +~~~ diff --git a/WebSocket.psd1 b/WebSocket.psd1 index 0441f61..4eb77b6 100644 --- a/WebSocket.psd1 +++ b/WebSocket.psd1 @@ -1,11 +1,13 @@ @{ - ModuleVersion = '0.1.1' + ModuleVersion = '0.1.2' RootModule = 'WebSocket.psm1' Guid = '75c70c8b-e5eb-4a60-982e-a19110a1185d' Author = 'James Brundage' CompanyName = 'StartAutomating' Copyright = '2024 StartAutomating' Description = 'Work with WebSockets in PowerShell' + FunctionsToExport = @('Get-WebSocket') + AliasesToExport = @('WebSocket') PrivateData = @{ PSData = @{ Tags = @('WebSocket', 'WebSockets', 'Networking', 'Web') @@ -15,21 +17,14 @@ > Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) > Love It? [Support It](https://github.com/sponsors/StartAutomating) -## WebSocket 0.1.1 +## WebSocket 0.1.2 -* WebSocket GitHub Action - * Run any `*.WebSocket.ps1` files in a repository (#24) -* WebSocket container updates - * Container now runs mounted `*.WebSocket.ps1` files (#26) -* Get-WebSocket improvements: - * New Parameters: - * -Maximum (#22) - * -TimeOut (#23) - * -WatchFor (#29) - * -RawText (#30) - * -Binary (#31) -* WebSocket Testing (#25) -* Adding FUNDING.yml (#14) +* WebSocket now decorates (#34) + * Added a -PSTypeName(s) parameter to Get-WebSocket, so we can extend the output. +* Reusing WebSockets (#35) + * If a WebSocketUri is already open, we will reuse it. +* Explicitly exporting commands (#38) + * This should enable automatic import and enable Find-Command --- diff --git a/_config.yml b/_config.yml deleted file mode 100644 index f894bca..0000000 --- a/_config.yml +++ /dev/null @@ -1,12 +0,0 @@ - -title: WebSocket -description: Work with WebSockets in PowerShell -url: https://websocket.powershellweb.com -permalink: pretty -palette: Konsolas -analyticsId: G-R5C30737B2 -googleFont: Noto Sans -stylesheet: https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css -defaults: - - values: - layout: Default diff --git a/_layouts/Default.html b/_layouts/Default.html deleted file mode 100644 index 9d96e1c..0000000 --- a/_layouts/Default.html +++ /dev/null @@ -1,27 +0,0 @@ ---- - -title: Default.html ---- - - -
- - - - {% include GoogleAnalytics.html %} - {% include ImportMap.html %} - {% include OpenGraph.html %} - {% include GoogleFont.html %} - {% include 4bitcss.html %} - {% include Margin.html %} - {% include Stylesheet.html %} - {% include Htmx.html %} - - - -{% include Menu.html %} - -{{content}} - -{% include Footer.html %} - \ No newline at end of file diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 1020c9d..a2ac339 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,17 @@ > Like It? [Star It](https://github.com/PowerShellWeb/WebSocket) > Love It? [Support It](https://github.com/sponsors/StartAutomating) +## WebSocket 0.1.2 + +* WebSocket now decorates (#34) + * Added a -PSTypeName(s) parameter to Get-WebSocket, so we can extend the output. +* Reusing WebSockets (#35) + * If a WebSocketUri is already open, we will reuse it. +* Explicitly exporting commands (#38) + * This should enable automatic import and enable Find-Command + +--- + ## WebSocket 0.1.1 * WebSocket GitHub Action diff --git a/docs/Get-WebSocket.md b/docs/Get-WebSocket.md index 5ad9b74..f252bef 100644 --- a/docs/Get-WebSocket.md +++ b/docs/Get-WebSocket.md @@ -118,6 +118,25 @@ websocket wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=app. } } ``` +We can decorate a type returned from a WebSocket, allowing us to add additional properties. +For example, let's add a `Tags` property to the `app.bsky.feed.post` type. + +```PowerShell +$typeName = 'app.bsky.feed.post' +Update-TypeData -TypeName $typeName -MemberName 'Tags' -MemberType ScriptProperty -Value { + @($this.commit.record.facets.features.tag) +} -Force + +# Now, let's get 10kb posts ( this should not take too long ) +$somePosts = + websocket "wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=$typeName" -PSTypeName $typeName -Maximum 10kb -Watch +$somePosts | + ? Tags | + Select -ExpandProperty Tags | + Group | + Sort Count -Descending | + Select -First 10 +``` --- @@ -231,6 +250,14 @@ The timeout for the WebSocket connection. If this is provided, after the timeou |------------|--------|--------|-------------| |`[TimeSpan]`|false |named |false | +#### **PSTypeName** +If provided, will decorate the objects outputted from a websocket job. +This will only decorate objects converted from JSON. + +|Type |Required|Position|PipelineInput|Aliases | +|------------|--------|--------|-------------|---------------------------------------| +|`[String[]]`|false |named |false |PSTypeNames